参考博客:
https://blog.csdn.net/qq_41830158/article/details/121254705
按下面步骤修改实测可用
步骤:
添加串口接收所需变量
打开uart.c文件,在文件顶部的USER CODE BEGIN 0下方添加下列变量
volatile uint8_t rx1_len = 0; //接收一帧数据的长度
volatile uint8_t rec1_end_flag = 0; //一帧数据接收完成标志
uint8_t rx1_buffer[BUFFER_SIZE]={0}; //接收数据缓存数组
添加串口及IDLE处理函数
打开uart.c文件,在文件末尾的USER CODE BEGIN 1下方添加下列函数
void Usart1_IDLE(void) //USART1的IDLE接收
{ uint32_t tmp_flag = 0; uint32_t temp;tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位if((tmp_flag != RESET))//idle标志被置位{__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位HAL_UART_DMAStop(&huart1); // 停止DMA传输,防止temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数 rx1_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数rec1_end_flag = 1; // 接受完成标志位置1 }
}void Usart1_Handle() //USART1对接收的一帧数据进行处理
{DMA_Usart1_Send(rx1_buffer, rx1_len); //将接收到的数据回发给发送端rx1_len = 0;//清除计数rec1_end_flag = 0;//清除接收结束标志位HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE);//重新打开DMA接收
}void DMA_Usart1_Send(uint8_t *buf,uint8_t len) //串口发送封装
{ if(HAL_UART_Transmit_DMA(&huart1,buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数{Error_Handler();}
}
声明变量及函数
打开usart.h文件,在文件开头的USER CODE BEGIN Includes下方添加如下语句
#include "stdio.h"
#include "string.h"
#define BUFFER_SIZE 100 extern volatile uint8_t rx1_len; //接收一帧数据的长度
extern volatile uint8_t rec1_end_flag; //一帧数据接收完成标志
extern uint8_t rx1_buffer[BUFFER_SIZE]; //接收数据缓存数组void Usart1_Handle(void);
void DMA_Usart1_Send(uint8_t *buf,uint8_t len);//串口发送封装
void Usart1_IDLE(void);
启用IDLE中断
进入main.c文件,找到入口函数void mian(void), 在USER CODE BEGIN 2下方开启串口1的DILE中断,并打开DMA接收。
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断 HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE); //开启DMA接收
在while语句中添加接收查询语句。
if(rec1_end_flag) //判断是否接收到1帧数据
{Usart1_Handle(); //前往数据处理函数处理接收到的数据。
}
修改中断文件stm32f1xx_it.c,在中断处理函数中添加Usart1_IDLE();
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 */Usart1_IDLE();/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}