介绍空闲中断接收串口的两种方法,使用HAL官方提供的函数实现:
方法一:单纯使用空闲中断。
方法二:空闲中断+DMA
方法一:使用空闲中断IDLE来接收不定长数据
使用到的HAL函数是:HAL_UARTEx_ReceiveToIdle_IT。我们通过这个函数来开启空闲接收中断。
HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
参数1是串口句柄,参数2是接收缓存区,参数3是预期接收字节大小(也可以理解为接收的字节最大是多少)。这个函数的作用是:当接收到的数据长度达到 Size
指定的数量,或者UART在接收数据过程中进入空闲状态时,会触发一个中断。
我们看一下HAL_UARTEx_ReceiveToIdle_IT函数的源码,我们截取其中一部分来看,如下:
红圈部分:设置空闲中断和接收完成中断。然后是开启接收中断(主要是使能)
然后,当触发中断时,(大家可以自行查看中断服务函数的源码)会执行HAL_UARTEx_RxEventCallback这个回调函数,我们需要重写该函数,在里面实现一些具体功能,然后需要重写开启HAL_UARTEx_ReceiveToIdle_IT,保证下一次接收。Size表示接收一帧数据的长度。
提供一个回调函数例子,供参考:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
if(huart->Instance == huart1.Instance){
printf("%d\n",Size);
}
HAL_UARTEx_ReceiveToIdle_IT(&huart1,buf,10); //重新开启
}
方法二:空闲中断IDLE+DMA来接收数据
首先完成串口接收DMA初始化工作。
使用到的HAL函数是:HAL_UARTEx_ReceiveToIdle_DMA。
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
这个函数和上面的HAL_UARTEx_ReceiveToIdle_IT函数是类似的,区别是这个函数会开启的DMA接收中断。
在使用过程中,重点是:在调用该函数后,要关闭DMA的半传输完成中断。如果不关闭,那么当接收到一半Size以上长度的数据时,除了产生一次空闲中断,还也会产生一次半传输完成中断,这两个中断都会调用一次HAL_UARTEx_RxEventCallback回调函数,共调用了两次。
提供一个回调函数例子,供参考:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
if(huart->Instance == huart1.Instance){
printf("size:%d\n",Size);
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,buf,10); //重新开启
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); //失能DMA本身的半传输中断
}
以上是所有内容,有问题联系微信:cccjw08