Windows XP Windows 7 Windows 2003 Windows Vista Windows教程綜合 Linux 系統教程
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟件教程
 Windows教程網 >> Linux系統教程 >> Linux教程 >> Linux控制串口的應用程序

Linux控制串口的應用程序

日期:2017/2/7 14:39:29      編輯:Linux教程
 

這是linux串口通信的程序,
/*寫串口程序*/

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <termios.h>

#include <stdlib.h>

 

/*打開串口函數*/

int open_port(int fd,int comport)

{

char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};

long vdisable;

if (comport==1)//串口 1

{

fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);

if (-1 == fd){

perror("Can't Open Serial Port");

return(-1);

}

}

else if(comport==2)//串口 2

{

fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);

if (-1 == fd){

perror("Can't Open Serial Port");

return(-1);

}

}

else if (comport==3)//串口 3

{

fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY);

if (-1 == fd){

perror("Can't Open Serial Port");

return(-1);

}

}

/*恢復串口為阻塞狀態*/

if(fcntl(fd, F_SETFL, 0)<0)

printf("fcntl failed!\n");

else

printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));

/*測試是否為終端設備*/

if(isatty(STDIN_FILENO)==0)

printf("standard input is not a terminal device\n");

else

printf("isatty success!\n");

printf("fd-open=%d\n",fd);

return fd;

}

 

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

/*保存測試現有串口參數設置,在這裡如果串口號等出錯,會有相關的出錯信息*/

if ( tcgetattr( fd,&oldtio) != 0) {

perror("SetupSerial 1");

return -1;

}

bzero( &newtio, sizeof( newtio ) );

/*步驟一,設置字符大小*/

newtio.c_cflag |= CLOCAL | CREAD;

newtio.c_cflag &= ~CSIZE;

/*設置停止位*/

switch( nBits )

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

/*設置奇偶校驗位*/

switch( nEvent )

{

case 'O': //奇數

newtio.c_cflag |= PARENB;

newtio.c_cflag |= PARODD;

newtio.c_iflag |= (INPCK | ISTRIP);

break;

case 'E': //偶數

newtio.c_iflag |= (INPCK | ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag &= ~PARODD;

break;

case 'N': //無奇偶校驗位

newtio.c_cflag &= ~PARENB;

break;

}

/*設置波特率*/

switch( nSpeed )

{

case 2400:

cfsetispeed(&newtio, B2400);

cfsetospeed(&newtio, B2400);

break;

case 4800:

cfsetispeed(&newtio, B4800);

cfsetospeed(&newtio, B4800);

break;

case 9600:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

case 115200:

cfsetispeed(&newtio, B115200);

cfsetospeed(&newtio, B115200);

break;

case 460800:

cfsetispeed(&newtio, B460800);

cfsetospeed(&newtio, B460800);

break;

default:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

}

/*設置停止位*/

if( nStop == 1 )

newtio.c_cflag &= ~CSTOPB;

else if ( nStop == 2 )

newtio.c_cflag |= CSTOPB;

/*設置等待時間和最小接收字符*/

newtio.c_cc[VTIME] = 0;

newtio.c_cc[VMIN] = 0;

/*處理未接收字符*/

tcflush(fd,TCIFLUSH);

/*激活新配置*/

if((tcsetattr(fd,TCSANOW,&newtio))!=0)

{

perror("com set error");

return -1;

}

printf("set done!\n");

return 0;

}

 

 

int main(void)

{

int fd;

int nwrite,i;

char buff[]="Hello\n";

if((fd=open_port(fd,1))<0){//打開串口

perror("open_port error");

return;

}

if((i=set_opt(fd,115200,8,'N',1))<0){//設置串口

perror("set_opt error");

return;

}

printf("fd=%d\n",fd);

for(i=0; i<20; i++){

nwrite=write(fd,buff,6);//寫串口

printf("nwrite=%d,%s\n",nwrite,buff);

sleep(1);

}

close(fd);

return;

}


經交叉編譯,在skyeye s3c2410下運行,結果如下:
Can't Open Serial Port: No such device or address
open_port error: Illegal seek
說明打開串口設備節點"/dev/ttyS0"失敗,但是嵌入式linux下的dev目錄下確實存在ttyS0文件

然後我將fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);
改為 fd = open( "/dev/ttySAC0", O_RDWR|O_NOCTTY|O_NDELAY);
再交叉編譯,在skyeye s3c2410下運行,結果如下:
fcntl=0
isatty success!
fd-open=3
set done!
fd=3
Hello
nwrite=6,Hello

Hello
nwrite=6,Hello
打開串口成功了,程序也能正常運行,所以說s3c2410開發板的串口設備節點是ttySAC0,而不是ttyS0?
但是我在一些嵌入式linux書裡看到的都是說ttyS0代表串口1,ttyS1代表串口2,那ttySAC0和ttyS0到底是什麼關系呢?什麼時候用ttySAC0,什麼時候用ttyS0呢?
對嵌入式linux不是很懂,希望高手能幫小弟解答一下,不勝感激


答:
2.4內核中用ttyS0,而2.6中則改成了ttySAC0。

Copyright © Windows教程網 All Rights Reserved