stm32 利用DMA 串列埠空閒中斷接受任意長資料

2021-08-29 01:33:11 字數 3523 閱讀 1041

二、串列埠空閒中斷

三、糾正

在進行stm32開發時,有時會遇到這種情況:需要在裝置間進行資料傳輸,由於stm32串列埠rdr和tdr暫存器都是8位有效的,我們往往需要定義傳輸協議(如一幀資料中,包含包含幀頭、幀id、資料幀、校驗幀等若干8位資料)。我們希望可以一次收到一幀資料,並進行解碼操作。利dma+串列埠空閒中斷可以有效完成上述任務。

dma用在只需要傳輸資料,不需要處理資料的地方,有三種傳輸方式:

在中文參考手冊9.2節詳細說明了dma特性

通常如下圖配置:

方向指標情況

外設 → 儲存器

外設指標不變,儲存buf指標遞增

儲存器 → 外設

儲存buf指標不變, 外設指標遞增

儲存器 → 儲存器

都遞增關於dma還有雙緩衝區模式、突發傳輸等等其他設定,一般用不到,具體查詢《stm32中文參考手冊》

//dma_streamx:dma資料流,dma1_stream0~7/dma2_stream0~7

//chx:dma通道選擇,@ref dma_channel dma_channel_0~dma_channel_7

//par:外設位址

//mar:儲存器位址

//ndtr:資料傳輸量

void dma_config(dma_stream_typedef *dma_streamx,uint32_t chx,uint32_t par,uint32_t mar,uint32_t dir,u16 ndtr)

else

dma_deinit(dma_streamx);

while (dma_getcmdstatus(dma_streamx) != disable){}//等待dma可配置

/* 配置 dma stream */

dma_initstructure.dma_channel = chx; //通道選擇

dma_initstructure.dma_peripheralbaseaddr = par; //dma外設位址

dma_initstructure.dma_memory0baseaddr = mar; //dma 儲存器0位址

dma_initstructure.dma_dir = dir; //direction of transmit.

dma_initstructure.dma_buffersize = ndtr; //資料傳輸量

dma_initstructure.dma_peripheralinc = dma_peripheralinc_disable; //外設非增量模式

dma_initstructure.dma_memoryinc = dma_memoryinc_enable; //儲存器增量模式

dma_initstructure.dma_peripheraldatasize = dma_peripheraldatasize_byte; //外設資料長度:8位

dma_initstructure.dma_memorydatasize = dma_memorydatasize_byte; //儲存器資料長度:8位

dma_initstructure.dma_mode = dma_mode_normal; // 使用普通模式

dma_initstructure.dma_priority = dma_priority_high; //中等優先順序

dma_initstructure.dma_fifomode = dma_fifomode_disable;

dma_initstructure.dma_fifothreshold = dma_fifothreshold_full;

dma_initstructure.dma_memoryburst = dma_memoryburst_single; //儲存器突發單次傳輸

dma_initstructure.dma_peripheralburst = dma_peripheralburst_single; //外設突發單次傳輸

dma_init(dma_streamx, &dma_initstructure);

dma_cmd(dma_streamx,enable);

} //開啟一次dma傳輸

void dma_enable(dma_stream_typedef *dma_streamx,u16 ndtr)

//等待傳輸結束

dma_setcurrdatacounter(dma_streamx,ndtr); //設定傳輸資料長度

dma_cmd(dma_streamx, enable); //開啟dma

}

先看一下串列埠中斷表

示例**如下

void my_usart1_init(void)

void usart1_irqhandler(void)

}

利用串列埠空閒中斷,可以用如下流程實現dma控制的任意長資料接收:

示例**如下:

void usart1_init(uint32_t bound)//dma2_stream2

void usart1_irqhandler(void)

{ uint8_t rc_tmp;

uint16_t rc_len;

uint16_t i;

if(usart_getitstatus(usart1,usart_it_idle)!=reset)

{ rc_tmp=usart1->sr;

rc_tmp=usart1->dr;//軟體序列清除idle標誌位

dma_cmd(dma2_stream2, disable);關閉dma,準備重新配置

dma_clearitpendingbit(dma2_stream2, dma_it_tcif2); // clear transfer complete flag

dma_clearitpendingbit(dma2_stream2, dma_it_teif2); // clear transfer error flag

rc_len = usart1_rx_buffer_size - dma_getcurrdatacounter(dma2_stream2);//計算接收資料長度

for(i=0;i上述**經stm32f407平台測試通過

STM32 匯流排空閒 DMA 方式接收

stm32 的 usart 支援乙個匯流排空閒中斷,如果這個中斷和dma配合,能夠較好的實現接收不定長資料的功能。匯流排空閒中斷是在檢測到在接收資料後,資料匯流排上乙個位元組的時間內,沒有再接到資料後發生。也就是rxne位被置位之後,才開始檢測,只被置位一次,除非再次檢測到rxne位被置位,然後才開...

STM32 串列埠DMA(一)

今天調usart,資料在晶元內部用dma傳到串列埠快取,發現dma真的很好,很快,而且不消耗系統資源。只是在傳輸完的時候中斷的標誌置位。下面解釋一下程式。void dma configuration void 再弄幾個重要的語句。這裡是開始dma傳輸前的一些準備工作,將usart1模組設定成dma方...

STM32串列埠 DMA使用1

stm32串列埠 dma使用 stm32有5個串列埠資源 usart1,usart2,usart3及uart4,uart5 其中3個usart 通用同步 非同步收 髮器universalsynchronous asynchronous receiver and transmitter 2個uart ...