天天看點

痞子衡嵌入式:嵌入式裡序列槽(UART)自動波特率識别程式設計與實作(輪詢)

  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是嵌入式裡序列槽(UART)自動波特率識别程式設計與實作。

  本篇是 《序列槽(UART)自動波特率識别程式設計與實作(中斷)》 的續集,上一篇我們利用 GPIO 子產品自帶的下降沿中斷功能實作了 RXD 電平跳變捕捉與計時,今天我們再試試古老的輪詢 RXD 管腳電平的方法去實作同樣的功能。

  輪詢法最大的缺點是會阻塞系統(不考慮 RTOS 排程),但是它也有中斷法所沒有的特點(或者說不太友善做到的),在做輪詢時,我們可以采取一些經典的管腳電平軟體消抖措施,進而降低誤識别率。

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

一、序列槽(UART)自動波特率識别程式設計

1.1 函數接口定義

  輪詢法與中斷法函數接口保持一緻,詳見 《序列槽(UART)自動波特率識别程式設計與實作(中斷)》 1.1 小節,兩者共享頭檔案:autobaud.h,這樣友善項目設計時自由切換自動波特率識别方法。

1.2 識别設計思想

  關于識别的思路,輪詢法與中斷法也是一緻的,詳見 《序列槽(UART)自動波特率識别程式設計與實作(中斷)》 1.2 小節,但是輪詢法裡多了手動檢測 RXD 引腳電平下降沿跳變的過程。

  引腳電平跳變檢測其實也很簡單,就是不斷讀取引腳輸入電平值,并比較相鄰兩次輸入電平值,如果發現不一緻,則是跳變發生之時。如果前一次電平值是高,那麼此時便是下降沿。

痞子衡嵌入式:嵌入式裡序列槽(UART)自動波特率識别程式設計與實作(輪詢)

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首頁、知乎首頁、微信公衆号 平台上。

微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。

痞子衡嵌入式:嵌入式裡序列槽(UART)自動波特率識别程式設計與實作(輪詢)

  最後歡迎關注痞子衡個人微信公衆号【痞子衡嵌入式】,一個專注嵌入式技術的公衆号,跟着痞子衡一起玩轉嵌入式。

痞子衡嵌入式:嵌入式裡序列槽(UART)自動波特率識别程式設計與實作(輪詢)
痞子衡嵌入式:嵌入式裡序列槽(UART)自動波特率識别程式設計與實作(輪詢)
痞子衡嵌入式:嵌入式裡序列槽(UART)自動波特率識别程式設計與實作(輪詢)

  衡傑(痞子衡),目前就職于恩智浦MCU系統部門,擔任嵌入式系統應用工程師。

  專欄内所有文章的轉載請注明出處:http://www.cnblogs.com/henjay724/

  與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]

  可以關注痞子衡的Github首頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。

  關于專欄文章有任何疑問請直接在部落格下面留言,痞子衡會及時回複免費(劃重點)答疑。

  痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。