STM32F0XX DMA串口收發數據

**前言:**

最近在接手一個安排的時候,需要修改之前的一些代碼的外設接口,然後發現之前有部分關於USART通過DMA收發數據的部分功能,修改移植的時候發現有些需要注意的事項,以及解釋的,做一篇小筆記吧,博主使用的單片機是STM32f071。

USART有三種模式進行傳輸:輪詢、中斷、以及DMA。

輪詢模式

CPU不斷查詢IO設備,如設備有請求則加以處理。例如CPU不斷查詢串口是否傳輸完成,如傳輸超過則返回超時錯誤。輪詢方式會佔用CPU處理時間,效率較低。

中斷控制方式

當I/O操作完成時,輸入輸出設備控制器通過中斷請求線向處理器發出中斷信號,處理器收到中斷信號之後,轉到中斷處理程序,對數據傳送工作進行相應的處理。

直接內存存取技術(DMA)方式

所謂直接傳送,即在內存與IO設備間傳送一個數據塊的過程中,不需要CPU的任何中間干涉,只需要CPU在過程開始時向設備發出“傳送塊數據”的命令,然後通過中斷來得知過程是否結束和下次操作是否準備就緒。

· 如果沒有多操作過,可以用STM32CubeMX進行快速配置哈,這是之前學習CubeMX時候看到教程,很精簡,點擊進入鏈接

串口的基本配置大家可以看哈野火老哥的教程,很紮實很細緻。
首先配置好需要用的usartx:
在這裏插入圖片描述
時鐘配置,開啓gpio、usart、dma時鐘.

在這裏插入圖片描述
IO配置爲需要的模式.**注意:**f0系類的MCU配置複用功能的時候需要配置GPIOx_AFR寄存器,此在數據手冊查詢到PD5 PD6引腳默認複用功能引腳便是USART2,所以此處便可以省略配置,但是其他時候大家配置的時候記得進行查詢在進行配置.
在這裏插入圖片描述
數據手冊查詢位置在這裏插入圖片描述
此處爲stm32f0開發手冊GPIO寄存器配置查詢
在這裏插入圖片描述
usart2外設配置

利用DMA通道發送接收串口時候,收發是分離的。

DMA的發送有幾個步驟.

1.在數據發送緩衝區內放好要發送的數據,說明:此數據緩衝區的首地址必須要在DMA初始化的時候寫入到DMA配置中去。
2. 將數據緩衝區內要發送的數據字節數賦值給發送DMA通道,(串口發送DMA和串口接收DAM不是同一個DMA通道)
3.開啓DMA,一旦開啓,則DMA開始發送數據,說明一下:在KEIL調試好的時候,DMA和調試是不同步的,即不管Keil 是什麼狀態,DMA總是發送數據。
3. 等待發送完成標誌位,即下面的終端服務函數中的第3點設置的標誌位。或者根據自己的實際情況來定,是否要一直等待這個標誌位,也可以通過狀態機的方式來循環查詢也可以。或者其他方式判斷數據發送完成.

DMA的接收步驟

串口接收DMA在初始化的時候就處於開啓狀態,一直等待數據的到來,在軟件上無需做任何事情,只要在初始化配置的時候設置好配置就可以了。
判斷數據數據接收完成:

這裏判斷接收完成是通過串口空閒中斷的方式實現,即當串口數據流停止後,就會產生IDLE中斷。這個中斷裏面做如下幾件事:

1.關閉串口接收DMA通道,2點原因:1>.防止後面又有數據接收到,產生干擾。2>.便於DMA的重新配置賦值,下面第4點。
2. 清除DMA 所有標誌位
3. 從DMA寄存器中獲取接收到的數據字節數
4. 重新設置DMA下次要接收的數據字節數,注意,這裏是給DMA寄存器重新設置接收的計數值,這個數量只能大於或者等於可能接收的字節數,否則當DMA接收計數器遞減到0的時候,又會重載這個計數值,重新循環遞減計數,所以接收緩衝區的數據則會被覆蓋丟失。
5. 開啓DMA通道,等待下一次的數據接收,注意,對DMA的相關寄存器配置寫入,如第4條的寫入計數值,必須要在關閉DMA的條件進行,否則操作無效。

說明一下,STM32的IDLE的中斷在串口無數據接收的情況下,是不會一直產生的,產生的條件是這樣的,當清除IDLE標誌位後,必須有接收到第一個數據後,纔開始觸發,一斷接收的數據斷流,沒有接收到數據,即產生IDLE中斷。

此處文字是摘錄別人的文字,大家可以看哈別人的文章,可以更好的學習一哈.附上鍊接.

雖然其他人寫的很詳細,但是博主用的使用是DMA移植髮送形式,並沒有在DMA通道的專用中斷函數發送.
MCU中DMA有5個通道的,有7個通道的,博主使用的MCU是七個通道的,我們需要從stm32開發手冊進行查詢並配置對應的通道,這個很重要,記得,因爲其他的配置都很常規,在這裏配置的時候需要注意,因爲配置一旦出錯,就很容易出現hardfault.
串口接收DMA在初始化的時候就處於開啓狀態,一直等待數據的到來,在軟件上無需做任何事情,只要在初始化配置的時候設置好配置就可以了。
判斷數據數據接收完成:
這裏判斷接收完成是通過串口空閒中斷的方式實現,即當串口數據流停止後,就會產生IDLE中斷。這個中斷裏面做如下幾件事:

  1. 關閉串口接收DMA通道,2點原因:1.防止後面又有數據接收到,產生干擾。2.便於DMA的重新配置賦值,下面第4點。
  2. 清除DMA 所有標誌位
  3. 從DMA寄存器中獲取接收到的數據字節數
  4. 重新設置DMA下次要接收的數據字節數,注意,這裏是給DMA寄存器重新設置接收的計數值,這個數量只能大於或者等於可能接收的字節數,否則當DMA接收計數器遞減到0的時候,又會重載這個計數值,重新循環遞減計數,所以接收緩衝區的數據則會被覆蓋丟失。
  5. 開啓DMA通道,等待下一次的數據接收,注意,對DMA的相關寄存器配置寫入,如第4條的寫入計數值,必須要在關閉DMA的條件進行,否則操作無效。
    說明一下,STM32的IDLE的中斷在串口無數據接收的情況下,是不會一直產生的,產生的條件是這樣的,當清除IDLE標誌位後,必須有接收到第一個數據後,纔開始觸發,一斷接收的數據斷流,沒有接收到數據,即產生IDLE中斷。

在這裏插入圖片描述
DMA處查詢usart2_通道爲ch4,或者可以通過Remap到ch7進行發送數據.
在這裏插入圖片描述
由於數據發送的時候,尚未發送完成就執行完函數,所以加上發送完成標誌完成判斷,然後再清除掉標誌.
DMA通道配置函數,配置之後就可以使用此函數了.
在這裏插入圖片描述
主函數調用
在這裏插入圖片描述
串口打印顯示

但是Remap請慎用,有些MCU是沒有此項功能的.博主最早之前就是想用Remap,沒有主要此處,所以造成了發送一直顯示只能發送第一個byte.
在這裏插入圖片描述
示範一個錯誤案例:沒有查詢是否可以DMA Remap就直接進行Remap

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述
**結語:**大家寫的時候一定多多注意,希望可以幫到大家,寫的比較匆忙,好多知識點就不寫了,CSDN等等大家都總結的很詳細.

發佈了17 篇原創文章 · 獲贊 16 · 訪問量 2460
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章