STM32 DMA學習筆記
1. 實驗環境:
開發板:野火指南者(STM32F103VE)
STM32庫版本:STM32F10x_StdPeriph_Lib_V3.5.0
IDE:KEIL5(代碼編寫很不方便,只在編譯的時候用到)
代碼編寫工具:Source Insight 4.0(跟讀代碼、編寫代碼的最佳工具)
使用到的串口:USART1
傳送方向:內存--->外設
硬件原理圖:
實驗效果:
2. 新建user_usart.h、user_usart.c、user_dma.h、user_dma.c、main.c 5個文件,並從STM32官方庫的例子中將stm32f10x_it.c、stm32f10x_it.h、stm32f10x_conf.h拷貝到自己的工程目錄下。
3. 在user_usart.h中添加如下代碼
1 #ifndef __USER_USART_H 2 #define __USER_USART_H 3 #include "stm32f10x.h" 4 5 void User_USART_GPIO_Config(void); 6 void User_USART_Config(void); 7 8 9 #endifuser_usart.h
4. 在user_usart.c中添加如下代碼
1 #include "user_usart.h" 2 3 4 5 voiduser_usart.cUser_USART_Config(void) 6 { 7 USART_InitTypeDef USART_Config; 8 9 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 10 11 USART_Config.USART_BaudRate = 115200; 12 USART_Config.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 13 USART_Config.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;14 USART_Config.USART_Parity = USART_Parity_No; 15 USART_Config.USART_StopBits = USART_StopBits_1; 16 USART_Config.USART_WordLength = USART_WordLength_8b; 17 18 USART_Init(USART1, &USART_Config); 19 20 USART_Cmd(USART1, ENABLE); 21 22 23 } 24 25 26 void User_USART_GPIO_Config(void) 27 { 28 GPIO_InitTypeDef USART_GPIO_TX,USART_GPIO_RX; 29 30 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 31 32 USART_GPIO_TX.GPIO_Mode = GPIO_Mode_AF_PP; 33 USART_GPIO_TX.GPIO_Pin = GPIO_Pin_9; 34 USART_GPIO_TX.GPIO_Speed = GPIO_Speed_50MHz; 35 36 GPIO_Init(GPIOA, &USART_GPIO_TX); 37 38 USART_GPIO_RX.GPIO_Mode = GPIO_Mode_IN_FLOATING; 39 USART_GPIO_RX.GPIO_Pin = GPIO_Pin_10; 40 41 GPIO_Init(GPIOA, &USART_GPIO_RX); 42 43 44 45 46 }
5. 在user_dma.h中添加如下代碼
1 #ifndef __USER_DMA_H 2 #define __USER_DMA_H 3 4 #include "stm32f10x.h" 5 6 7 #define USART_DATA_ADRESS (USART1_BASE + 0x04) 8 9 extern char str[]; 10 11 12 13 void User_DMA_Config(void); 14 15 16 17 #endifuser_dma.h
6. 在user_dma.c中添加如下代碼
1 #include "user_dma.h" 2 3 char str[] = "aahhhhhhhhhh"; 4 5 6 void User_DMA_Config(void) 7 { 8 DMA_InitTypeDef m_DMA; 9 10 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 11 12 m_DMA.DMA_BufferSize = sizeof(str); //此處大小一定要和發送的字符串大小一致,否則多余的部分出現亂碼,因為值是未知的 13 m_DMA.DMA_DIR = DMA_DIR_PeripheralDST; 14 m_DMA.DMA_M2M = DMA_M2M_Disable; 15 m_DMA.DMA_MemoryBaseAddr = (uint32_t)str; 16 m_DMA.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 17 m_DMA.DMA_MemoryInc = DMA_MemoryInc_Enable; 18 m_DMA.DMA_Mode = DMA_Mode_Circular; 19 m_DMA.DMA_PeripheralBaseAddr = USART_DATA_ADRESS; 20 m_DMA.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 21 m_DMA.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 22 m_DMA.DMA_Priority = DMA_Priority_Medium; 23 24 /* 25 串口工具接收來自開發板發送的數據,結合硬件實際物理連接, 26 此處為USART1_TX,即DMA1_Channel 27 */ 28 DMA_Init(DMA1_Channel4, &m_DMA); 29 30 31 //使能實際與之對應的DMA通道, 32 DMA_Cmd(DMA1_Channel4, ENABLE); 33 34 35 }user_dma.c
7. 在main.c中添加如下代碼
1 #include "stm32f10x.h" 2 #include "user_dma.h" 3 #include "user_usart.h" 4 5 extern char str[]; 6 7 8 int main(void) 9 { 10 11 12 User_DMA_Config(); 13 User_USART_GPIO_Config(); 14 User_USART_Config(); 15 16 //使能USART的DMA模式,這裏操作的寄存器是USART的CR3第7bit,此bit置一為打開 17 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); 18 19 20 while(1) 21 { 22 23 } 24 25 26 return 0; 27 }main.c
實現步驟總結:
1、設置USART硬件中實際使用到的GPIO口,這裏為GPIOA的PIN9、PIN10,具體設置如下
1.1、使能GPIO時鐘,使用RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)庫函數
1.2、初始化GPIO_InitTypeDef結構體成員,若為輸入則不需要初始化GPIO_Speed成員
1.3、將GPIO_InitTypeDef結構體的值寫入到對應GPIO寄存器中,使用GPIO_Init(GPIO_TypeDef * GPIOx, GPIO_InitTypeDef * GPIO_InitStruct)庫函數
2、設置USART對應的寄存器
2.1、使能USART時鐘,使用RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)庫函數,若不是USART1則需要使用RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)庫函數,因為USART1掛載在APB2總線上,USART2~USART5掛載在APB1總線上。
2.2、初始化USART_InitTypeDef結構體成員。一般為8N1,即數據長度為8bit、無校驗位、1個停止位
2.3、將USART_InitTypeDef結構體的值寫入到對應的USART寄存器中,使用USART_Init(USART_TypeDef * USARTx, USART_InitTypeDef * USART_InitStruct)庫函數
2.4、打開對應的中斷寄存器來響應中斷,即中斷到來時可進入對應的中斷服務程序,若不需要中斷,則不用設置,跳過此不走。本實驗使用了數據接收中斷,使用USART_ITConfig(USART_TypeDef * USARTx, uint16_t USART_IT, FunctionalState NewState)庫函數設置
2.5、使能串口USART1,使其進行工作,使用USART_Cmd(USART_TypeDef * USARTx, FunctionalState NewState)庫函數
3、定義要傳輸的數據
4、設置DMA對應的寄存器
4.1、使能DMA時鐘,使用RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)庫函數
4.2、初始化DMA_InitTypeDef結構體成員
4.3、將DMA_InitTypeDef結構體的值寫入DMA對應的寄存器中,使用DMA_Init(DMA_Channel_TypeDef * DMAy_Channelx, DMA_InitTypeDef * DMA_InitStruct)庫函數
4.4、使能串口DMA,使其進行工作,使用DMA_Cmd(DMA_Channel_TypeDef * DMAy_Channelx, FunctionalState NewState)庫函數
5. 使能USART的DMA模式,使用USART_DMACmd(USART_TypeDef * USARTx, uint16_t USART_DMAReq, FunctionalState NewState)庫函數
實驗代碼:
鏈接:https://pan.baidu.com/s/19QRoJf6HSdOejX_YIXFc6A
提取碼:3xd0
STM32 DMA學習筆記