串口波特率自动检测的一种工程实现:分段特征值匹配

来源:互联网 发布:南笙姑娘知乎 编辑:程序博客网 时间:2024/06/05 04:44

最近做的一个linux上的项目,串口需要对上位机的未知波特率自适应,在google了一通之后找到满多的资源,但是都不能满足项目的需要,最后借鉴前人的做法,终于解决了问题,这里把方法记录下来,和大家分享一下。

 

一、需求

      自动检测到上位机的典型波特率(1200,1800,2400,4800,9600,19200,38400,57600,115200)。

 

二、已知方法

      主要参考资料:

      1)http://www.iol.ie/~ecarroll/autobaud.html

      2)http://documentation.renesas.com/eng/products/region/rtas/mpumcu/apn/autobaud.pdf

      网上其它的资料基本上都不超出上面两篇文章的范畴,采用的方法也基本类似,假设本机初始波特率为9600,上位机发送回车符0x0D给本机,则可以归纳为:

      a)上位机波特率<=600,采用时间测量法;

      b)上位机波特率>=1200,采用特征值匹配法。

 

Baud  Bit pattern received at 9600 baud        Byte
19200  01011000011111111111                     0xF?

9600  0 1 0 1 1 0 0 0 0 1                      0x0D
4800  0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1  0xE6
2400  0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1  0x78
1800  0 0 0 0 0 x 1 1 1 1 x 0 0 0 0 0 1 1 1 1  0xE0
1800  0 0 0 0 0 x 1 1 1 1 x 0 0 0 0 0 1 1 1 1  0xF0
1200  0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0  0x80
  600  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1  0x00
  300  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0x00
  150  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0x00
  110  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0x00

 

      方法是简单易懂的,但是用于实际的工程项目中却并不一定实用。特别是前面提到的时间测量法,不同的机器,不一样的配置,时间值变化太大,估算起来太麻烦。相比较而言特征值匹配法中的特征值却比较稳定。但是特征值匹配法也有问题,在实际的操作中我发现,当上位机的波特率>=19200时,特征值也开始变得不那么稳定了,甚至有时候上位机给本机发送一个字符,本机根本接收不到的情况也时有发生。也就是说对于本机波特率为9600,上位机波特率>=19200的情况,特征值匹配法就会失效。

 

三、改进的方法

      针对现有方法中存在的问题,结合项目的需求,我们进行了改进。我们只使用特征值匹配的方法。但是,前面我们说了,本机波特率为9600时,当上位机的波特率>=19200时,特征值也开始变得不那么稳定了,甚至有时候上位机给本机发送一个字符,本机根本接收不到的情况也时有发生(如上位机波特率为115200时)。

      所以,我们将本机的初始波特率设定为115200,这样

 

Baud  Bit pattern received at 9600 baud        Byte
230400  01011000011111111111                     0xF?

115200  0 1 0 1 1 0 0 0 0 1                      0x0D
57600  0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1  0xE6
38400  0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 0  0x1C
19200  0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1  0xE0
  9600  0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1  0x00
  4800  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0x00
  2400  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0x00

  1800  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0x00
  1200  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0x00

      对于上位机波特率<=9600的情况,我们不使用时间测量法,根据上表,可以看到,在这种情况下,特征值都为0x00,我们可以利用这一点进行二次检测。当我们初次检测发现特征值为0x00时,我们将本机的波特率调整设置为9600,再继续从上位机接收数据,结合最开始的表格来进行波特率的检测。这种情况下上位机需要向本机发送两个回车符0x0D。

      使用上面的方法优点为:

      1)由于我们只使用特征值匹配法,而本机特定波特率下的特征值是相对唯一的,相比较估算的时间测量法,检测出来的准确率高。

      2)我们可以将该方法扩展到任意范围的波特率检测中去,而不局限于这里所给出的范围,主要的思想就是这里的分段检测。

      缺点:

      1)主要是检测时需要上位机发送的字节增加了,一般来说,分段分得越多,需要上位机发送的字节也就越多。

 

四、结束语

      知识有限,如有不周之处请大家海涵。转载请留名。

      不知道有没有更好的方法,有的话大家分享一下啊。

原创粉丝点击