嵌入式linux串口编程

2019-07-12 17:52发布

  串口的设置主要是设置struct termios结构体 #include 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);