使用环形缓冲区可以解决HAL库接受中断的数据接受不完整问题,由于中断的速度不够快,会导致接受的数据被快速覆盖。
详见下面链接
https://blog.csdn.net/m0_72065741/article/details/135630825?spm=1001.2014.3001.5501
static circle_buffer Rxbuffer;//定义环形缓冲区结构体变量
static uint8_t Getbuffer[100];//定义环形缓冲区
static uint8_t g_recvchar;//定义存储接收数据的字节变量
static volatile uint32_t g_Tx_sign = 0;//定义发送完成标志位,必须定义volatile类型,否则改变量会被编译器优化
static volatile uint32_t g_Rx_sign = 0;//定义接收完成标志位,必须定义volatile类型,否则改变量会被编译器优化
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)//发送完成回调函数
{
g_Tx_sign = 1;//标志位置1表示发送完成
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//接收完成回调函数
{
g_Rx_sign = 1;//标志位置1表示接收完成
Circle_Write(&Rxbuffer,g_recvchar);//将接收到的数据逐字节写入环形缓冲区
HAL_UART_Receive_DMA(&huart1,&g_recvchar,1);//使能串口DMA中断
}
void Wait_Tx_Complete(void)//等待发送完成函数
{
while(g_Tx_sign == 0);
g_Tx_sign = 0;
}
void Wait_Rx_Complete(void)//等待接收完成函数
{
while(g_Rx_sign == 0);
g_Rx_sign = 0;
}
void Get_Buffer_Init(void)//初始化
{
Circle_Buffer_Init(&Rxbuffer,100,Getbuffer);//环形缓冲区初始化
HAL_UART_Receive_DMA(&huart1,&g_recvchar,1);//使能串口DMA中断
}
int UART_GetChar(uint8_t *pVal)//得到一个字节
{
return Circle_Read(&Rxbuffer,pVal);//读取字节并返回值
}
int main(void)
{
/* USER CODE BEGIN 1 */
char data1[] = "hello world\r\n";
char data2[] = "Input:";
uint8_t c = 0;
uint8_t getdata;
uint8_t getbuffer[10];//定义一个缓冲区用于保存数据,可用此来控制外设
int i = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
Get_Buffer_Init();
HAL_UART_Transmit(&huart1,(uint8_t *)data1,strlen(data1),1000);
HAL_UART_Transmit_DMA(&huart1,(uint8_t *)data2,strlen(data2));
Wait_Tx_Complete();
while (1)
{
while (0 != UART_GetChar(&getdata));//如果读函数能够读取数据则返回0
getbuffer[i] = getdata;//将字节存入缓冲区
i++;
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(i == 10)//如果缓冲区满了
{
i = 0;
HAL_UART_Transmit_DMA(&huart1,getbuffer,10);//将缓冲区十个字节的数据发送
Wait_Tx_Complete();
HAL_UART_Transmit(&huart1,(uint8_t *)"\r\n",1,1000);
HAL_UART_Transmit_DMA(&huart1,(uint8_t *)data2,7);
Wait_Tx_Complete();
}
}
/* USER CODE END 3 */
}