Linux下C语言串口应用编程

2019-07-12 21:42发布

在编写Linux串口的C程序之前,需要包含以下头文件:#include Linux系统中,一切皆文件,所以串口设备也是一类文件,学习过Linux驱动程序的学员都知道,Linux有三类设备:字符设备,块设备,网络设备。那么串口设备属于字符设备。所以串口设备的命名一般为/dev/ttySn(n = 012......),如果该串口为USB转串口,可能名称为/dev/ttyUSBn(n = 012......),不同的平台下串口的名称是不同的,且串口的名称也是可以更改的。如何更改?在板卡对应的Linux驱动中更改。Linux下操作串口,那么也就是跟操作一个文件一样,既然是文件,也就可以使用标准的文件操作API来操作。1、打开串口
2、关闭串口
fd为文件描述符。如果不设置串口的波特率,数据位,停止位,校验位的情况下,Linux下默认设置的属性值为:波特率:9600数据位:8校验位:n(表示无)停止位:1在不设置串口属性值的情况下,也可以读写串口值。3、读写串口使用readwrite函数即可,例如: 以上例程展现的是往串口写入一个数据,串口就会回复一个数据,也就是自发自收。完整例程:#include #include #include #include #include #define DEV_NAME "/dev/ttyS1" int main (int argc, char *argv[]) { int fd; int len, i,ret; char buf[] = "hello ZLG!"; fd = open(DEV_NAME, O_RDWR | O_NOCTTY); if(fd < 0) { perror(DEV_NAME); return -1; } len = write(fd, buf, sizeof(buf)); if (len < 0) { printf("write data error "); } len = read(fd, buf, sizeof(buf)); if (len < 0) { printf("read error "); return -1; } printf("%s", buf); return(0); }   上面给出的例程是串口驱动的默认属性值(9600,8n1,无流控),在实际产品开发过程中,还是会根据不同的应用场景来设置串口的属性。操作串口属性需要设置对应的标志,在POSIX终端已经帮我们实现了若干结构体以及相应的标志位,我们只要熟练使用它即可,非常简单。  最重要的struct termios结构体:

1、设置串口波特率
.
例程:static void set_baudrate (struct termios *opt, unsigned int baudrate) { cfsetispeed(opt, baudrate); cfsetospeed(opt, baudrate); }
2、设置数据位  数据位指的是每字节中实际数据所占的比特数。要修改数据位可以通过修改termios结构体中c_cflag成员来实现。CS5CS6CS7CS8分别表示数据位为5678。值得注意的是,在设置数据位时,必须先使用CSIZE做位屏蔽。例程:static void set_data_bit (struct termios *opt, unsigned int databit) { opt->c_cflag &= ~CSIZE; switch (databit) { case 8: opt->c_cflag |= CS8; break; case 7: opt->c_cflag |= CS7; break; case 6: opt->c_cflag |= CS6; break; case 5: opt->c_cflag |= CS5; break; default: opt->c_cflag |= CS8; break; } }3、设置校验位  奇偶校验可以选择偶校验、奇校验、空格等方式,也可以不使用校验。如果要设置为偶校验的话,首先要将termios结构体中c_cflag设置PARENB标志,并清除PARODD标志。如果要设置奇校验,要同时设置termios结构体中c_cflag设置PARENB标志和PARODD标志。如果不想使用任何校验的话,清除termios结构体中c_cflag的PARENB位。表6.12所示为设置奇偶校验的具体方法。

例程:static void set_parity (struct termios *opt, char parity) { switch (parity) { case 'N': /* no parity check */ opt->c_cflag &= ~PARENB; break; case 'E': /* even */ opt->c_cflag |= PARENB; opt->c_cflag &= ~PARODD; break; case 'O': /* odd */ opt->c_cflag |= PARENB; opt->c_cflag |= ~PARODD; break; default: /* no parity check */ opt->c_cflag &= ~PARENB; break; } }4、设置停止位 设置串口停止位是在 termios 对象的 c_cflag 成员上设置,需要用到的选项标志为
CSTOPB(2 位停止位,否则为 1 位)。例程:static void set_stopbit (struct termios *opt, const char *stopbit) { if (0 == strcmp (stopbit, "1")) { opt->c_cflag &= ~CSTOPB; /* 1 stop bit */ } else if (0 == strcmp (stopbit, "1")) { opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */ } else if (0 == strcmp (stopbit, "2")) { opt->c_cflag |= CSTOPB; /* 2 stop bits */ } else { opt->c_cflag &= ~CSTOPB; /* 1 stop bit */ } }于是我们就可以将串口这三样基本的设置写成一个函数,以后用的时候就调用它即可。
//串口设置 int Serial_Handle::set_port_attr ( int fd, int baudrate, // B1200 B2400 B4800 B9600 .. B115200 int databit, // 5, 6, 7, 8 const char *stopbit, // "1", "1.5", "2" char parity, // N(o), O(dd), E(ven) int vtime, int vmin ) { struct termios opt; tcgetattr(fd, &opt); //设置波特率 set_baudrate(&opt, baudrate); opt.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */ //设置数据位 set_data_bit(&opt, databit); //设置校验位 set_parity(&opt, parity); //设置停止位 set_stopbit(&opt, stopbit);      //其它设置 opt.c_oflag = 0; opt.c_lflag |= 0; opt.c_oflag &= ~OPOST; opt.c_cc[VTIME] = vtime; opt.c_cc[VMIN] = vmin; tcflush (fd, TCIFLUSH); return (tcsetattr (fd, TCSANOW, &opt)); }以后在使用串口的时候即是要遵循以下的顺序才能使用。1、打开串口设备2、设置串口的波特率,数据位,校验位,停止位以及其它设置3、写数据4、读出数据5、关闭串口
参考文献:1、http://book.51cto.com/art/200711/59758.htm
2、周立功=====>【开发指南】M6G2C&A6G2C系列核心板软件开发指南_V1.05