昨天晚上在STM32串口DMA的問題上糾結了好長時間,所以今天上午寫篇博客來談談我對串口DMA發(fā)送的理解。
討論三個問題:1、什么叫串口DMA 請求;
2、串口簡要復習;
3、串口DMA發(fā)送流程。
1、什么叫串口DMA 請求(戰(zhàn)艦STM32開發(fā)板)
說這個問題之前先簡單回顧DMA的基本特性。先導出原子哥的PPT內(nèi)容:
DMA 全稱Direct Memory Access,即直接存儲器訪問。
DMA傳輸將數(shù)據(jù)從一個地址空間復制到另一個地址空間。當CPU初始化這個傳輸動作,傳輸動作本身是由DMA控制器來實現(xiàn)和完成的。
STM32有兩個DMA控制器(DMA2只存在于大容量產(chǎn)品中),DMA1有7個通道,DMA2有5個通道,每個通道專門用來管理來自于一個或者多個外設對存儲器的訪問請求。還有一個仲裁器來協(xié)調(diào)各個DMA請求的優(yōu)先權。
作用:為CPU減負!
下面上圖
DMA各通道
從外設(TIMx、ADCx、SPIx、I2Cx、和USARTx)產(chǎn)生的DMA請求,通過邏輯或輸入到DMA控制器,這就意味著同時只能有一個請求有效(在同一時間,就只能使用其中的一個,其他通道也類似)。外設的DMA請求,可以通過設置相應的外設寄存器中的控制位,被獨立的開啟或關閉。
看到這里串口DMA請求的定義就出來了:先舉個例子:譬如我想用串口發(fā)送數(shù)據(jù)到PC機,一般做法是CPU通過APB1/APB2總線往串口寫數(shù)據(jù),然后串口發(fā)送;或者是CPU通過總線從串口取(讀)數(shù)據(jù);如果此時CPU處理的任務非常多,這就會耗費CPU的處理時間。
而我們?nèi)绻肈MA來傳送數(shù)據(jù)那就很快了,DMA會通過自己的特定通道將數(shù)據(jù)從一個地址空間復制到另一個地址空間,而且不需要CPU的干預。所以串口DMA請求的定義是:串口要發(fā)送/接收數(shù)據(jù)會請求DMA來完成數(shù)據(jù)的寫和讀。(注意這句話只針對本文?。?/span>
2、串口簡要復習(庫函數(shù))
這里給大家分享個帖子關于printf重定向和半主機模式的理解:
http://www.openedv.com/forum.php?mod=viewthread&tid=44609&highlight=printf
這里簡要復習一下戰(zhàn)艦STM32串口的知識點。舉個例子:我想用PC機往STM32串口發(fā)送個數(shù)據(jù),然后STM32接收到后將數(shù)據(jù)原樣返回給PC機(顯示在串口調(diào)試助手中)。思路:
首先我們會在串口初始化函數(shù)中配置串口接收中斷,當你PC機往串口發(fā)送數(shù)據(jù)時,串口會產(chǎn)生接收中斷;并在中斷服務函數(shù)中,判斷接沒接收完,如果接收完畢就會把接收狀態(tài)寄存器的接收完成標志位置1。到這兒是接收中斷的作用。。
然后在主函數(shù)中,我們不斷檢測接收狀態(tài)寄存器的接收完成標志,看接沒接收完。如果接收完了,就通過for循環(huán)將接收到的數(shù)據(jù),全部發(fā)給串口的USART_DR寄存器(當向該寄存器寫數(shù)據(jù)時,串口就會自動發(fā)送)。于是我們通過PC機發(fā)給串口的數(shù)據(jù)就會被STM32通過串口發(fā)回來了,顯示在串口調(diào)試助手中。
3、串口DMA發(fā)送流程(庫函數(shù))
戰(zhàn)艦實驗:通過按鍵KEY0來控制DMA發(fā)送,每按一次KEY0,DMA就傳送一次數(shù)據(jù)到USART1,然后在TFTLCD模塊上顯示進度信息。這個現(xiàn)在理解就不難了吧。
從主函數(shù)入手,首先我們在STM32的SRAM中開辟一段5200(這個數(shù)字越大DMA傳輸越慢,反之越快)字節(jié)的空間SendBuff[],作為我們的存儲器(內(nèi)存),存儲要往外設(USART1)發(fā)送的數(shù)據(jù)。
然后我們在SendBuff[]中寫滿TEXT_TO_SEND[]里的內(nèi)容。這里戰(zhàn)艦往SendBuff[]里寫的算法非常巧妙,應該學習;
現(xiàn)在SendBuff[]中已經(jīng)存滿了要發(fā)送給串口的數(shù)據(jù)。這時我們還要檢測KEY0有沒有按下,如果按下了,就通過兩個函數(shù):1、使能串口發(fā)送(在STM32庫函數(shù)stm32f10x_usart.c中,配置USART_CR3中的DMA使能位DMAT);2、使能DMA1通道4,啟動傳輸(在dam.c中,最后也是調(diào)用了stm32f10x_dma.c中的DMA_Cmd();函數(shù)來使能通道)。加上之前(本文沒有)對DMA參數(shù)的初始化(初始化存儲器和外設基地址等),就可以啟動一次傳輸了。
傳輸時間問題:傳輸時間跟波特率密切相關。比如波特率是9600,意思就是每秒鐘發(fā)送或接受的速率為9600bit/s,8bit=1Byte(字節(jié)),故當波特率為9600時,串口的傳輸速率為1200字節(jié)每秒。上文我們申請的存儲器(內(nèi)存)空間是5200字節(jié),故串口要傳輸完這個大小的空間內(nèi)容內(nèi)容,預計需要5200/1200約4秒多。。。
-
stm32串口
+關注
關注
0文章
6瀏覽量
2016
原文標題:容易被大多數(shù)人忽視的STM32串口DMA問題
文章出處:【微信號:Mouser-Community,微信公眾號:貿(mào)澤電子設計圈】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論