二、串列埠空閒中斷
三、糾正
在進行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 ...