5.1串口DMA与接收不定长数据
串口DMA与接收不定长数据
DMA作用:在寄存器与内存之间搬运数据。
使用DMA步骤
1.创建DMA通道
从源地址的数据搬运到目标地址,等全部搬运完成,再通过中断提醒我们
例如,在串口的发送端和接收端创建两条DMA通道,就可以让DMA帮着在串口的寄存器与内存变量间搬运数据。
在DMA Settings中添加两条通道用于USART2接收和发送
2.使用DMA进行发送和接收
发送函数
HAL_UART_Transmit_DMA(huart,pData,Size);
参数说明同HAL_UART_Transmit_IT();
接收函数
HAL_UART_Receive_DMA(huart,pData,Size);
参数说明同HAL_UART_Receive_IT();
即使使用的DMA,其实还是有中断参与其中的,例如RxCpltCallback函数还是由中断触发,但不是由于串口中断触发,而是DMA的传输完成中断
如何接收不定长数据,依靠串口空闲中断,此中断的触发条件与接收的字节数无关,只有串口上无后续字节输入,串口接收从忙碌转为空闲时才会触发,即串口空闲中断发生时,就是一帧数据包接收完成了
串口空闲中断函数
HAL_UARTEx_ReceiveToIdle(huart,pData,Size);
HAL_UARTEx_ReceiveToIdle_IT(huart,pData,Size);
HAL_UARTEx_ReceiveToIdle_DMA(huart,pData,Size);
Ex代表扩展,Idle代表空闲中断
- 此参数中的Size 指的是,一次能接受的最大数据长度
此函数的完成回调函数不再是HAL_UART_ReCpltCallBack()方法了,而是
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{/* Prevent unused argument(s) compilation warning */UNUSED(huart);UNUSED(Size);/* NOTE : This function should not be modified, when the callback is needed,the HAL_UARTEx_RxEventCallback can be implemented in the user file.*/
}
在mian.c中重新声明
值得注意的是:HAL_UARTEx_ReceiveToIdle_DMA() 在接收数据量达到我们设置的最大值一半的时候,也会调用HAL_UARTEx_RxEventCallback(),对于一般的场景可以关闭“DMA传输过半中断”
DMA传输过半中断语句:
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
之后就可以发送不定长数据了
输过半中断语句:
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
之后就可以发送不定长数据了