剖析非標(biāo)準(zhǔn)波特率的設(shè)置和使用于Linux操作系統(tǒng)中
Linux操作系統(tǒng)最近幾年的發(fā)展超過(guò)了微軟的想象,大有趕上微軟的趨勢(shì),于是也就有大部分人開(kāi)始學(xué)習(xí)Linux操作系統(tǒng),通常,在Linux下面,設(shè)置串口使用終端IO的相關(guān)函數(shù)設(shè)置,如tcsetattr等函數(shù),Linux內(nèi)部有一個(gè)對(duì)常用波特率列表的索引,根據(jù)設(shè)置的波特率用底層驅(qū)動(dòng)來(lái)設(shè)置異步通信芯片的寄存器
對(duì)于非標(biāo)準(zhǔn)的任意波特率需要用ioctl(fd, TIOCGSERIAL, p)和ioctl(fd, TIOCSSERIAL, p)的配合,ioctl的***一個(gè)參數(shù)是struct serial_struct *類型,在Linux/serial.h中定義。其中baud_base是基準(zhǔn)晶振頻率/16,通常是115200,你需要設(shè)的是custom_divisor這個(gè)值,最終的波特率為baud_base/custom_divisor,比如你需要28800,因?yàn)?15200/4=28800,所以要設(shè)置custom_divisor=4,。
具體過(guò)程為,先設(shè)置波特率設(shè)為38400(tcsetattr),然后用TIOCGSERIAL得到當(dāng)前的設(shè)置,將flags設(shè)置ASYNC_SPD_CUST位,設(shè)置custom_divisor,***用TIOCSSERIAL設(shè)置。
使用setserial其實(shí)就是利用上述方法,來(lái)設(shè)置baud_base, custom_divisor等, 其內(nèi)部實(shí)現(xiàn)就是使用ioctl來(lái)進(jìn)行設(shè)置,
另外還可以用硬件更換晶振,根據(jù)比例來(lái)達(dá)到使用一些非標(biāo)準(zhǔn)的波特率的目的.
參考:http://blog.ednchina.com/seam_liu/7181/post.aspx
- #include <termios.h>
- #include <sys/ioctl.h>
- #include <Linux/serial.h>
- struct serial_t {
- int fd;
- char *device;/*/dev/ttyS0,...*/
- int baud;
- int databit;/*5,6,7,8*/
- char parity;/*O,E,N*/
- int stopbit;/*1,2*/
- int startbit;/*1*/
- struct termios options;
- };
//設(shè)置為特訴波特率,比如28800
- int serial_set_speci_baud(struct serial_t *tty,int baud)
- {
- struct serial_struct ss,ss_set;
- cfsetispeed(&tty->options,B38400);
- cfsetospeed(&tty->options,B38400);
- tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/
- tcsetattr(tty->fd,TCSANOW,&tty->options);
- if((ioctl(tty->fd,TIOCGSERIAL,&ss))<0){
- dprintk("BAUD: error to get the serial_struct info:%s\n",strerror(errno));
- return -1;
- }
- ss.flags = ASYNC_SPD_CUST;
- ssss.custom_divisor = ss.baud_base / baud;
- if((ioctl(tty->fd,TIOCSSERIAL,&ss))<0){
- dprintk("BAUD: error to set serial_struct:%s\n",strerror(errno));
- return -2;
- }
- ioctl(tty->fd,TIOCGSERIAL,&ss_set);
- dprintk("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",
- baud,ss_set.custom_divisor,ss_set.baud_base);
- return 0;
- }
用法:只要指定serial_t的baud就可以了
- static struct serial_t __seri_conf[] = {
- [0] = {//connect with b board, ttyS0
- .device = "/dev/ttyS0",
- .baud = 28800,
- .databit = 8,
- .parity = 'N',
- .stopbit = 1,
- },
- };
以上就Linux操作系統(tǒng)下非標(biāo)準(zhǔn)波特率的設(shè)置和使用。