串口终端设备的接口属性如下:
struct termios
{
tcflag_t c_cflag; //控制标志
tcflag_t c_iflag; //输入标志
tcflag_t c_oflag; //输出标志
tcflag_t c_lflag; //本地标志
tcflag_t c_cc[NCCS];//控制字符
}
其中定义类型如下:
typedef unsigned int tcflag_t;
需要包含的头文件<termios.h>
下面介绍一下各个标志的选项
控制标志c_cflag:
波特率相关:
标志 | 说明 | 标志 | 说明 |
---|---|---|---|
CBAUD | 波特率位屏蔽 | B4800 | 4800 位/秒 |
B0 | 0 位/秒(挂起) | B9600 | 9600 位/秒 |
B110 | 100 位/秒 | B19200 | 19200 位/秒 |
B134 | 134 位/秒 | B57600 | 57600 位/秒 |
B1200 | 1200 位/秒 | B115200 | 115200 位/秒 |
B2400 | 2400 位/秒 | B460800 | 460800 位/秒 |
数据位相关:
标志 | 说明 |
---|---|
CSIZE | 数据位屏蔽 |
CS5 | 5 位数据位 |
CS6 | 6 位数据位 |
CS7 | 7 位数据位 |
CS8 | 8 位数据位 |
停止位相关:
标志 | 说明 |
---|---|
CSTOPB | 2 位停止位,否则为 1 位 |
校验位:
标志 | 说明 |
---|---|
PARENB | 进行奇偶校验 |
PARODD | 奇校验,否则为偶校验 |
其他:
标志 | 说明 |
---|---|
CREAD | 启动接收 |
HUPCL | 最后关闭时断开 |
CLOCAL | 忽略调制调解器状态行 |
输入标志c_iflag:
标志 | 说明 | 标志 | 说明 |
---|---|---|---|
INPCK | 打开输入奇偶校验 | IXOFF | 启用/停止输入控制流起作用 |
IGNPAR | 忽略奇偶错字符 | IGNBRK | 忽略BREAK条件 |
PARMRK | 标记奇偶错字符 | INLCR | 讲输入的NL转换为CR |
ISTRIP | 剥除字符第八位 | IGNCR | 忽略CR |
IXON | 启用/停止输出控制流起作用 | ICRNL | 将输入的CR转换为NL |
输出标志c_oflag:
标志 | 说明 | ||
---|---|---|---|
BSDLY | 退格延迟屏蔽 | OLCUC | 将输出的小写字符转换为大写字符 |
CMSPAR | 标志或空奇偶性 | ONLCR | 将 NL 转换为 CR-NL |
CRDLY | CR 延迟屏蔽 | ONLRET | NL 执行 CR 功能 |
FFDLY | 换页延迟屏蔽 | ONOCR | 在 0 列不输出 CR |
OCRNL | 将输出的 CR 转换为 NL | OPOST | 执行输出处理 |
OFDEL | 填充符为 DEL,否则为 NULL | OXTABS | 将制表符扩充为空格 |
OFILL | 对于延迟使用填充符 |
本地标志c_lflag:
标志 | 说明 | 标志 | 说明 |
---|---|---|---|
ISIG | 启用终端产生的信号 | NOFLSH | 在中断或退出键后禁用刷清 |
ICANON | 启用规范输入 | IEXTEN | 启用扩充的输入字符处理 |
XCASE | 规范大/小写表示 | ECHOCTL | 回送控制字符为(char) |
ECHO | 进行回送 | ECHOPRT | 硬拷贝的可见擦除方式 |
ECHOE | 可见擦除字符 | ECHOKE | Kill 的可见擦除 |
ECHOK | 回送 kill 符 | PENDIN | 重新打印未决输入 |
ECHONL | 回送 NL | TOSTOP | 对于后台输出发送 SIGTTOU |
控制字符组:
标志 | 说明 | 标志 | 说明 |
---|---|---|---|
VINTR | 中断 | VEOL | 行结束 |
VQUIT | 退出 | VMIN | 需读取的最小字节数 |
VERASE | 擦除 | VTIME | 与“VMIN”配合使用,是指限定的传输或等待的最长时间 |
VEOF | 行结束 |
示例代码:
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#define TRUE 1
#define FALSE (-1)
int serialAttr(int baudrate, int databit, char paritybit, int stopbit);
int main(void)
{
serialAttr(9600, 8, 'N', 1);
return 0;
}
int serialAttr(int baudrate, int databit, char paritybit, int stopbit)
{
int fd;
fd = open("/dev/ttyx",O_RDWR | O_NOCTTY); //读写方式打开;不作为控制终端
if(fd == -1)
{
return FALSE;
}
/*更改波特率*/
int status;
struct termios opt;
tcgetattr(fd,&opt);//获取终端参数
tcflush(fd,TCIOFLUSH);//刷清输入输出缓存
cfsetispeed(&opt,baudrate);//设置输入的波特类
cfsetospeed(&opt,baudrate);//设置输出的波特类
/*数据位、停止位、校验位*/
opt.c_cflag |= (CLOCAL | CREAD);
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//原始模式,输入数据不经处理
opt.c_oflag &= ~OPOST; //原始输出
opt.c_iflag &= ~(BRKINT | ICRNL | ISTRIP | IXON);
opt.c_cflag &= ~CSIZE; //数据位清零
switch (databit) //数据位
{
case 7:
opt.c_cflag |= CS7;break;
case 8:
opt.c_cflag |= CS8;break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (paritybit) //校验位
{
case 'n':
case 'N':
opt.c_cflag &= ~PARENB; // 不校验
opt.c_iflag &= ~INPCK; //关闭输入奇偶校验
opt.c_iflag &= ~(ICRNL|IGNCR);
opt.c_lflag &= ~(ICANON ); //不规范输入
break;
case 'o': //奇校验
case 'O':
opt.c_cflag |= PARENB; //进行奇偶校验
opt.c_cflag |= PARODD; //奇校验,否则为偶校验
opt.c_iflag |= INPCK; //打开输入奇偶校验
break;
case 'e': //偶校验
case 'E':
opt.c_cflag |= PARENB; // 进行奇偶校验
opt.c_cflag &= ~PARODD; //偶校验
opt.c_iflag |= INPCK; //打开输入奇偶校验
break;
case 'S':
case 's': /*as no parity*/
opt.c_cflag &= ~PARENB; //不进行奇偶校验
opt.c_cflag &= ~CSTOPB; //1 位停止位
break;
default:
fprintf(stderr,"Unsupported parity bit\n");
return (FALSE);
}
switch (stopbit) //停止位
{
case 1:
opt.c_cflag &= ~CSTOPB;break; //1 位停止位
case 2:
opt.c_cflag |= CSTOPB;break; //2 位停止位,否则为 1 位
default:
fprintf(stderr,"Unsupported stop bit\n");
return (FALSE);
}
opt.c_cc[VTIME] = 150; // 等待数据到达的分秒数(秒的 1/10 为分秒)
opt.c_cc[VMIN] = 0; // read 调用期望返回的最小字节数
tcflush(fd,TCIFLUSH); // 刷清输入缓存区
if (tcsetattr(fd,TCSANOW,&opt) != 0) //TCSANOW:不等数据传输完毕就立即改变属性。
{
perror("Setup serial port fail\n");
return FALSE;
}
else
{
return TRUE;
}
}