zhangchaoying 发表于 2014-10-25 21:36:22

【资料分享】串口速率,我拿什么识别你?

本帖最后由 zhangchaoying 于 2014-10-25 21:37 编辑

UART串口,作为单片机最常用的通讯接口已经深入每一个嵌入式工程师的脑海。UART串口有着简单、实用的特性,嵌入式工程师常常用来将其作为调试系统的重要工具。UART串口的配置参数有很多,但是最常用,且需要修改的参数只有通讯波特速率这一个。可是这仅有的一个参数又常常给我们带来许多困扰。那么,我们对于串口波特速率该如何识别呢?笔者在这里介绍三种识别串口速率的方法,供大家参考。
UART(Universal Asynchronous serial Receiver and Transmitter)异步串行接收/发送接口,是嵌入式系统里最为重要的接口之一,它不仅用于板级芯片之间的通讯,而且应用于实现系统之间的通信和系统调度中。UART作为异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输,其字符数据帧格式如下图所示:
1.jpg
图1 UART字符数据帧格式
从上面图中的帧格式可以看出,UART数据帧由1个开始同步位,1个数据字,1个结束停止位,以及可选的校验位组成。由于UART为异步通讯,因此,其按位发送时必须严格遵守设定的波特率,而接收方也必须在相同的波特率下才能正确解析发送的字符数据。于是,接收方正确识别、配置波特率就相当关键了。下面笔者根据实际经验介绍三种识别串口波特率的方法:
穷举法
理论上,发送波特率可以设定为任意的值,但是平时我们使用的串口速率只有这么几种数值,如图2所示:
2.jpg
图2 常用串口波特速率
既然知道了常用串口速率,于是我们就可以一个一个试,总会有一个是成功。当然前提是我们知道主机发送的内容是什么,否则如何才能知道串口速率正确匹配呢!这里必须注意,在设定波特率与实际波特率成倍数的情况下,是可以读出来数据——当然,数据是错误的。
示波器法
示波器被秒为电子工程师的“眼睛”,我们可以就用这双眼睛来“看”出串口发送数据的波特率。这里我们先排除掉高端的带有数字逻辑分析功能的示波器,因为,这样的示波器已经远超笔者的IQ了,不是我们本篇讨论的内容。
上一部分,我们讲述了波形的帧格式,这里我们就利用波形,发送一个特殊的字符0x55(1010 1010B)。从理论上面分析,这个波形应该会产生一个按位翻转的波形效果。图3是笔者使用示波器采集下来的截图:
3.jpg
图3 9600bps发送0x55波形图
看到图3所示的波形图,再加上理论分析,我们知道波形是按位翻转,于是我们使用示波器的指针功能(cursor)来直接查看波特率。如图3左上角的测量结果显示,每位翻转的频率为9.615KHz,与我们设定的频率9600kbps基本相符,可以确定此发送频率为9600bps。
芯片自识别法
UART串口常常用来做为固件升级使用的接口,因此,其波特率要根据上位机的实际情况而定。如果环境较差时,就需要使用低波特率的通讯。这时,自动波特率识别的方法就诞生了。下面我们以TI Stellaris里bootloader里的串口波特率自动识别源程序为例进行分析:
int UARTAutoBaud(unsigned long *pulRatio){
long lPulse, lValidPulses, lTemp, lTotal;
volatile long lDelay;
// 配置systick,将其值设定为最大值;
HWREG(NVIC_ST_RELOAD) = 0xffffffff;
HWREG(NVIC_ST_CTRL) = NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_ENABLE;
// 打开引脚的边沿触发中断
HWREG(GPIO_PORTA_BASE + GPIO_O_IBE) = UART_RX;
// 使能UART RXD引脚边沿触发中断
HWREG(NVIC_EN0) = 1;
// 采集引脚边沿中断,两个字节的边沿
while(g_ulTickIndex < MIN_EDGE_COUNT)
{
}
// 计算systick采样下来的值,对溢出进行处理
for(lPulse = 0; lPulse < (MIN_EDGE_COUNT - 1); lPulse++){
lTemp = (((long)g_pulDataBuffer -
(long)g_pulDataBuffer) & 0x00ffffff);
g_pulDataBuffer = lTemp;
}
// 此循环计算两个连续脉冲之间的宽度
for(lPulse = 0; lPulse < (MIN_EDGE_COUNT - 1); lPulse++){
// 精确计算两个连续脉冲之间的宽度
lTemp = (long)g_pulDataBuffer;
lTemp -= (long)g_pulDataBuffer;
if(lTemp < 0) {
lTemp *= -1;
}
// 验证两个边沿的脉宽是否正确,其算法如下:
// abs(Pulse - Pulse) < Pulse / PULSE_DETECTION_MULT
// 或者
// PULSE_DETECTION_MULT * abs(Pulse - Pulse) < Pulse
if((lTemp * PULSE_DETECTION_MULT) < (long)g_pulDataBuffer) {
lTotal += (long)g_pulDataBuffer;
lValidPulses++;
}
else{
lValidPulses = 0;
lTotal = 0;
}
// 7个有效脉冲,就可以计算UART串口速率
if(lValidPulses == 7) {
// 将最后一个脉冲加入计数器,并计算波特率
lTotal += (long)g_pulDataBuffer;
*pulRatio = lTotal >> 1;
// 返回成功标识
return(0);
}
}
// 检测失败
return(-1);
}
UART串口有着这样或者那样的优点,但新兴的USB接口的USB DFU功能可以更加有效替代串口来完成固件升级;性能优越的CAN总线,其硬件价格不断下降,而且CAN总线的MAC接口更多集成在最新MCU芯片上;CAN2.0B接口正在挤压着UART接口器件的市场;对于我们普通民众,现在新型号电脑已经没有DB9串口座。在残酷的现实下,多年后也许只有我们电子工程师才会记得曾经的简单、实用的UART串口。

网址http://www.21ic.com/app/mcu/201409/602500.htm

fengyunyu 发表于 2014-10-25 21:45:34

有单片机支持波特率自动识别的。

zhangchaoying 发表于 2014-10-25 21:51:19

fengyunyu 发表于 2014-10-25 21:45
有单片机支持波特率自动识别的。

什么单片机支持波特率自动识别的?

fengyunyu 发表于 2014-10-25 22:04:02

zhangchaoying 发表于 2014-10-25 21:51
什么单片机支持波特率自动识别的?

貌似前几天看一个单片机的介绍,支持串口波特率的自动识别,型号搞忘了。

zhangchaoying 发表于 2014-10-25 22:19:53

fengyunyu 发表于 2014-10-25 22:04
貌似前几天看一个单片机的介绍,支持串口波特率的自动识别,型号搞忘了。 ...

你这么说我以为神器早已普遍。呵呵

myin4 发表于 2014-10-25 22:22:28

zhangchaoying 发表于 2014-10-25 21:51
什么单片机支持波特率自动识别的?

STM32F0,不过貌似要特定字符

sup888 发表于 2014-10-25 22:25:34

Mark.示波器用的不太熟的路过。

syflash 发表于 2014-10-25 23:05:12

mark                        

步之道 发表于 2014-10-26 00:19:44

识别别人的波特率,能理解是准备抄别人的通讯协议吗?

gao5528 发表于 2014-10-26 09:14:36

好贴,谢谢了。

zhangchaoying 发表于 2014-10-26 09:15:47

步之道 发表于 2014-10-26 00:19
识别别人的波特率,能理解是准备抄别人的通讯协议吗?

高手完全可以这么干啊~

lzgs2866 发表于 2014-10-26 09:38:30

用逻辑分析仪吧

wh9602 发表于 2014-10-26 09:40:45

hen牛,深入啊

zhangchaoying 发表于 2014-10-26 09:41:26

lzgs2866 发表于 2014-10-26 09:38
用逻辑分析仪吧

1000+的逻辑分析仪,咱不是搞破解

步之道 发表于 2014-10-26 18:14:23

zhangchaoying 发表于 2014-10-26 09:15
高手完全可以这么干啊~

出门左走,金石滩逻辑分析仪才是利器啊。

浪里白条 发表于 2014-10-26 19:09:36

学习了,需要去识别串口分辨率一般在什么场合用得到呢?

salahading 发表于 2014-10-26 19:28:23

多说几次,就明白了

1431897797 发表于 2014-10-26 21:02:55

本帖最后由 1431897797 于 2014-10-26 21:04 编辑

用串口波特率转换器立即搞定:串口波特率转换器http://www.amobbs.com/thread-5599521-1-1.html   
只需要用一个波特率转换器,把几种波特率一一都试试,一定有一个是正确的。

zhangchaoying 发表于 2014-10-26 21:32:56

1431897797 发表于 2014-10-26 21:02
用串口波特率转换器立即搞定:串口波特率转换器http://www.amobbs.com/thread-5599521-1-1.html   
只需要 ...

         姊妹贴~http://www.amobbs.com/thread-5599521-1-1.html

zhangchaoying 发表于 2014-10-26 21:34:07

浪里白条 发表于 2014-10-26 19:09
学习了,需要去识别串口分辨率一般在什么场合用得到呢?

            做串口国产飞卡~调试器?{:lol:}

mcucow 发表于 2014-10-27 09:01:53

串口速率能自动识别当然好
不过 等你识别出来 前面的命令是不是就丢了 串口监控会丢数据当然可以用缓存方案来弥补 但貌似有点牵强 除非是不得已为之
所以 事先定义好 个人认为比较实在
页: [1]
查看完整版本: 【资料分享】串口速率,我拿什么识别你?