stm32H743串口+DMA+空闲中断,HAL库

具体串口工程如何使用CubeMX生成,不再赘述,例程很多,本人只关心生成之后需要修改和注意的地方。

完整代码:https://download.csdn.net/download/niu_88/11034265

1. 开启空闲中断和DMA接收

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_UART4_Init();
  /* USER CODE BEGIN 2 */
  __HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
  HAL_UART_Receive_DMA(&huart4, rev_buf, BUFFER_LENGTH);
  __HAL_UART_DISABLE_IT(&huart4, UART_IT_ERR);
  __HAL_UART_DISABLE_IT(&huart4, UART_IT_PE);
  /* USER CODE END 2 */

2. 改写DMA停止接收函数

/**
 1. @brief Stop the DMA Receive.
 2. @param huart: UART handle.
 3. @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_DMAStopRx(UART_HandleTypeDef *huart)
{
  /* Stop UART DMA Rx request if ongoing */
  if ((huart->RxState == HAL_UART_STATE_BUSY_RX) &&
      (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
  {
    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);

    /* Abort the UART DMA Rx channel */
    if(huart->hdmarx != NULL)
    {
      HAL_DMA_Abort(huart->hdmarx);
    }

    //UART_EndRxTransfer(huart);
    /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
	CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
	CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);

	/* At end of Rx process, restore huart->RxState to Ready */
	huart->RxState = HAL_UART_STATE_READY;
  }

  return HAL_OK;
}

3. 处理串口空闲中断

/**
  * @brief This function handles UART4 global interrupt.
  */
void UART4_IRQHandler(void)
{
  /* USER CODE BEGIN UART4_IRQn 0 */

  /* USER CODE END UART4_IRQn 0 */
  HAL_UART_IRQHandler(&huart4);
  /* USER CODE BEGIN UART4_IRQn 1 */
  uint32_t isrflags   = READ_REG(huart4.Instance->ISR);
  uint32_t cr1its     = READ_REG(huart4.Instance->CR1);

  if(((isrflags & USART_ISR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET)){
	  __HAL_UART_CLEAR_IDLEFLAG(&huart4);

	  uint32_t _len_dmarev = BUFFER_LENGTH - __HAL_DMA_GET_COUNTER(huart4.hdmarx);

	  if(_len_dmarev){
		  HAL_UART_DMAStopRx(huart4.hdmarx);
		 /* 接收的到的数据处理,添加自己的处理代码 */
		  HAL_UART_Receive_DMA(&huart4, rev_buf, BUFFER_LENGTH);
		  __HAL_UART_DISABLE_IT(&huart4, UART_IT_ERR);
		  __HAL_UART_DISABLE_IT(&huart4, UART_IT_PE);
	  }else{
		  READ_REG(huart4.Instance->RDR);
		  __HAL_UART_CLEAR_OREFLAG(&huart4);
	  }


  }

  /* USER CODE END UART4_IRQn 1 */
}

注意: 
   最关键的就是中断处理,调用官方给的库函数,发送与接收同时工作时容易出现挂掉等问题,所以需要修改DMA停止接收函数;
   进入空闲中断后,首先判断DMA接收到的数据长度是否为0,若为0(即DMA没有接收到数据但进入了空闲中断),则此时串口接收寄存器可能产生了溢出,上一个数据还未读取,则下一个数据立马就来了,产生了溢出中断,需要将RDR寄存器的数据读出来并清掉溢出中断,否则串口再也接收不到数据了,这种情况在传输数据量较频繁、多任务已经在线调试DEBUG情况下很容易发生,可参考手册:
在这里插入图片描述
   若DMA接收到的数据长度不是为0,则停止DMA接收,自己可做数据缓存区处理,然后再次启动DMA接收。每次启动DMA接收后,我还做了禁止奇偶校验错位中断和错误中断使能,因为启动DMA接收函数将这两个中断都使能,若产生了这两个中断而中断函数又没有相应的处理的话,则程序将卡死在中断里了,可依个人情况而设置。
  最近在使用h7,不断的发现库里的bug,很多地方也是经自己修改和完善才能正常使用,哎,慢慢爬坑吧。

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值