• 痞子衡嵌入式:嵌入式里串口(UART)自动波特率识别程序设计与实现(轮询)



      大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是嵌入式里串口(UART)自动波特率识别程序设计与实现

      本篇是 《串口(UART)自动波特率识别程序设计与实现(中断)》 的续集,上一篇我们利用 GPIO 模块自带的下降沿中断功能实现了 RXD 电平跳变捕捉与计时,今天我们再试试古老的轮询 RXD 管脚电平的方法去实现同样的功能。

      轮询法最大的缺点是会阻塞系统(不考虑 RTOS 调度),但是它也有中断法所没有的特点(或者说不太方便做到的),在做轮询时,我们可以采取一些经典的管脚电平软件消抖措施,从而降低误识别率。

    一、串口(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)自动波特率识别程序设计与实现痞子衡便介绍完毕了,掌声在哪里~~~

    欢迎订阅

    文章会同时发布到我的 博客园主页CSDN主页知乎主页微信公众号 平台上。

    微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

      最后欢迎关注痞子衡个人微信公众号【痞子衡嵌入式】,一个专注嵌入式技术的公众号,跟着痞子衡一起玩转嵌入式。

    痞子衡嵌入式-微信二维码 痞子衡嵌入式-微信收款二维码 痞子衡嵌入式-支付宝收款二维码

      衡杰(痞子衡),目前就职于恩智浦MCU系统部门,担任嵌入式系统应用工程师。

      专栏内所有文章的转载请注明出处:http://www.cnblogs.com/henjay724/

      与痞子衡进一步交流或咨询业务合作请发邮件至 hengjie1989@foxmail.com

      可以关注痞子衡的Github主页 https://github.com/JayHeng,有很多好玩的嵌入式项目。

      关于专栏文章有任何疑问请直接在博客下面留言,痞子衡会及时回复免费(划重点)答疑。

      痞子衡邮箱已被私信挤爆,技术问题不推荐私信,坚持私信请先扫码付款(5元起步)再发。


  • 相关阅读:
    POJ 3687 Labeling Balls <<拓扑排序
    FATFS 初学之 f_mount
    STM8 低功耗时钟管理
    还记得 C中带参宏的 "#"号吗?
    8.9并发编程(一)
    8.8网络编程(三)
    8.7网络编程(二)
    8.6网络编程(一)
    7.30反射、元类及项目生命周期
    7.29多态
  • 原文地址:https://www.cnblogs.com/henjay724/p/14882905.html
Copyright © 2020-2023  润新知