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 中添加如下代码
- #ifndef __USER_USART_H
- #define __USER_USART_H
- #include "stm32f10x.h"
- void User_USART_GPIO_Config(void);
- void User_USART_Config(void);
- #endif
- user_usart.h
4. 在 user_usart.c 中添加如下代码
- #include "user_usart.h"
- void User_USART_Config(void)
- {
- USART_InitTypeDef USART_Config;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- USART_Config.USART_BaudRate = 115200;
- USART_Config.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_Config.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
- USART_Config.USART_Parity = USART_Parity_No;
- USART_Config.USART_StopBits = USART_StopBits_1;
- USART_Config.USART_WordLength = USART_WordLength_8b;
- USART_Init(USART1, &USART_Config);
- USART_Cmd(USART1, ENABLE);
- }
- void User_USART_GPIO_Config(void)
- {
- GPIO_InitTypeDef USART_GPIO_TX,USART_GPIO_RX;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- USART_GPIO_TX.GPIO_Mode = GPIO_Mode_AF_PP;
- USART_GPIO_TX.GPIO_Pin = GPIO_Pin_9;
- USART_GPIO_TX.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &USART_GPIO_TX);
- USART_GPIO_RX.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- USART_GPIO_RX.GPIO_Pin = GPIO_Pin_10;
- GPIO_Init(GPIOA, &USART_GPIO_RX);
- }
- user_usart.c
5. 在 user_dma.h 中添加如下代码
- #ifndef __USER_DMA_H
- #define __USER_DMA_H
- #include "stm32f10x.h"
- #define USART_DATA_ADRESS (USART1_BASE + 0x04)
- extern char str[];
- void User_DMA_Config(void);
- #endif
- user_dma.h
6. 在 user_dma.c 中添加如下代码
- #include "user_dma.h"
- char str[] = "aahhhhhhhhhh";
- void User_DMA_Config(void)
- {
- DMA_InitTypeDef m_DMA;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
- m_DMA.DMA_BufferSize = sizeof(str); // 此处大小一定要和发送的字符串大小一致, 否则多余的部分出现乱码, 因为值是未知的
- m_DMA.DMA_DIR = DMA_DIR_PeripheralDST;
- m_DMA.DMA_M2M = DMA_M2M_Disable;
- m_DMA.DMA_MemoryBaseAddr = (uint32_t)str;
- m_DMA.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
- m_DMA.DMA_MemoryInc = DMA_MemoryInc_Enable;
- m_DMA.DMA_Mode = DMA_Mode_Circular;
- m_DMA.DMA_PeripheralBaseAddr = USART_DATA_ADRESS;
- m_DMA.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
- m_DMA.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- m_DMA.DMA_Priority = DMA_Priority_Medium;
- /*
- 串口工具接收来自开发板发送的数据, 结合硬件实际物理连接,
- 此处为 USART1_TX, 即 DMA1_Channel
- */
- DMA_Init(DMA1_Channel4, &m_DMA);
- // 使能实际与之对应的 DMA 通道,
- DMA_Cmd(DMA1_Channel4, ENABLE);
- }
- user_dma.c
7. 在 main.c 中添加如下代码
- #include "stm32f10x.h"
- #include "user_dma.h"
- #include "user_usart.h"
- extern char str[];
- int main(void)
- {
- User_DMA_Config();
- User_USART_GPIO_Config();
- User_USART_Config();
- // 使能 USART 的 DMA 模式, 这里操作的寄存器是 USART 的 CR3 第 7bit, 此 bit 置一为打开
- USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
- while(1)
- {
- }
- return 0;
- }
- 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
来源: http://www.bubuko.com/infodetail-2998414.html