相关头文件:
#include <termios.h>
串口帧格式:
1. 打开串口
int open(const char * pathname, int flags);
linux 下串口文件位于 /dev 下,一般串口一为 /dev/ttys0 ,串口二为 /dev/ttys1
示例代码如下:
int fd; /* 以读写方式打开串口 */
fd = open( " /dev/ttys0", O_RDWR | O_NOCTTY | O_NDELAY);
if ( -1 == fd )
{
perror( "串口0被占用,不能打开!!" );
}
==============================================
串口的打开方式选项:
O _RDWR /* 串口可收可发 */
O_RDONLY /* 串口只收不发 */
O_NOCTTY /* 这个串口不是控制终端,普通串口要说明这项 */
O_NDELAY /* 不需要理会DCD管脚的状态,如果不选,当DCD置低时,串口应用进入休眠状态 */
==============================================
第一串口与其他串口的区别:
—— linux 下第一个串口都充当控制台,已启动就打开,如果一个程序同时想开这个串口,就必须以控制台模式打开,否则接受不到数据。
—— open 该串口时不带 O_NOCTTY 参数
—— 该串口必须碰到 \r\n 字符才会触发读操作
—— 普通的串口只要受到数据就触发读操作
2. 设置串口参数
串口参数有四个: 波特率,校验位,停止位,数据位
串口数据保存在 struct termios
================================================
#include <termios.h>
struct termio
{
unsigned short c_iflag; /* 输入模式标志 */
unsigned short c_oflag; /* 输出模式标志 */
unsigned short c_cflag; /* 控制模式标志(很重要,跟数据位,校验模式等相关) */
unsigned short c_lflag; /* 本地模式表之 */
unsigned char c_line; /* 行规 */
unsigned char c_cc[ NCC ]; /* 控制字符 */
speed_t c_ispeed ; /* 输入数据波特率 */
speed_t c_ospeed ; /* 输出数据波特率 */
};
================================================
串口的设置主要是设置这个结构体的各成员值,然后利用该结构体将参数传给硬件驱动程序。
int tcgetattr( int fd, struct termios *termios_p ); /* 获取串口的参数 */
int tcsetattr( int fd, int optional_actions , struct termios *termios_p ); /* 设置串口的参数 */
这两个参数都有一个批向termios结构体的指针作为参数,用于返回当前终端的属性或设置该终端的属性。参数fd就是用open()函数打开的终端文件句柄,
而串口就是用open()打开的串口设备文件句柄。tcsetattr()函数的optional_action参数用于指定新设定的参数起作用的时间,其设定值可以为:
================================================
TCSANOW 改变立即生效
TCSADRAIN 在所有的输出都被传输后改变生效,适用于更改影响输出参数的情况。
TCSAFLUSH 在所有输出都被传输后改变生效,丢弃所有末读入的输入(清空输入缓 存)。
================================================
宏介绍:
================================================
c_cflag:
B1800, B 2400, B4800, B9600, B19200, B28400, B57600, B115200 波特率
CSIZE 数据位掩码
CS5, CS6, CS7, CS8 有多少数据位
CSTOPB 2个停止位(不设置则为1个)
CREAD 接受使能
PARENB 校验位使能
PARODD 使用奇校验
CLOCAL 本地连接
c_iflag:
INPCK 奇偶校验使能
ISTRIP 去除奇偶校验位
IXON 启动出口硬件流控
IXOFF 启动出口软件流控
================================================
(1)设置波特率
使用 cfsetospeed() / cfsetispeed() 函数设置波特率,它们分别用于在termios结构体中设置输出和输入的波特率。设置波特率可以使用波特率常数,
其定义为字母 “ B+速率 ” ,如B19200就是波特率为19200bps,B115200就是波特率为115200bps。
int cfsetispeed( struct termios *termios_p, speed_t speed );
int cfsetospeed( struct termios *termios_p, speed_t speed );
例 :
struct termios Opt;
tcgetattr( fd, &Opt ); /* 获取 */
cfsetispeed( ttys0_opt, B115200 ); /* 设置 */
cfsetospeed( ttys0_opt, B115200 ); /* 设置 */
tcsetattr( fd, TCSANOW , &Opt ); /* 生效 */
(2)设置数据位
数据位有5,6,7,8四个标准,格式为 “ CS+数字 ”,如CS7,CS8
例:
struct termios Opt;
tcgetattr( fd, &Opt ); /* 获取 */
Opt . c_cflag & = ~CSIZE; /* 将标志位的数据位标志置0 */ Opt . c_cflag | = CS8; /* 设置数据位为8位 */
tcsetattr( fd, TCSANOW , &Opt ); /* 生效 */
(3)设置校验模式
校验模式主要有偶校验,奇校验, 空格校验跟没有校验
校验模式的设置也是设置c_cflag
如果有一个校验位,那么数据位必然变成7位,所以数据位跟校验位要同时设置。
例:
/* 偶校验收 Even parity ( 7 E 1) */
Opt . c_cflag |= PARENB; /* 校验位使能 */
Opt . c_cflag &= ~PARODD; /* 设置为偶校验 */
Opt . c_cflag &= ~CSTOPB; /* 设置为一个停止位 */
Opt . c_cflag &= ~CSIZE; /* 将标志位的数据位标志置0 */
Opt . c_cflag |= CS7; /* 设置数据位为7位 */
/* 奇校验 Odd parity ( 7 O 1 ) */
Opt . c_cflag |= PARENB; /* 校验位使能 */
Opt . c_cflag |= PARODD; /* 设置为奇校验 */
Opt . c_cflag &= ~CSTOPB; /* 设置为一个停止位 */
Opt . c_cflag &= ~CSIZE; /* 将标志位的数据位标志置0 */
Opt . c_cflag |= CS7; /* 设置数据位为7位 */
/* 无校验 No parity ( 8 N 1 ) */
Opt . c_cflag &= ~PARENB; /* 校验位停止 */
Opt . c_cflag &= ~CSIZE; /* 将标志位的数据位标志置0 */
Opt . c_cflag |= CS8; /* 设置数据位为8位 */
/* 空白校验 Space parity ( 7 S 1 ) */
Opt . c_cflag &= ~PARENB; /* 校验位停止 */
Opt . c_cflag &= ~CSIZE; /* 将标志位的数据位标志置0 */
Opt . c_cflag |= CS7; /* 设置数据位为7位 */
只用来串口收发数据,不需要串口终端处理,大部分串口采用这一设置
例:
struct termios options;
option . c_iflag &= ~(ICANON | ECHO | ECHOE | ISIg); //接收采用原始模式
option . c_oflag &= ~OPOST; //发送采用原始模式
ssize_t read( int fd, void *buf, size_t count );
ssize_t write( int fd, const void *buf, size_t count );
4. 关闭串口
int close( fd );