1、简介
STM32F302的内核为Cortex-M4
直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。
2、准备
2.1、软件
1、HAL 库版本:STM32Cube FW_F3 V1.11.2
2.2、开发工具
1、STM32CubeMX 6.2.0
2、Keil uVision5 V5.34.0.0
2.3、代码测试时间
2021年7月24日
2.4、参考文档
STM32F302参考手册:RM0365
STM32F3 HAL库用户手册:UM1786
3、CubeMX 工程配置
3.1、配置基本参数
3.2、DMA 通道配置
3.3、中断配置
3.4、中断优先级配置
3.5、注意事项
若出现串口打印的数据乱码情况,1、查看波特率。2、查看时钟配置
4、代码配置
4.1、配置 UART 初始化代码
在 usart.c 文件中的 MX_USART1_UART_Init 函数添加中断的使能
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
4.2、添加串口通信的个人配置文件
在工程中添加App 文件夹,在文件夹中添加 UartComm.c、UartComm.h 文件,并配置。
UartComm.c
#include "UartComm.h"
uint8_t Rx_Flag = 0;
uint16_t Rx_Len;
uint8_t Rx_Buf1[Rx_Max];
uint8_t Rx_Buf2[Rx_Max];
UartComm.h
#ifndef _UartComm_H_
#define _UartComm_H_
#include "main.h"
/********************************************************
*下列定义在 stm32f3xx_it.c 和 main.c 文件夹中调用
*在串口的全局中断 void USART1_IRQHandler(void) 中使用
*
*
********************************************************/
#define Rx_Max 200
extern uint8_t Rx_Flag;
extern uint16_t Rx_Len;
extern uint8_t Rx_Buf1[Rx_Max];
extern uint8_t Rx_Buf2[Rx_Max];
#endif
4.3、配置中断处理代码
以下代码中注释处判断状态标志位的效果相同,可选其一
uint32_t Len;
// if(__HAL_UART_GET_IT(&huart1,UART_IT_IDLE) != RESET)
// {
// __HAL_UART_CLEAR_IT(&huart1,UART_CLEAR_IDLEF);
if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))
{
/*清除状态寄存器和串口数据寄存器*/
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_2);
HAL_UART_DMAStop(&huart1); //不停止DMA的接收,数据会在接收缓存区1叠加
Len = huart1.hdmarx->Instance->CNDTR;
Rx_Len = Rx_Max - Len;
Rx_Flag = 1;
HAL_UART_Receive_DMA(&huart1,Rx_Buf1,Rx_Max);
HAL_UART_Transmit_DMA(&huart1,Rx_Buf1,strlen((char *)Rx_Buf1));
}
4.4、配置主函数
对主函数进行配置,测试串口的 DMA 通信。
if(1 == Rx_Flag)
{
Rx_Flag = 0;
Rx_BufLen = Rx_Len;
for(unsigned int i=0;i<Rx_BufLen;i++)
{
Rx_Buf2[i] = Rx_Buf1[i];
}
for(unsigned int j=0;j<(strlen((char *)Rx_Buf2));j++)
{
HAL_Delay(100);
printf("串口DMA测试%x\r\n",Rx_Buf2[j]);
}
memset((char *)Rx_Buf2,0,(strlen((char *)Rx_Buf2)));//清除接收的数据缓存
}