加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

古老的輪詢法也能實(shí)現(xiàn)串口自動(dòng)波特率識別

2021/06/17
876
閱讀需 4 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家分享的是嵌入式里串口(UART)自動(dòng)波特率識別程序設(shè)計(jì)與實(shí)現(xiàn)。

本篇是 《串口(UART)自動(dòng)波特率識別程序設(shè)計(jì)與實(shí)現(xiàn)(中斷)》 的續(xù)集,上一篇我們利用 GPIO 模塊自帶的下降沿中斷功能實(shí)現(xiàn)了 RXD 電平跳變捕捉與計(jì)時(shí),今天我們再試試古老的輪詢 RXD 管腳電平的方法去實(shí)現(xiàn)同樣的功能。

輪詢法最大的缺點(diǎn)是會(huì)阻塞系統(tǒng)(不考慮 RTOS 調(diào)度),但是它也有中斷法所沒有的特點(diǎn)(或者說不太方便做到的),在做輪詢時(shí),我們可以采取一些經(jīng)典的管腳電平軟件消抖措施,從而降低誤識別率。

  • 程序主頁:https://github.com/JayHeng/cortex-m-apps/tree/master/components/autobaud

一、串口(UART)自動(dòng)波特率識別程序設(shè)計(jì)

1.1 函數(shù)接口定義

輪詢法與中斷法函數(shù)接口保持一致,詳見 《串口(UART)自動(dòng)波特率識別程序設(shè)計(jì)與實(shí)現(xiàn)(中斷)》  1.1 小節(jié),兩者共享頭文件:autobaud.h,這樣方便項(xiàng)目設(shè)計(jì)時(shí)自由切換自動(dòng)波特率識別方法。

1.2 識別設(shè)計(jì)思想

關(guān)于識別的思路,輪詢法與中斷法也是一致的,詳見 《串口(UART)自動(dòng)波特率識別程序設(shè)計(jì)與實(shí)現(xiàn)(中斷)》  1.2 小節(jié),但是輪詢法里多了手動(dòng)檢測 RXD 引腳電平下降沿跳變的過程。

引腳電平跳變檢測其實(shí)也很簡單,就是不斷讀取引腳輸入電平值,并比較相鄰兩次輸入電平值,如果發(fā)現(xiàn)不一致,則是跳變發(fā)生之時(shí)。如果前一次電平值是高,那么此時(shí)便是下降沿。

 

1.3 主代碼實(shí)現(xiàn)

根據(jù)上一小節(jié)描述的設(shè)計(jì)思想,我們很容易寫出下面的主代碼(autobaud_poll_v2.1.c),代碼里痞子衡都做了詳細(xì)注釋。相比中斷法源代碼,我們其實(shí)只需要修改 autobaud_get_rate() 函數(shù)實(shí)現(xiàn)如下:

//! @brief 讀取GPIO管腳輸入電平
extern uint32_t read_autobaud_pin(void);

bool autobaud_get_rate(uint32_t *rate)
{
    // 僅當(dāng)電平為低(非空閑態(tài))時(shí)才開始識別
    uint32_t currentEdge = read_autobaud_pin();
    if (currentEdge != 1)
    {
        pin_transition_callback();
        uint32_t previousEdge = currentEdge;
        while (s_transitionCount < kFirstByteRequiredFallingEdges + kSecondByteRequiredFallingEdges)
        {
            // 檢查是否有電平翻轉(zhuǎn)
            currentEdge = read_autobaud_pin();
            if (currentEdge != previousEdge)
            {
                // 僅當(dāng)電平翻轉(zhuǎn)是下降沿時(shí)
                if (previousEdge == 1)
                {
                    pin_transition_callback();
                }
                previousEdge = currentEdge;
            }
        }

        // 計(jì)算出實(shí)際檢測到的波特率值
        uint32_t calculatedBaud =
            (microseconds_get_clock() * (kNumberOfBitsForFirstByteMeasured + kNumberOfBitsForSecondByteMeasured)) /
            (uint32_t)(s_firstByteTotalTicks + s_secondByteTotalTicks);
        // 對實(shí)際檢測出的波特率值做對齊處理
        // 公式:rounded = stepSize * (value/stepSize + .5)
        *rate = ((((calculatedBaud * 10) / kAutobaudStepSize) + 5) / 10) * kAutobaudStepSize;

        return true;
    }
    else
    {
        return false;
    }
}

二、串口(UART)自動(dòng)波特率識別程序?qū)崿F(xiàn)

前面講的都是硬件無關(guān)設(shè)計(jì),但最終還是要落實(shí)到具體 MCU 平臺上的,其中 GPIO 讀取部分是跟 MCU 緊相關(guān)的。我們以恩智浦 i.MXRT1011 為例來介紹硬件實(shí)現(xiàn)。

2.1 軟件消抖實(shí)現(xiàn)

恩智浦 MIMXRT1010-EVK 有板載調(diào)試器 DAPLink,這個(gè) DAPLink 中也集成了 USB 轉(zhuǎn)串口的功能,對應(yīng)的 UART 引腳是 IOMUXC_GPIO_09_LPUART1_RXD 和 IOMUXC_GPIO_10_LPUART1_TXD,我們就選用這個(gè)管腳 GPIO1[9] 做自動(dòng)波特率檢測,引腳電平讀取函數(shù)代碼如下:

#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);
    }

    // 如某電平值出現(xiàn)幾率超過半數(shù),則認(rèn)定為有效電平
    return (readCount < (AUTOBAUD_PIN_DEBOUNCE_READ_COUNT / 2)) ? 0 : 1;
}

關(guān)于 I/O 軟件消抖,一般有兩種實(shí)現(xiàn):一、是兩次 I/O 讀取之間加一定延時(shí)(us級別),如兩次值一樣,則認(rèn)定有效,否則重復(fù)此過程;二、是多次讀取 I/O 值,取其中出現(xiàn)幾率超過一半的那個(gè)電平值。前者主要適用按鍵的場景,后者更適用本文輪詢法自動(dòng)波特率識別場景。

2.2 在MIMXRT1010-EVK上實(shí)測

最后就是在板子上實(shí)測,因?yàn)樵谠O(shè)計(jì)上輪詢法與中斷法接口是一致的,因此測試主函數(shù)代碼完全不用修改,詳見 《串口(UART)自動(dòng)波特率識別程序設(shè)計(jì)與實(shí)現(xiàn)(中斷)》  2.2 小節(jié)。測試結(jié)果同樣達(dá)到了預(yù)期效果。

至此,嵌入式里串口(UART)自動(dòng)波特率識別程序設(shè)計(jì)與實(shí)現(xiàn)痞子衡便介紹完畢了,掌聲在哪里~~~

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學(xué)電子信息學(xué)院,目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)部門,擔(dān)任嵌入式系統(tǒng)應(yīng)用工程師。痞子衡會(huì)定期分享嵌入式相關(guān)文章