HAL库DMA+空闲中断接受
今天遇到了一个问题,关于DMA+空闲中断的问题,串口无法接收到内容
具体代码如下
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,s_buff, RXDMASIZE);
//此函数放在初始化出来打开空闲中断
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
if(huart->Instance == USART1){
// HAL_UART_DMAStop(huart);//若接收为Circle模式,则需要取消注释,我用的normal模式
/*下面是空闲中断想要实现的功能
uint8_t buff[8];
memset(buff,s_buff,sizeof(buff));
memset(s_buff,0,sizeof(s_buff));
DataTrans(buff);
功能到这里结束*/
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,s_buff, RXDMASIZE);
//再次打开空闲中断
}
}
这样设置就完成了,但是却遇到了问题,每一次进入到中断处理函数时,进入的不是下面中断
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t
而是
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
我调试进入到中断处理函数进行查看时发现他会进入到如下if语句当中
也就是发生了溢出错误,导致处理函数直接就调用了错误回调函数,想要验证的同学可以自己写一个错误回调函数的串口调试看看。以下是我写的,进入错误回调函数会给我发送一个"error"。
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1){
HAL_UART_Transmit(&huart1,"error",5,0xff);
// printf("x:%d,y:%d",value[0],value[1]);
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_ORE))//溢出标志
{
uint32_t temp = USART1->SR;
temp = USART1->DR;
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,s_buff, RXDMASIZE);
}
}
后来发现是MX的问题生成代码的问题。
在初始化时,MX_DMA_Init();放在了DMA接收所使用的串口(我这里时串口1)初始化的前面,导致DMA无法确定外设发送的数据存到哪里,因此无法读取串口接收缓冲器里的内容,当数据接收区或者FIFO区有数据或者满时,又有新数据进来,会导致发生溢出错误,一旦发生溢出错误,RX 移位寄存区虽然能有新数据不断的覆盖,但是数据不会到达RXR或FIFO(现象是:RXNE在ORE置位时不会被置位),导致程序中不能读到新的数据。
详细可以参照大佬这篇文章的的注意事项
链接: 参考文章