串口的设置主要是设置struct termios结构体
#include<termios>
struct termios
{
unsigned short c_iflag;//输入模式标志
unsigned short c_oflag;//输出模式标志
unsigned short c_cflag;//控制模式标志
unsigned short c_lflag;//本地模式标志
unsigned short c_line;//线路规程
unsigned short c_cc[NCC];//控制特性
speed_t c_ispeed;//输入速度
speed_t c_ospeed;//输出速度
};
中端有三种工作模式:c_lflag:规范模式(ICANNON)非规范模式(清除ICANNON)原始模式(调用函数cfmakeraw())
在规范模式下,所有的输入是基于行进行处理。在用户输入一个行结束符(回车符,EOF等)之前,系统调用read()函数读不到用户输入的任何字符。除了EOF之外的行结束符(回车符等)与普通字符一样会被read()函数读到缓冲区中。在规范模式中,行编程是可行的,而且一次调用read()函数最多只能读到一行的数据。如果在read()函数中北请求读取的数据字节数小于当前行可读取的字节数,则read()函数只会读取被请求的字节数,剩下的字节下次在被读取。
在非规范模式下,所有的输入是即时有效的,不需要用户另外输入行结束符,而且不可进行行编程。在非规范模式下,对参数MIN(c_cc[VMIN])和TIME(c_cc[VTIME])的设置决定read(0函数的调用方式。设置可用有4中不同的情况。
MIN=0和TIME=0:read()函数立即返回。若有可读数据,则读取数据并返回被读取的字节数,否则读取失败并返回0.
MIN>0和TIME=0:read()函数会被阻塞直到MIN个字节数据可被读取。
MIN=0和TIME>0:只要有数据或者经过TIME个十分之一秒得时间,read()函数则立即返回,返回值为被读取的字节数。如果超时并且未数据,则read()函数返回0.
MIN>0和TIME>0:当有MIN个字节可读或着两个输入字符之间的时间间隔超过TIME个十分之一秒时,read()函数才返回。因为在输入第一个字符之后系统才会启动定时器,所以在这种情况下,read()函数至少读取一个字节之后才返回。
按照严格的意义来讲,原始模式是一种特殊的非规范模式。在原始模式下,所有的输入数据以字节为单位被处理。在这个模式下,终端是不可回显的,而且所有特定的终端输入输出控制处理不可用。通过嗲用cfmakeraw()函数可以将终端设置为原始模式。
设置串口属性的基本流程
1保存原先传奇偶配置tcgetattr(fd,&old_cfg)
2激活选项 CLOCAL和CREAD分别用于本地连接和接收使能。new_cfg.c_cflag |= CLOCAL | CREAD;
3设置波特率 cfsetispeed(&new_cfg,B115200) cfsetospeed(&new_cfg,B115200)
4设置字符大小 new_cfg.c_cflag &= ~CSIZE;new_cfg.c_cflag |=CS8;
5设置奇偶校验位
6设置停止位new_cfg.c_cflag &= ~CSTOPB; new_cfg.c_cflag |=CSTOPB;
7设置最少字符和等待时间
8清除串口缓冲
9激活配置tcsetattr(int fd,int optional_actions,const struct termios *termios_p)
optional_actions 可能的取值有3种:
TCSANOW:配置的修改立即生效。
TCSADRAIN:配置的修改在所有写入fd的输出都传输完毕之后生效
TCSAFLUSH:所有已接收但未读入的输入都将在修改生效之前被丢弃。
下面是串口配置的完整函数:
int set_con_config(int fd,int baud_rate,int data_bits,cha parity,int stop_bits)
{
strut termios new_cfg,old_cfg;
int speed;
if(tcgetattr(fd,&old_cfg) !=0)
{
perror("tcgetattr");
return -1;
}
new_cfg= old_cfg;
cfmakeraw(&new_cfg);
new_cfg.c_cflag &=~CSSIZE;
switch(baud_rate)
{
case 2400:
{
speed=B2400;
}
case 2400:
{
speed=B2400;
}
....
}
}
串口使用:
1打开串口
fd= open("/dev/ttys0",ORDWR|O_NOCTTY|O_NDELAY);
O_NOCTTY 标志用于通知linux系统,改参数不会是打开的文件成为这个进程的控制终端。如果没有指定这个标志,那么任何一个输入都将会影响用户的进程。
O_NDELAY 标志通知linux系统,这个程序不关心DCD信号线所处的状态(端口的另一端是否激活或者停止)。如果用户指定了这个标志,则就能成将会一直处于睡眠状态,直到DCD信号线被激活。
设置串口的状态为阻塞状态,用于等待串口数据的读入,可用fcntl()
fcntl(fd,F_SETFL,0);
测试打开文件描述符是否连接到一个终端设备,以进一步确认串口是否正确打开
isatty(STDIN_FILENO);
2读写串口
write(fd,buff,strlen(buff));
read(fd,buff,BUFF_SIZE);