STM32F103 STM32CUBE HAL库 串口DMA发送无法执行回调

STM32F103 STM32CUBE HAL库 串口DMA接收无法执行回调

一、STM32CubeMX 串口DMA配置

配置串口2波特率19200,启用DMA发送正常模式。配置DMA中断。

二、串口程序生成代码

串口初始化程序

c 复制代码
void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 19200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

DMA中断处理程序入口

c 复制代码
/**
  * @brief This function handles DMA1 channel6 global interrupt.
  */
void DMA1_Channel6_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */

  /* USER CODE END DMA1_Channel6_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_rx);
  /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */

  /* USER CODE END DMA1_Channel6_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel7 global interrupt.
  */
void DMA1_Channel7_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel7_IRQn 0 */

  /* USER CODE END DMA1_Channel7_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_tx);
  /* USER CODE BEGIN DMA1_Channel7_IRQn 1 */

  /* USER CODE END DMA1_Channel7_IRQn 1 */
}

三、代码新增

3.1 自定义DMA回调函数

弱函数重定义

c 复制代码
/**
  * @brief  Tx Transfer completed callbacks.
  * @param  huart  Pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval None
  */
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
}

重定义回调函数

c 复制代码
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
   if (huart->Instance == USART1)
   {
		...
   }
}

四、DMA发送问题点

在实际测试中,发现第一次发送后进入中断后无法再次发送,且未执行回调函数。

调试发现。

当发送使用HAL_UART_Transmit_DMA发送数据时,状态呗置位了,再次发送不发进入if判断。

解决办法1

调用发送接口后将状态 huart->gState 复位。但是发送数据太长时,数据可能还未传输完成,可能会导致状态不一致。如果HAL_UART_Transmit_DMA调用的频率过快,可能出现冲突,数据错乱。

解决办法2

发送后在发送中断回调函数中复位状态。

新问题,回调函数无法执行,DMA正常模式下,未调用会点函数:


此时需要更改UART_DMATransmitCplt函数或者更改成循环模式。

c 复制代码
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
  /* DMA Normal mode*/
  if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
  {
    huart->TxXferCount = 0x00U;

    /* Disable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    /* Enable the UART Transmit Complete Interrupt */
    ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
	  
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
    /*Call registered Tx complete callback*/
    huart->TxCpltCallback(huart);
#else
    /*Call legacy weak Tx complete callback*/
    HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
  }
  /* DMA Circular mode */
  else
  {
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
    /*Call registered Tx complete callback*/
    huart->TxCpltCallback(huart);
#else
    /*Call legacy weak Tx complete callback*/
    HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
  }
}

参考STM32F4

总结

STM32CUBE给开发提供了很多便利,但是HAL库还是有不少坑在里面,需要我们理解库函数的机制,遇到BUG后去调试优化。

相关推荐
振浩微433射频芯片2 小时前
工业遥控器总在关键时刻“掉链子”?——433MHz芯片方案如何破局
网络·单片机·嵌入式硬件·物联网·工业遥控
三易串口屏4 小时前
三易串口屏开发教程:如何使用键盘控件输入参数并发送给单片机
单片机·嵌入式硬件·串口屏·三易串口屏·键盘控件
十月的皮皮4 小时前
STM32从零到量产开发:四路继电器工业控制模块开发实战笔记(小白视角)
c语言·笔记·stm32·stm32cubemx·hal库
2CM_Embed5 小时前
F28379D 下载后 VOFA+ 无数据、Reset 后恢复:一次 TZ 中断误触发排查记录
笔记·单片机·sci·c2000·f28379d·vofa·tz
国科安芯5 小时前
空间机电一体化:AS32S601型抗辐射MCU在卫星推进与执行机构控制中的关键技术研究
单片机·嵌入式硬件·物联网·机器人·云计算
国科安芯5 小时前
AS32S601型抗辐射MCU在分布式太空算力架构中的技术演进与应用前景
人工智能·分布式·单片机·嵌入式硬件·架构·边缘计算
国科安芯5 小时前
在轨能源中枢:AS32S601型抗辐射MCU在卫星电源管理与配电系统中的控制策略研究
嵌入式硬件·架构·能源·risc-v·sps·电源管理·卫星
纯音乐sjc5 小时前
ARM Linux 嵌入式中断全流程解析:从 GPIO 到 GIC 架构实战
单片机·嵌入式硬件
雯宝5 小时前
|____1.4外部中断/看门狗/定时器/PWM/RTC/待机唤醒/ADC/DAC/IIC/SPI/485/CAN
单片机
sramdram20 小时前
基于32位微控制器的FOC汽车水泵方案
单片机·嵌入式硬件·汽车·微控制器·32位微控制器