STM32之HAL库—-使用STM32CubeMX配置串口DMA发送数据时不开启串口中断只发送一次数据。
问题
最近在学习使用STM32CubeMX配置DMA时,使用UART作为示例来演示DMA的功能,遇到一个问题,使用串口和DMA传输数据时,在不开启串口中断时,程序只能发送一次数据,查阅了一些资料和博客,总算搞清楚了。
环境配置
使用的是STMF103系列的板子。使用STM32CubeMX配置串口1工作在DMA模式下。
1、选择串口
2、开启串口中断
3、添加DMA
DMA参数保持默认即可
DMA通道的中断在这里会被强制开启。
这里主要并不是讲解如何使用STM32CubeMX配置DMA的,所以只展示了串口和DMA的配置。
例程
1、UART+DMA发送数据(开串口中断)
打开生成的工程,新建一个变量
uint8_t sendBuff[] = "USART test by DMA\r\n";
在 man.c 中的主循环添加以下代码:
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)sendBuff, sizeof(sendBuff));
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
通过串口助手可以看出不断有数据打印出来
2、UART+DMA发送数据(关串口中断)
关闭中断,重新生成代码。
重新烧录一边程序,按下复位键,串口打印如下:
代码分析,为什么不开启串口中断只打印一次
重新打开串口中断,生成代码。
DMA发送数据的中断函数入口是:
void DMA1_Channel4_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
/* USER CODE END DMA1_Channel4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_tx);
/* USER CODE BEGIN DMA1_Channel4_IRQn 1 */
/* USER CODE END DMA1_Channel4_IRQn 1 */
}
USART1的中端入口是:
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
DMA数据发送分析:
1、开启DMA数据传输
点击HAL_UART_Transmit_DMA(&huart1, (uint8_t *)sendBuff, sizeof(sendBuff));进入定义中。
①:判断USART外设当前状态,是否为准备使用
②:将USART外设状态设置为忙碌(记住目前的USART为忙碌)
③:UART_DMATransmitCplt为DAM中断回调函数,huart->hdmatx->XferCpltCallback是一个函数指针。
④:启用DMA传输请求。
记住这四点,后面都要用到。
2、当DMA数据传输完成后,进入中断。
点击HAL_DMA_IRQHandler(&hdma_usart1_tx);进入定义中。
红箭头所指的部分是DMA发送完成的回调函数,它是一个函数指针,也就是调用了函数UART_DMATransmitCplt。
3、调用DMA回调函数
⑤:清除串口到DMA的数据传输标志位。
⑥:使能了串口发送完成中断TCIE。
4、串口中断查看
因为在DMA发送完成后,在回调函数中开启了串口数据发送完成中断,因此,当数据发送完成时,会进入串口中断中。
找到串口发送模式,在进入UART_EndTransmit_IT(huart);函数定义中
如下所示:
⑧:关闭串口发送完成中断
⑨:USART外设当前的状态改为准备使用。(从忙碌态转为了空闲)
至此,一次数据发送完成了。下次发送数据再次调用HAL_UART_Transmit_DMA函数开始。
如果没有串口中断函数,在第一次发送数据时,第②步将USART设为忙碌后,数据传输完成后,没有串口中断函数则不会有第⑨步将USART变为可准备态,便不会在启动DMA到USART的数据传输。
参考博客:
(stm32之HAL库)UART工作在DMA模式要打开串口中断吗?_hal uart dma-CSDN博客
STM32CubeMX学习笔记(7)——DMA接口使用_cubemx dma-CSDN博客
作者:菜鸟_爱学习