HAL库STM32串口开启DMA接收数据
STM32CubeMx的配置
此博客仅仅作为记录,这个像是有bug一样,有时候好使,有时候不好,所以趁现在好使赶紧记录一下,很多地方用到串口接收数据,DMA又是一种非常好的接收方式,可以节约CPU的时间,提高利用率,首先是在CubeMX的配置,这个很简单,首先配置成异步收发。这样配置可以接收不固定长度的字符
然后配置DMA接收和发送:
Keil的配置
其余配置都一样,在编译工程里面也需要配置一些东西(Keil工程)
首先就是必须勾选,要不然打印不了数据,使用DMA发送数据的时候,可能printf函数就不好使了,这个需要注意:
代码配置
接下来就是添加代码
先在usart.c文件定义几个变量
uint8_t Rx_Flag = 0;
uint16_t Rx_Len = 0;
uint8_t Rx_Buf[Rx_Max] = {0};
在usart.h文件里面声名一下,防止其他地方调用会报错
#define Rx_Max 1024
extern uint8_t Rx_Flag; //接收数据标志位
extern uint16_t Rx_Len; //DMA接收数据的长度
extern uint8_t Rx_Buf[Rx_Max];
先在main函数里面开启DMA接收和开启空闲中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //开启空闲中断,当时没有数据的时候中断
HAL_UART_Receive_DMA(&huart1, Rx_Buf, Rx_Max);//开启DMA接收
最后需要在串口中断函数stm32f1xx_it.c操作一些东西,首先在此函数中引用usart.h文件,否则会报错
uint32_t temp;
if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))
{
/*清除状态寄存器和串口数据寄存器*/
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
/*失能DMA接收*/
HAL_UART_DMAStop(&huart1);
/*读取接收长度,总大小-剩余大小*/
temp = huart1.hdmarx->Instance->CNDTR;
Rx_Len = Rx_Max - temp;
/*接收标志位置1*/
Rx_Flag=1;
/*使能接收DMA接收*/
HAL_UART_Receive_DMA(&huart1,Rx_Buf,Rx_Max);
}
在while(1)中的代码操作,就是判断标志位,然后把接收到的数据打印出来
if(Rx_Flag == 1)
{
Rx_Flag = 0;
HAL_UART_Transmit_DMA(&huart1,Rx_Buf,Rx_Len);
}