Linux下串口应用程序编程(一)

2014-11-24 08:59:33 · 作者: · 浏览: 5

这几天,由于多功能温度测量仪项目的需要,涉及到了GSM信息的串口读取,所以在Linux下串口信息的读取有了一点心得体会。


1. 打开串口


与其他的关于设备编程的方法一样,在Linux下,操作、控制串口也是通过操作起设备文件进行的。在Linux下,串口的设备文件是/dev/ttyS0或/dev/ttyS1等。因此要读写串口,我们首先要打开串口:


char *dev = "/dev/ttyS0"; //串口1


int fd = open( dev, O_RDWR ); //打开串口的核心语句


//| O_NOCTTY | O_NDELAY


if (-1 == fd)


{


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


return -1;


}


else


return fd;



2. 设置串口速度


打开串口成功后,我们就可以对其进行读写了。首先要设置串口的波特率:


int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, };


int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };


void set_speed(int fd, int speed){


int i;


int status;


struct termios Opt;


tcgetattr(fd, &Opt);


for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {


if (speed == name_arr[i]) {


tcflush(fd, TCIOFLUSH);


cfsetispeed(&Opt, speed_arr[i]);//波特率大小在驱动中已经做了初始化 大小根据实际串口驱动而定,这句话可以重设波特率


cfsetospeed(&Opt, speed_arr[i]);


status = tcsetattr(fd, TCSANOW, &Opt);


if (status != 0) {


perror("tcsetattr fd");


return;


}


tcflush(fd,TCIOFLUSH);


}


}


}


3. 设置串口信息


这主要包括:数据位、停止位、奇偶校验位这些主要的信息。


/**


*@brief 设置串口数据位,停止位和效验位


*@param fd 类型 int 打开的串口文件句柄


*@param databits 类型 int 数据位 取值 为 7 或者8


*@param stopbits 类型 int 停止位 取值为 1 或者2


*@param parity 类型 int 效验类型 取值为N,E,O,,S


*/


int set_Parity(int fd,int databits,int stopbits,int parity)//串口设置的核心函数,波特率可以使用驱动默认波特率,但是本函数不可省略,本段代码经测试有效,可直接cp使用


{


struct termios options;


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


perror("SetupSerial 1");


return(FALSE);


}


options.c_cflag &= ~CSIZE;


options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/


options.c_oflag &= ~OPOST; /*Output*/



switch (databits) /*设置数据位数*/


{


case 7:


options.c_cflag |= CS7;


break;


case 8:


options.c_cflag |= CS8;


break;


default:


fprintf(stderr,"Unsupported data size\n"); return (FALSE);


}


switch (parity)


{


case 'n':


case 'N':


options.c_cflag &= ~PARENB; /* Clear parity enable */


options.c_iflag &= ~INPCK; /* Enable parity checking */


break;


case 'o':


case 'O':


options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/


options.c_iflag |= INPCK; /* Disnable parity checking */


break;


case 'e':


case 'E':


options.c_cflag |= PARENB; /* Enable parity */


options.c_cflag &= ~PARODD; /* 转换为偶效验*/


options.c_iflag |= INPCK; /* Disnable parity checking */


break;


case 'S':


case 's': /*as no parity*/


options.c_cflag &= ~PARENB;


options.c_cflag &= ~CSTOPB;break;


default:


fprintf(