一. 什么是串口
串口是计算机上的串行通讯的物理接口。计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备。虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接通常特指那些与RS-232标准兼容的硬件或者调制解调器的接口。
Linux 操作系统从一开始就对串行口提供了很好的支持,本文就 Linux 下的串行口通讯编程进行简单的介绍,如果要非常深入了解,建议看看本文所参考的 《Serial Programming Guide for POSIX Operating Systems》
二. 打开串口
在 Linux 下串口文件是位于 /dev 下的
串口一 为 /dev/ttyACM0
串口二 为 /dev/ttyACM1
打开串口是通过使用标准的文件打开函数操作:
int fd;
fd=open("/dev/ttyACM0",O_RDWR); /以读写方式打开串口
if (-1==fd)
{
perror("提示错误!\n"); / 不能打开串口一
}
三. 设置串口
最基本的设置串口包括波特率设置,校验位和停止位设置。
串口的设置主要是设置 struct termios 结构体的各成员值。
设置这个结构体很复杂,我这里就只说说常见的一些设置:
1. 波特率设置:
下面是修改波特率的代码:
2. 参数设置中常用函数
用tcgetattr函数与tcsetattr函数控制终端
(1) tcgetattr函数用于获取与终端相关的参数。参数fd为终端的文件描述符,返回的结果保存在termios结构体中,该结构体一般包括如下的成员:
tcflag_t c_iflag; //输入模式标志,控制终端输入方式
tcflag_t c_oflag; //输出模式标志
tcflag_t c_cflag; //控制模式标志,指定终端硬件控制信息
tcflag_t c_lflag; //本地模式标志,控制终端编辑功能
cc_t c_cc[NCCS]; //控制字符,用于保存终端驱动程序中的特殊字符,如输入结束符等
(2) tcsetattr函数用于设置终端的相关参数。参数fd为打开的终端文件描述符,参数optional_actions用于控制修改起作用的时间,而结构体termios_p中保存了要修改的参数。
optional_actions (tcsetattr函数 的第二个参数)指定了什么时候改变会起作用:
* TCSANOW:改变立即发生
* TCSADRAIN:改变在所有写入 fd 的输出都被传输后生效。这个
函数应当用于修改影响输出的参数时使用。(当前输出完成时将值改变)
* TCSAFLUSH :改变在所有写入 fd 引用的对象的输出都被传输后生效,所 有已接受但未读入的输入都在改变发生前丢弃(同TCSADRAIN,但会舍弃当前所有 值)。
(3) 获取波特率:
获得端口波特率信息是通过cfgetispeed函数和cfgetospeed函数来实现的。cfgetispeed函数用于获得结构体termios_p中的输入波特率信息,而cfgetospeed函数用于获得结构体termios_p中的输出波特率信息。这两个函数的具体信息如下表所示。
(4) 设置波特率
cfsetispeed函数和cfsetospeed函数会修改结构体termios_p中的波特率信息
cfsetospeed函数
头文件:#include<termios.h>
函数原型:int cfsetospeed(struct termios *termptr, speed_t speed);
参数:struct termios *termptr - 指向termios结构的指针
speed_t speed - 需要设置的输出波特率
返回值:如果成功返回0,否则返回-1
cfsetispeed函数
头文件:#include<termios.h>
函数原型:int cfsetispeed(struct termios *termptr, speed_t speed);
参数:struct termios *termptr - 指向termios结构的指针
speed_t speed - 需要设置的输入波特率
如果成功返回0,否则返回-1
其中参数speed可以使用下表中所列出的宏。
speed参数常用波特率信息:
3. 数据位
数据位指的是每字节中实际数据所占的比特数。要修改数据位可以通过修改termios结构体中c_cflag成员来实现。CS5、CS6、CS7和CS8分别表示数据位为5、6、 7和8。值得注意的是,在设置数据位时,必须先使用CSIZE做位屏蔽。
struct termios opt;//定义指向termios 结构类型的指针opt
tcgetattr(fd, &opt);//获得串口指向termios结构的指针
opt.c_cflag&=~CSIZE;//屏蔽其他标志
opt.c_cflag |=CS8;//将数据位修改为8bit
tcsetattr(fd,TCANOW,&opt); //将修改后的termios数据设置到串口中
4. 数据流控制
数据流控制指是使用何种方法来标志数据传输的开始和结束。可以选择不使用数据流控制、使用硬件进行流控制和使用软件进行流控制。数据流控制设置如下表所示。
5. 奇偶校验位
奇偶校验可以选择偶校验、奇校验、空格等方式,也可以不使用校验。如果要设置为偶校验的话,首先要将termios结构体中c_cflag设置PARENB标志,并清除PARODD标志。如果要设置奇校验,要同时设置termios结构体中c_cflag设置PARENB标志和PARODD标志。如果不想使用任何校验的话,清除termios结构体中c_cflag的PARENB位。下表为设置奇偶校验的具体方法
设置:
Option.c_cflag &= ~PARENB; //无校验位
Option.c_cflag &= ~CSTOPB; //设置一个停止位
Option.c_cflag &= ~CSIZE; //屏蔽其他标志
Option.c_cflag |= CS8; //设置数据位是8bit
四. 读写串口
设置好串口之后,读写串口就很容易了,把串口当作文件读写就是。
发送数据:
char buffer[1024];int length;
int Byte;
Byte = write(fd, buffer ,length)
读取串口数据:
使用文件操作read函数读取,如果设置为原始模式(Raw Mode)传输数据, 那么read函数返回的字符数是实际串口收到的字符数。
char buff[1024];
int len;
int Byte = read(fd,buff,len);
五. 关闭串口
关闭串口就是关闭文件。
close(fd);
编程实现,有意思
下的串行口通讯编程进行简单的介绍
提供了很好的支持!