新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32 UART DMA實現未知數據長度接收

        STM32 UART DMA實現未知數據長度接收

        作者: 時間:2016-11-19 來源:網絡 收藏
        串口通信是經常使用到的功能,在STM32UART具有DMA功能,并且收發都可以使用DMA,使用DMA發送基本上大家不會遇到什么問題,因為發送的時候會告知DMA發送的數據長度,DMA按照發送的長度直接發送就OK了,但是使用DMA接收時候就不同了,因為有時候數據接收并不是每一次都是定長的,但是DMA只在接收數據長度和設定數據長度相同的時候才可以觸發中斷,告訴MCU數據接收完畢,針對這個問題,解決方法如下,有一點復雜,但是很管用。

        UART在傳輸一個字節的時候,首先拉低,傳輸起始位,然后在是LSB –MSB,最后是停止位,停止位是高電平

        本文引用地址:http://www.104case.com/article/201611/318276.htm

        超時時間
        搞過串口通信的都知道,如果串口有協議,一般都是有個超時時間的,超時時間是定義兩個幀之間的間隔的,如果串口接收到一個字節后,在規定的超時時間內沒有接收到其他數據,我們則認為前面接收的數據位一幀。

        定時器復位復位模式
        STM32定時器功能比較強大,其中有一種模式為復位模式,TI1的輸入上升沿會復位定時器的計數器

        整體的思路是這樣的,一開始設置好DMA接收,可以把緩沖區長度設置為幀最大長度,我們可以把RX連接到定時器的管腳輸入端,并且一開始設置輸入并且使能引腳下降沿中斷,當幀的第一個字節發送時,因為起始位為低電平,空閑時UART為高電平,滿足條件,進入中斷,禁止中斷,并且在中斷中開啟定時器,該定時器工作在復位模式,上升沿復位,并且設置好定時器輸出比較值為超時時間,比如20ms,這樣,在傳輸后面字節時,肯定會有高低電平出現,即便是傳輸的是0x00,0xFF,雖然UART數據區不變,但是都為1,或都為0,但是因為起始位為低電平,停止位是高電平,所以肯定會有上升沿,定時器會一直復位,輸出定時器的計數器一直到達不了輸出比較值,當一幀傳輸結束后,定時在最后一個字節復位后,由于沒有數據繼續到達,無法復位,則計數器就能計到輸出比較值,這時發出中斷,在定時器中斷中可以計算出接收數據的長度,并且通知外部數據已經接收完畢。

        功能實現
        實現的步驟:
        1、硬件連接:UART的RX線在連接外部的同時,還需要連接到一個定時器的輸入端TIMx_CHx,定時器可以為任意定時器,但是CHx,只能為CH1或CH2

        軟件設置
        a) IO、中斷設置:在把UART功能口設置好后,還需要設置TIM4_CH2為輸入上拉,并且使能該引腳外部中斷

        把DMA接收的數據緩沖區設置為你認為最大的幀長度,(如果最長不能確定,也可以隨便指定一個長度,后面再講怎么實現)。
        b) 定時器設置
        因為使用的是TIM4_CH2,所以需要配置TIM4,并且配置為復位模式,把超時時間定為20ms,為了方便TIM4時鐘定輸入為1KHZ

        工作過程如下
        在串口傳輸起始位的時候,首先產生外部中斷,在外部中斷中開啟定時器,禁止外部中斷,只要串口上一直有數據,定時器肯定會不停的復位,到達不了定時時間,當串口上沒有數據的時候,到超時時間后,定時器產生中斷,此時可以讀出接收的數據長度,然后開啟外部中斷,進入下一個周期。

        總結:本方法的缺點是程序開始的初始化麻煩些,但是優點是非常明顯的,徹底解放了CPU,這樣在計算串口超時的時候,就不需要定時器不停的中斷,并且串口接收數據使用DMA方式,也不需要CPU參與,只是在接收結束的時候通知CPU取數據,CPU的利用率會更高。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 天柱县| 中超| 青冈县| 定州市| 文登市| 松阳县| 徐水县| 遂溪县| 西乡县| 原平市| 黑水县| 乌苏市| 安庆市| 钟祥市| 吴堡县| 奎屯市| 龙口市| 化州市| 滨州市| 安岳县| 双牌县| 桑日县| 鲁山县| 萍乡市| 徐水县| 台中县| 拉萨市| 文昌市| 辽源市| 南和县| 麟游县| 将乐县| 镇沅| 双峰县| 平谷区| 万安县| 麟游县| 巴彦淖尔市| 沾益县| 阜城县| 铁力市|