错误记录:
快速发送几次错误回调报错,然后再也不能接收
源代码:
c
// 串口接收完成回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);
if(huart->Instance == USART1)
{
HAL_UART_Transmit(&huart1,&Uart1RX_Data,1,0xFFFF);
HAL_UART_Receive_IT(&huart1,&Uart1RX_Data,1);
}
if(huart->Instance == USART2)
{
HAL_UART_Transmit(&huart2,&Uart2RX_Data,1,0xFFFF);
HAL_UART_Receive_IT(&huart2,&Uart2RX_Data,1);
}
}
//错误回调
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if( huart->Instance == USART1)
{
printf("error %d\r\n",huart->ErrorCode);
}
}
若定长串口中断接收数据,数据溢出,将会产生数据溢出错误,中断不再接收数据 这和前面的开启接收中断有关:
c
//使能 USART1 的接收中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);
//开启 USART1 的连续接收中断,并指定接收缓冲区的地址和长度
HAL_UART_Receive_IT(&huart1,&Uart1RX_Data,8);
超出缓冲区就会发生溢出,然后不能再接收
可以修改为下面的示例:https://blog.csdn.net/Qxiaofei_/article/details/119029425
c
#include "debug.h"
#include "string.h"
#define RXBUFFERSIZE 256 //最大接收字节数
// UART_HandleTypeDef *UART_Handle = &huart1;
//定义数据缓冲区
uint8_t RxBuffer[RXBUFFERSIZE];
uint8_t Uart1_RxBuffer; //接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0; //接收缓冲计数
void Debug_Init(void)
{
/*串口硬件配置代码(使用cudeMX则不需要此部分)
Init the GPIO of USART1
*/
//使能 USART1 的接收中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);
//开启 USART1 的连续接收中断,并指定接收缓冲区的地址和长度
HAL_UART_Receive_IT(&huart1,&Uart1_RxBuffer,1);
}
//串口1接收完成回调函数
void UART1_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
if(Uart1_Rx_Cnt >= 255) //溢出判断
{
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF);
}
else
{
RxBuffer[Uart1_Rx_Cnt++] = Uart1_RxBuffer;
//单字符判断
if(Uart1_RxBuffer == '1')//当发送1时,翻转电平
{
printf("发送1");
}
else if(Uart1_RxBuffer == '2')//当发送2时,翻转电平
{
printf("发送2");
}
else if(Uart1_RxBuffer == '3')//当发送3时,翻转电平
{
printf("发送3");
}
else if(Uart1_RxBuffer == '4')//当发送4时,翻转电平
{
printf("发送4");
}
if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
{
//这里可以写多字节消息的判断
HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
//复位
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&Uart1_RxBuffer, 1); //因为接收中断使用了一次即关闭,所以在最后加入这行代码即可实现无限使用
}
//串口1错误回调函数(主要用来清除溢出中断)
void UART1_ErrorCallback(UART_HandleTypeDef *huart)
{
if(HAL_UART_ERROR_ORE)
{
uint32_t temp = huart->Instance->SR;
temp = huart->Instance->DR;
}
}
参考
STM32CubeMX之串口使用(中断方式)
https://zhuanlan.zhihu.com/p/162732368