剖析非标准波特率的设置和使用于Linux操作系统中


Linux操作系统最近几年的发展超过了微软的想象,大有赶上微软的趋势,于是也就有大部分人开始学习Linux操作系统,通常,在Linux下面,设置串口使用终端IO的相关函数设置,如tcsetattr等函数,Linux内部有一个对常用波特率列表的索引,根据设置的波特率用底层驱动来设置异步通信芯片的寄存器

对于非标准的任意波特率需要用ioctl(fd, TIOCGSERIAL, p)和ioctl(fd, TIOCSSERIAL, p)的配合,ioctl的最后一个参数是struct serial_struct *类型,在Linux/serial.h中定义。其中baud_base是基准晶振频率/16,通常是115200,你需要设的是custom_divisor这个值,最终的波特率为baud_base/custom_divisor,比如你需要28800,因为115200/4=28800,所以要设置custom_divisor=4,。

具体过程为,先设置波特率设为38400(tcsetattr),然后用TIOCGSERIAL得到当前的设置,将flags设置ASYNC_SPD_CUST位,设置custom_divisor,最后用TIOCSSERIAL设置。

使用setserial其实就是利用上述方法,来设置baud_base, custom_divisor等, 其内部实现就是使用ioctl来进行设置,

另外还可以用硬件更换晶振,根据比例来达到使用一些非标准的波特率的目的.

参考:http://blog.ednchina.com/seam_liu/7181/post.aspx

  1. #include <termios.h> 
  2. #include <sys/ioctl.h> 
  3. #include <Linux/serial.h> 
  4. struct serial_t {  
  5.     int     fd;  
  6.     char    *device;/*/dev/ttyS0,...*/  
  7.     int     baud;  
  8.     int     databit;/*5,6,7,8*/  
  9.     char    parity;/*O,E,N*/  
  10.     int    stopbit;/*1,2*/  
  11.     int    startbit;/*1*/  
  12.     struct termios    options;  
  13. }; 

//设置为特诉波特率,比如28800

  1. int serial_set_speci_baud(struct serial_t *tty,int baud)  
  2. {  
  3.     struct serial_struct ss,ss_set;  
  4.     cfsetispeed(&tty->options,B38400);  
  5.     cfsetospeed(&tty->options,B38400);  
  6.     tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/  
  7.     tcsetattr(tty->fd,TCSANOW,&tty->options);  
  8.     if((ioctl(tty->fd,TIOCGSERIAL,&ss))<0){  
  9.         dprintk("BAUD: error to get the serial_struct info:%s\n",strerror(errno));  
  10.         return -1;  
  11.     }  
  12.     ss.flags = ASYNC_SPD_CUST;  
  13.     ssss.custom_divisor = ss.baud_base / baud;  
  14.     if((ioctl(tty->fd,TIOCSSERIAL,&ss))<0){  
  15.         dprintk("BAUD: error to set serial_struct:%s\n",strerror(errno));  
  16.         return -2;  
  17.     }  
  18.     ioctl(tty->fd,TIOCGSERIAL,&ss_set);  
  19.     dprintk("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",  
  20.             baud,ss_set.custom_divisor,ss_set.baud_base);  
  21.     return 0;  

用法:只要指定serial_t的baud就可以了

  1. static struct serial_t __seri_conf[] = {  
  2.     [0] = {//connect with b board, ttyS0  
  3.         .device = "/dev/ttyS0",  
  4.         .baud = 28800,  
  5.         .databit = 8,  
  6.         .parity = 'N',  
  7.         .stopbit = 1,  
  8.     },  
  9. }; 

以上就Linux操作系统下非标准波特率的设置和使用。

相关内容