大鹏新区住房建设局网站,手机网站建站费用,无极招聘网最新招聘,阿里云买完域名空间如何做网站为什么需要波特率自动检测机制
我们都知道#xff0c;串口通讯是需要约定波特率才能够进行准确的通讯。此时假设#xff0c;你们公司开发了一个板子#xff0c;有一个串口与外接设备进行通讯。因为你们公司开发的产品要提供给多个客户#xff0c;而有些客户可能之前就有一…为什么需要波特率自动检测机制
我们都知道串口通讯是需要约定波特率才能够进行准确的通讯。此时假设你们公司开发了一个板子有一个串口与外接设备进行通讯。因为你们公司开发的产品要提供给多个客户而有些客户可能之前就有一个类似功能的产品之所以现在用你们公司的产品可能是基于安全价格稳定性等因素考虑。现在你规定自己板子上的串口波特率为115200而你客户之前用的那个产品波特率是9600。你板子都要卖给客户总不可能要求客户去该他们的波特率吧。好你们公司为了保住这个订单现在修改波特率为9600然后安排人将程序重新烧录到产品中。这个订单是保住了现在又来了一个客户他们也想要用你们的产品不过他们的波特率是19200。没办法客户是上帝你们又得重新修改波特率然后烧录。人工成本也是钱呀所以说如果不提出一个好的解决办法这家公司迟早会凉凉。为了解决这个问题我们可用用0x55/0xAA这两个特殊值进行处理。
波特率自动检测机制的原理
我们知道0x55/0xAA从二进制角度来看就是变化的0和1。我们知道0是低电平1是高电平。而0x55/0xAA这两个特殊的值每次变化时候他们的0和1都是1bit。因此我们只需要计算出一个高电平或者一个低电平的持续时间即可算出波特率。例如现在我们截取0x55/0xAA波形中的一小段如下。现在如果我想知道这里的波特率只需要测量出图中所指示的低电平部分持续时间即可。测量低电平持续时间也很简单打开MCU的双边沿检测。对端设备串口发送0x55/0xAA此时MCU检测到下降沿那么就打开定时器当检测到上升沿那么就关闭定时器。最终将定时器中的值读取出来即可算出波特率。 代码
如下为网上找到的一段波特率自适应的代码我进行简单的分析。这里就是让 GPIO10 作为 RX 输入不过将该引脚设置为 UART 之前先将该引脚设置为浮空输入测试出对端设备的波特率然后再将该引脚设置为 UART。打开定时器之后 CPU 轮询 GPIO10检测 32 次该引脚的电平变化找到最大的两次电平变化差值。然后再将该值进行 0.75% 的修正。最终返回算出来的波特率。这个时候肯定会有人问如果对端设备的波特率是 115200但是我算出来的是115249 阁下如何应对呢木有关系首先 UART 是存在一个波特率误差容限的而且你在设置一个非标准波特率时芯片也会匹配到一个接近的标准波特率。因为波特率本身就是利用时钟产生的。
u32 USART1_Baud(void)
{u16 t10,t2,t0; // 定时器寄存器为16位u32 b1,b2;u32 i;GPIO_Init(GPIOA, 10, GPIO_IN_FLOAT); // GPIOA.10浮空输入TIM_Open(Tim3); // 开TIM3的时钟TIM_Enable(TIM3); // 开启TIM3b1 GPIO_Pin_Get(GPIOA,10); // 读GPIOA.10的电平for(i0;i32;) // 连续检测GPIO.10引脚32次电平变化{b2 GPIO_Pin_Get(GPIOA,10); // 读GPIOA.10的新值if(b2 ! b1) // 如果有电平变化{t2 TIM3-COUNT; // 读定时器中的值b1 b2; // 更新为新的引脚值if((t1 0)(t0)) // 第一个电平变化{t1 t2; // 记录第一个时刻点}else // 不是第一个电平变化{if(t 0) // 第一段电平{t t2-t1; // 记录第一段电平所用时间}else // 不是第一段电平{if((t2-t1) t) // 保留电平段的最小值{t t2-t1;}}t1 t2; // 更新为新的时刻点}i; // 电平变化数1}}TIM_Close(Tim3); // 关闭TIM3的时钟return ((u32)t*403/400);// 修正波特率值(加上电平变化的斜率大概为0.75%经验值)
}参考
博客园UART串口波特率自适应