高質(zhì)量程序是怎么寫出來的?串口DMA機制
[導(dǎo)讀]來源:嵌入式大雜燴今天說一下串口DMA。直接存儲器訪問(DirectMemoryAccess),簡稱DMA。DMA是CPU一個用于數(shù)據(jù)從一個地址空間到另一地址空間“搬運”(拷貝)的組件,數(shù)據(jù)拷貝過程不需CPU干預(yù),數(shù)據(jù)拷貝結(jié)束則通知CPU處理。因此,大量數(shù)據(jù)拷貝時,使用DMA可以...
今天說一下串口DMA。直接存儲器訪問(Direct Memory Access),簡稱DMA。DMA是CPU一個用于數(shù)據(jù)從一個地址空間到另一地址空間“搬運”(拷貝)的組件,數(shù)據(jù)拷貝過程不需CPU干預(yù),數(shù)據(jù)拷貝結(jié)束則通知CPU處理。因此,大量數(shù)據(jù)拷貝時,使用DMA可以釋放CPU資源。DMA數(shù)據(jù)拷貝過程,典型的有:
- 內(nèi)存—>內(nèi)存,內(nèi)存間拷貝
- 外設(shè)—>內(nèi)存,如uart、spi、i2c等總線接收數(shù)據(jù)過程
- 內(nèi)存—>外設(shè),如uart、spi、i2c等總線發(fā)送數(shù)據(jù)過程
1、 串口有必要使用DMA嗎?
串口(uart)是一種低速的串行異步通信,適用于低速通信場景,通常使用的波特率小于或等于115200bps
。對于小于或者等于115200bps
波特率的,而且數(shù)據(jù)量不大的通信場景,一般沒必要使用DMA,或者說使用DMA并未能充分發(fā)揮出DMA的作用。對于數(shù)量大,或者波特率提高時,必須使用DMA以釋放CPU資源,因為高波特率可能帶來這樣的問題:對于發(fā)送,使用循環(huán)發(fā)送,可能阻塞線程,需要消耗大量CPU資源“搬運”數(shù)據(jù),浪費CPU對于發(fā)送,使用中斷發(fā)送,不會阻塞線程,但需浪費大量中斷資源,CPU頻繁響應(yīng)中斷;以115200bps波特率,1s傳輸11520字節(jié),大約69us需響應(yīng)一次中斷,如波特率再提高,將消耗更多CPU資源對于接收,如仍采用傳統(tǒng)的中斷模式接收,同樣會因為頻繁中斷導(dǎo)致消耗大量CPU資源因此,高波特率場景下,串口非常有必要使用DMA。2、實現(xiàn)方式
3、STM32串口使用DMA
關(guān)于STM32串口使用DMA,不乏一些開發(fā)板例程及網(wǎng)絡(luò)上一些博主的使用教程。使用步驟、流程、配置基本大同小異,正確性也沒什么毛病,但都是一些基本的Demo例子,作為學(xué)習(xí)過程沒問題;實際項目使用缺乏嚴謹性,數(shù)據(jù)量大時可能導(dǎo)致數(shù)據(jù)異常。測試平臺:- STM32F030C8T6
- UART1/UART2
- DMA1 Channel2—Channel5
- ST標準庫
- 主頻48MHz(外部12MHz晶振)
4、串口DMA接收
4.1 基本流程
4.2 相關(guān)配置
關(guān)鍵步驟- 初始化串口
- 使能串口DMA接收模式,使能串口空閑中斷
- 配置DMA參數(shù),使能DMA通道buf半滿(傳輸一半數(shù)據(jù))中斷、buf溢滿(傳輸數(shù)據(jù)完成)中斷
- 串口接收,DMA通道工作模式設(shè)為連續(xù)模式
- 使能DMA通道接收buf半滿中斷、溢滿(傳輸完成)中斷
- 啟動DMA通道前清空相關(guān)狀態(tài)標識,防止首次傳輸錯亂數(shù)據(jù)
void?bsp_uart2_dmarx_config(uint8_t?*mem_addr,?uint32_t?mem_size)
{
???DMA_InitTypeDef?DMA_InitStructure;
?
?DMA_DeInit(DMA1_Channel5);?
?DMA_Cmd(DMA1_Channel5,?DISABLE);
?DMA_InitStructure.DMA_PeripheralBaseAddr??=?(uint32_t)