完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、串口(UART)自动波特率识别程序设计
1.1 函数接口定义 轮询法与中断法函数接口保持一致,详见 《串口(UART)自动波特率识别程序设计与实现(中断)》 1.1 小节,两者共享头文件:autobaud.h,这样方便项目设计时自由切换自动波特率识别方法。 1.2 识别设计思想 关于识别的思路,轮询法与中断法也是一致的,详见 《串口(UART)自动波特率识别程序设计与实现(中断)》 1.2 小节,但是轮询法里多了手动检测 RXD 引脚电平下降沿跳变的过程。 引脚电平跳变检测其实也很简单,就是不断读取引脚输入电平值,并比较相邻两次输入电平值,如果发现不一致,则是跳变发生之时。如果前一次电平值是高,那么此时便是下降沿。 1.3 主代码实现 根据上一小节描述的设计思想,我们很容易写出下面的主代码(autobaud_poll_v2.1.c),代码里痞子衡都做了详细注释。相比中断法源代码,我们其实只需要修改 autobaud_get_rate() 函数实现如下: //! @brief 读取GPIO管脚输入电平 extern uint32_t read_autobaud_pin(void); bool autobaud_get_rate(uint32_t *rate) { // 仅当电平为低(非空闲态)时才开始识别 uint32_t currentEdge = read_autobaud_pin(); if (currentEdge != 1) { pin_transition_callback(); uint32_t previousEdge = currentEdge; while (s_transitionCount < kFirstByteRequiredFallingEdges + kSecondByteRequiredFallingEdges) { // 检查是否有电平翻转 currentEdge = read_autobaud_pin(); if (currentEdge != previousEdge) { // 仅当电平翻转是下降沿时 if (previousEdge == 1) { pin_transition_callback(); } previousEdge = currentEdge; } } // 计算出实际检测到的波特率值 uint32_t calculatedBaud = (microseconds_get_clock() * (kNumberOfBitsForFirstByteMeasured + kNumberOfBitsForSecondByteMeasured)) / (uint32_t)(s_firstByteTotalTicks + s_secondByteTotalTicks); // 对实际检测出的波特率值做对齐处理 // 公式:rounded = stepSize * (value/stepSize + .5) *rate = ((((calculatedBaud * 10) / kAutobaudStepSize) + 5) / 10) * kAutobaudStepSize; return true; } else { return false; } } 二、串口(UART)自动波特率识别程序实现 前面讲的都是硬件无关设计,但最终还是要落实到具体 MCU 平台上的,其中 GPIO 读取部分是跟 MCU 紧相关的。我们以恩智浦 i.MXRT1011 为例来介绍硬件实现。 2.1 软件消抖实现 恩智浦 MIMXRT1010-EVK 有板载调试器 DAPLink,这个 DAPLink 中也集成了 USB 转串口的功能,对应的 UART 引脚是 IOMUXC_GPIO_09_LPUART1_RXD 和 IOMUXC_GPIO_10_LPUART1_TXD,我们就选用这个管脚 GPIO1[9] 做自动波特率检测,引脚电平读取函数代码如下: #define AUTOBAUD_PIN_DEBOUNCE_READ_COUNT (20U) uint32_t read_autobaud_pin(void) { // 多次读取管脚输入电平值 uint32_t readCount = 0; for (uint32_t i = 0; i < AUTOBAUD_PIN_DEBOUNCE_READ_COUNT; i++) { readCount += GPIO_PinRead(GPIO1, 9); } // 如某电平值出现几率超过半数,则认定为有效电平 return (readCount < (AUTOBAUD_PIN_DEBOUNCE_READ_COUNT / 2)) ? 0 : 1; } 关于 I/O 软件消抖,一般有两种实现:一、是两次 I/O 读取之间加一定延时(us级别),如两次值一样,则认定有效,否则重复此过程;二、是多次读取 I/O 值,取其中出现几率超过一半的那个电平值。前者主要适用按键的场景,后者更适用本文轮询法自动波特率识别场景。 2.2 在MIMXRT1010-EVK上实测 最后就是在板子上实测,因为在设计上轮询法与中断法接口是一致的,因此测试主函数代码完全不用修改,详见 《串口(UART)自动波特率识别程序设计与实现(中断)》 2.2 小节。测试结果同样达到了预期效果。 至此,嵌入式里串口(UART)自动波特率识别程序设计与实现痞子衡便介绍完毕了,掌声在哪里~~~ |
|
|
|
只有小组成员才能发言,加入小组>>
3308 浏览 9 评论
2988 浏览 16 评论
3490 浏览 1 评论
9049 浏览 16 评论
4083 浏览 18 评论
1167浏览 3评论
601浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
592浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2329浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1892浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 09:55 , Processed in 1.725317 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号