STM32-CubeMx-HAL库-串口空闲中断+DMA——利用HAL_UARTEx_ReceiveToIdle_DMA实现不定长数据接收
1 主要函数
主要用到的函数:
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
/*
@parameter1:串口句柄
@parameter2:目标缓存区
@parameter3:接收长度,这个接收长度一般设置大于我们所要的不定长数据长度
@note:此函数实现了:设置空闲中断模式、调用UART_Start_Receive_DMA函数、空闲中断使能
*/
HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
/*
@note:空闲中断回调函数
*/
2 CubeMX配置
2.1 在串口配置中添加DMA:USART_Rx
![DMA_Settings](https://img-blog.csdnimg.cn/1cb780c215eb4b52a8c2a798d32b62c6.png)
PS:这里DMA选择Normal模式,然后再回调函数HAL_UARTEx_RxEventCallback
中重新调用HAL_UARTEx_ReceiveToIdle_DMA
函数即可实现不断接收不定长数据的效果。
如果非要选择Circular模式,需要在回调函数中加入HAL_UART_DMAStop
函数,否则会数据错乱。
2.2 中断设置
![NVIC_Settings](https://img-blog.csdnimg.cn/7dd75c535d1c4db98b0bd421e24cd717.png)
PS:这里要把串口中断打开
(空闲中断需要用到串口中断),把相应的DMA中断关闭
(因为对于不定长数据,DMA中断判别不了到底要接收几个字节的数据才中断,而串口可以),否则容易引起异常。(如果是定长的数据的话,可以关闭串口中断,直接开DMA中断。)
3 代码实现
/*
先调用HAL_UARTEx_ReceiveToIdle_DMA函数(比如说在main中调用),产生空闲中断后进入中断服务函数,中断服务函数会调用回调函数。
*/
int main(void)
{
...
HAL_UARTEx_ReceiveToIdle_DMA(&huart3,DATA_BUFF,BUFF_SIZE);
...
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance == USART3)
{
//这里的DMA为Normal模式
//HAL_UART_DMAStop(huart)//如果DMA为Circular模式,回调函数加上stop函数
USER_FNC();//用户自定义函数
HAL_UARTEx_ReceiveToIdle_DMA(&huart3,DATA_BUFF,BUFF_SIZE);//继续接收数据
}
}