搜索
bottom↓
回复: 2

转帖:linux串口编程中非标准波特率的实现

[复制链接]

出0入0汤圆

发表于 2010-9-28 21:35:22 | 显示全部楼层 |阅读模式
linux下实现标准波特率的编程非常方便,这方面的资料也举不胜举。通常,在linux下面,设置串口使用终端IO的相关函数设置,如tcsetattr等函数,linux内部有一个对常用波特率列表的索引,根据设置的波特率用底层驱动来设置异步通信芯片的寄存器
但是在一些特定应用中需要用到非标准的波特率,比如125000、28800等,这种情况下,如何实现串口通信呢?linux同样提供了对非标准波特率的支持:
对于非标准的任意波特率需要用ioctl(fd, TIOCGSERIAL, p)和ioctl(fd, TIOCSSERIAL, p)的配合,ioctl的最后一个参数是struct serial_struct *类型,在linux/serial.h中定义。其中baud_base是基准晶振频率/16(对于SEP4020来说,baud_base=sysclk/16),你需要设的是custom_divisor这个值,最终的波特率计算公式为baud=baud_base/custom_divisor,所以要设置custom_divisor=baud_base/baud,。
具体过程为,先设置波特率设为38400(tcsetattr),然后用TIOCGSERIAL得到当前的设置,将flags设置ASYNC_SPD_CUST位,设置custom_divisor,最后用TIOCSSERIAL设置。
相关代码如下:
void set_baud(int fd, int baud)
{
        int   status;
        struct termios   Opt;
        struct serial_struct Serial;

        tcgetattr(fd, &Opt);        /*Get current options*/
        tcflush(fd, TCIOFLUSH);/*Flush the buffer*/     
        cfsetispeed(&Opt, B38400);/*Set input speed,38400 is necessary? who can tell me why?*/  
        cfsetospeed(&Opt, 38400); /*Set output speed*/
        tcflush(fd,TCIOFLUSH);        /*Flush the buffer*/
        status = tcsetattr(fd, TCSANOW, &Opt);  /*Set the 38400 Options*/
        if  (status != 0)
        {        
                perror("tcsetattr fd1");  
                return;     
        }   
                        
        if((ioctl(fd,TIOCGSERIAL,&Serial))<0)/*Get configurations vim IOCTL*/
        {
                printf("Fail to get Serial!\n");
                return;
        }
        Serial.flags = ASYNC_SPD_CUST;/*We will use custom buad,May be standard,may be not */
        Serial.custom_divisor=Serial.baud_base/baud;/*In Sep4020,baud_base=sysclk/16*/
        printf("divisor is %x\n",Serial.custom_divisor);
        if((ioctl(fd,TIOCSSERIAL,&Serial))<0)/*Set it*/
        {
                printf("Fail to set Serial\n");
                return;
        }
        ioctl(fd,TIOCGSERIAL,&Serial);/*Get it again,not necessary.*/
   printf("\nBAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",baud,Serial.custom_divisor,Serial.baud_base);
}

附件是一个在SEP4020开发板上实现的波特率为125000的串口通信例子,用跳线将两块4020开发板(俺用的一块Mini4020,一块Micro4020)的T/R交叉连接(两块开发板都使用的uart1,注意共地):
在Micro上用ADS初始化波特率后暂停程序运行,用内存察看窗口打开0x10006000地址,并打开定时刷新功能观察这个地址的内容变化,这个地址就是RX_FIFO,有数据收到的话会有变化,看变化的数据与发送方是否一致即可简单验证波特率设置是否正确。
在Mini上启动Linux系统,将附件中的uart.c编译成可执行程序并执行,即可观察到Micro的FiFO在0x31-0x36变化,与Linux应用程序发送的数据一致

转自:http://www.armfans.net
参考:http://blog.chinaunix.net/u3/103428/showart_2091817.html

出0入0汤圆

发表于 2010-9-29 04:16:25 | 显示全部楼层
Mark

出0入0汤圆

发表于 2014-3-24 15:08:57 | 显示全部楼层
学习了      
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 23:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表