|
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 |
|