串口设置(波特率、数据位、校验位、停止位)

串口终端设备的接口属性如下:

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;

需要包含的头文件
下面介绍一下各个标志的选项

控制标志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 
#include 
#include 

#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;
	}
}

你可能感兴趣的:(Linux,C)