linux串口示例

最近看了下linux的串口,发现还是蛮容易的

做一些总结和记录

【这篇文章也重在备份和记录,代码都是套用别人的 ,所以基本只是罗列了些代码,但保证代码可用】

其实串口操作也就那么几步

1.打开串口

2.设置参数

3.发送接收

4.按需关闭

而根据函式提供的形式,

一般设置参数分两步进行【其实就是那么配置下,分几步都行,只是配合后面的代码了】

[1]设置波特率

[2]设置数据格式

下面还是罗列一些代码

打开串口

int OpenDev(char *Dev)

{

int fd = open( Dev, O_RDWR );

if (-1 == fd)

{

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

return -1;

}

else

return fd;

}

O_RDWR就是可读写的意思设置波特率

Code

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 fd1");

return;

}

tcflush(fd,TCIOFLUSH);

}

}

}

设置参数是用到了一个专用的结构体struct termios其实也没啥说的,就是通过它去配置串口参数罢了

注意tcflush,他是清空buffer用的,关于buffer这东西,里面其实挺饶,这里不多说明,只是要注意它清空的buffer并不是printf那类函式中所谓的缓冲。

另外那两个数组,其实可以弄的简单些,只不过懒得改了

有点像画刷的使用,旧的一般都爱保存起来,最后还要还原。

设置数据格式

int set_Parity(int fd,int databits,int stopbits,int parity)

{

struct termios options;

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

perror("SetupSerial 0");

return -1;

}

options.c_cflag &= ~CSIZE;

switch (databits)

{

case 7:

options.c_cflag |= CS7;

break;

case 8:

options.c_cflag |= CS8;

break;

default:

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

return -1;

}

switch (parity)

{

case 'n':

case 'N':

options.c_cflag &= ~PARENB;

options.c_iflag &= ~INPCK;

break;

case 'o':

case 'O':

options.c_cflag |= (PARODD | PARENB);

options.c_iflag |= INPCK;

break;

case 'e':

case 'E':

options.c_cflag |= PARENB;

options.c_cflag &= ~PARODD;

options.c_iflag |= INPCK;

break;

case 'S':

case 's':

options.c_cflag &= ~PARENB;

options.c_cflag &= ~CSTOPB;break;

default:

fprintf(stderr,"Unsupported parity\n");

return -1;

}

switch (stopbits)

{

case 1:

options.c_cflag &= ~CSTOPB;

break;

case 2:

options.c_cflag |= CSTOPB;

break;

default:

fprintf(stderr,"Unsupported stop bits\n");

return -1;

}

if (parity != 'n')

options.c_iflag |= INPCK;

tcflush(fd,TCIFLUSH);

options.c_cc[VTIME] = 150;

options.c_cc[VMIN] = 0;

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

{

perror("SetupSerial 3");

return -1;

}

return 0;

}

和前面的函式不同这里直接对struct termios进行操作,进而配置了数据位长度,校验位,停止位,超时等信息

最后整合下,列出一个测试用例

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <termios.h>

#include <errno.h>

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 fdl");

return;

}

tcflush(fd,TCIOFLUSH);

}

}

}

int set_Parity(int fd,int databits,int stopbits,int parity)

{

struct termios options;

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

perror("SetupSerial 1");

return -1;

}

options.c_cflag &= ~CSIZE;

switch (databits)

{

case 7:

options.c_cflag |= CS7;

break;

case 8:

options.c_cflag |= CS8;

break;

default:

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

}

switch (parity)

{

case 'n':

case 'N':

options.c_cflag &= ~PARENB;

options.c_iflag &= ~INPCK;

break;

case 'o':

case 'O':

options.c_cflag |= (PARODD | PARENB);

options.c_iflag |= INPCK;

break;

case 'e':

case 'E':

options.c_cflag |= PARENB;

options.c_cflag &= ~PARODD;

options.c_iflag |= INPCK;

break;

case 'S':

case 's':

options.c_cflag &= ~PARENB;

options.c_cflag &= ~CSTOPB;break;

default:

fprintf(stderr,"Unsupported parity\n");

return -1;

}

switch (stopbits)

{

case 1:

options.c_cflag &= ~CSTOPB;

break;

case 2:

options.c_cflag |= CSTOPB;

break;

default:

fprintf(stderr,"Unsupported stop bits\n");

return -1;

}

if (parity != 'n')

options.c_iflag |= INPCK;

tcflush(fd,TCIFLUSH);

options.c_cc[VTIME] = 150;

options.c_cc[VMIN] = 0;

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

{

perror("SetupSerial 3");

return -1;

}

return 0;

}

int OpenDev(char *Dev)

{

int fd = open( Dev, O_RDWR );

if (-1 == fd)

{

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

return -1;

}

else

return fd;

}

int main(int argc, char **argv){

int fd;

int nread;

char buff[6];

char *dev = "/dev/ttyS0";

fd = OpenDev(dev);

set_speed(fd,9600);

if (set_Parity(fd,8,1,'N') == FALSE) {

printf("Set Parity Error\n");

exit (0);

}

while (1) {

write(fd,"hello",5);

nread = read(fd, buff, 5);

tcflush(fd,TCIOFLUSH);

buff[nread+1] = '\0';

printf( "%s", buff);

}

//close(fd);

// exit (0);

}

这个测试将发送hello字符并接受,主要是为了测试自发自收用的如果有串口的话,可以使用跳线帽将2,3脚端接来完成此测试可以看到终端中不断出现hellohello……就对了!我的是现代化的笔记本。。。。。XD怎会有串口的存在所以整了张卡,据说比usb转接线稳定,目前还没发现稳定到哪里去

posted @ 2009-09-20 13:50  与时俱进  阅读(1871)  评论(0编辑  收藏  举报
友情链接:同里老宅院民居客栈