1. 程式人生 > >STM32的UART DMA傳輸總結

STM32的UART DMA傳輸總結

使用DMA傳輸可以連續獲取或傳送一段資訊而不佔用中斷或延時,在通訊頻繁或有大段資訊要傳輸時非常有用。

這裡寫圖片描述
由上表可知,要使用USART1TX/RX我們選擇通道4和5

1、 DMA傳輸方式:
(1) DMA_Mode_Normal,當通道配置為非迴圈模式時,傳輸結束後(即傳輸計數變為0)將不再產生DMA操作。要開始新的DMA傳輸,需要3個步驟:在關閉DMA通道的情況下,在DMA_CNDTRx暫存器中重新寫入傳輸數目,然後重新開啟DMA。

void DMA1_Channel5_IRQHandler(void)
{//由於不同的中斷源擁有同一個中斷向量入口,所以需要判斷中斷標誌
    if(DMA_GetFlagStatus(DMA1_FLAG_TC5)
==SET)
{ DMA_Cmd (DMA1_Channel5,DISABLE);//關閉DMA通道 DMA_ClearFlag(DMA1_FLAG_TC5);//清中斷標誌,否則會一直中斷 DMA_SetCurrDataCounter(DMA1_Channel5,UART_DMA_BUFFSIZE);//重置傳輸數目,當再次達到這個數目就會進中斷 DMA_Cmd (DMA1_Channel5,ENABLE);//開啟DMA通道 } }

(2) DMA_Mode_Circular,在迴圈模式下,最後一次傳輸結束時, DMA_CNDTRx暫存器的內容會自動地被重新載入為其初始數值,內部的當前外設/儲存器地址暫存器也被重新載入為DMA_CPARx/DMA_CMARx暫存器設定的初始基地址。
2、

將外設與DMA連線起來
將串列埠1的傳送設定成DMA模式:

USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

3、資料的傳送
使用非迴圈模式,跟上文的1.(1)中重新開啟DMA的3個步驟一樣,將UART_TX_Buff中的資料準備好,然後開啟DMA,即可自動傳送UART_TX_Buff中的資料,資料傳輸完成,進入中斷DMA1_Channel4_IRQHandler

4、資料的接收
使用DMA中斷來接收資料,只能接收固定幀長的資料,USART接收夠一定長度的資料,就會進入DMA中斷。
若要接收可變長度的資料,方法有以下3種:
  1.將RX腳與一路時鐘外部引腳相連,當串列埠一幀發完,即可利用此定時器產生超時中斷.這個實時性較高,可以做到1個位元組實時監測.
  2.不改變硬體,開啟一個定時器監控DMA接收,如果超時則產生中斷.這個實時性不高,因為超時時間必須要大於需要接收幀的時間,精度不好控制.
  3.STM32微控制器有的串列埠可以監測匯流排是否處於空閒,如果空閒則產生中斷.可以用它來監測DMA接收是否完畢.這種方式實時性很高。當USART在停止位後的一個byte的時間內,匯流排是空閒的,就置位匯流排空閒標誌,這時我們認為一幀的資料傳輸完成,就會進入USART中斷處理。
  但這裡需要注意一個問題就是,如果兩幀的資料緊挨著一起被接收,那麼這種情況應該使用DMA中斷。因為使用USART空閒中斷的話,要兩幀全部發完才能進入中斷,這樣只能處理一幀的資料;使用DMA中斷的話,在第一幀結束就可以進入中斷,即使第二幀緊跟著後面。