1. 程式人生 > >STM32 DMA學習筆記

STM32 DMA學習筆記

rcu nbsp 編寫代碼 style 野火 工具 2.4 lose 亂碼

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 #endif
user_usart.h

4. 在user_usart.c中添加如下代碼

技術分享圖片
 1 #include "user_usart.h"
 2 
 3 
 4 
 5 void
User_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 }
user_usart.c

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 #endif
user_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學習筆記