STM32f103的數電采集電路的DMA設計和使用優化程序
阿新 • • 發佈:2017-06-19
mod time alt art 輸出 次數 中文 技術分享 技術
DMA,全稱為:Direct Memory Access,即直接存儲器訪問。DMA傳輸方式無需CPU直接控制傳輸,也沒有中斷處理方式那樣保留現場和恢復現場的過程,通過硬件為RAM與I/O設備開辟一條直接傳送數據的通路,能使CPU的效率大為提高。
DMA設置的一般步驟可以總結為如下幾個步驟:
1.DMA時鐘使能
2.DMA設置復位
3.設置DMA基地址,內存地址,輸出方向參數
4.設置DMA數據大小,優先級,使用通道參數
5.DMA工作方式初始化
6.使能DMA
7.編寫中斷處理函數
前端采集模塊的DMA使用主要用於ADC采集結果的傳輸和USART串口的數據發送傳輸。根據《stm32中文參考手冊》的DMA請求一覽表,選用了DMA1的通道1作為ADC1的數據傳輸通道,以及DMA1通道4作為和USART串口的數據發送傳輸通道。此處采用了單個DMA復用多通道的設計,是因為DMA速度足以完成這些任務,而且留下其他DMA資源以便項目以後可以擴展,達到節省資源的目的。
USART使用DMA發送數據配置和使能代碼
[cpp] view plain copy
- //DMA1的各通道配置
- //這裏的傳輸形式是固定的,這點要根據不同的情況來修改
- //從存儲器->外設模式/8位數據寬度/存儲器增量模式
- //DMA_CHx:DMA通道CHx
- //cpar:外設地址
- //cmar:存儲器地址
- //cndtr:數據傳輸量
- void DMA_USART_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
- {
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA傳輸
- DMA_DeInit(DMA_CHx); //將DMA的通道1寄存器重設為缺省值
- DMA1_MEM_LEN=cndtr;
- DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外設ADC基地址
- DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA內存基地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //數據傳輸方向,從內存讀取發送到外設
- DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA緩存的大小
- 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_Medium; //DMA通道 x擁有中優先級
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x沒有設置為內存到內存傳輸
- DMA_Init(DMA_CHx, &DMA_InitStructure); //根據DMA_InitStruct中指定的參數初始化DMA的通道USART1_Tx_DMA_Channel所標識的寄存器
- }
- //開啟一次DMA傳輸
- void DMA_USART_Enable(DMA_Channel_TypeDef*DMA_CHx)
- {
- DMA_Cmd(DMA_CHx, DISABLE ); //關閉USART1 TX DMA1 所指示的通道
- DMA_SetCurrDataCounter(DMA_CHx, DMA1_MEM_LEN);//DMA通道的DMA緩存的大小
- DMA_Cmd(DMA_CHx, ENABLE); //使能USART1 TX DMA1 所指示的通道
- }
ADC使用DMA傳送多通道數據配置和使能代碼
[cpp] view plain copy
- //DMA1的各通道配置
- //這裏的傳輸形式是固定的,這點要根據不同的情況來修改
- //從存儲器->外設模式/8位數據寬度/存儲器增量模式
- //DMA_CHx:DMA通道CHx
- //cpar:外設地址
- //cmar:存儲器地址
- //cndtr:數據傳輸量
- void DMA_ADC_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
- {
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA傳輸
- DMA_DeInit(DMA_CHx); //將DMA的通道1寄存器重設為缺省值
- DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外設ADC基地址
- DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA內存基地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //內存作為數據傳輸的目的地
- DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA緩存的大小
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設地址寄存器不變
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存地址寄存器遞增
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //數據寬度為16位
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //數據寬度為16位
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循環緩存模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x擁有高優先級
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x沒有設置為內存到內存傳輸
- DMA_Init(DMA_CHx, &DMA_InitStructure); //根據DMA_InitStruct中指定的參數初始化DMA的通道
- }
- //開啟一次DMA傳輸
- void DMA_ADC_Enable(DMA_Channel_TypeDef*DMA_CHx)
- {
- DMA_Cmd(DMA_CHx, DISABLE ); //關閉USART1 TX DMA1 所指示的通道
- DMA_Cmd(DMA_CHx, ENABLE); //使能USART1 TX DMA1 所指示的通道
- }
這裏需要註意的是USART使用DMA發送數據需要每一次都重新使能,即每發送一次數據使能一下。
而ADC使用DMA傳送多通道數據則只需要使能一次就可以自動循環工作,只需從數組空間讀取ADC數據。
STM32f103的數電采集電路的DMA設計和使用優化程序