【笔记】HAL DMA 串口空闲中断处理不定长数据

应用案例:cubeMX hal库 dma串口应用。串口DMA接收消息,利用串口的空闲中断,实现消息的处理

核心代码

stm32f1xx_it.c空闲中断中获取有效消息数量,并置位消息标志

//"stm32f1xx_it.c"
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
  #define wifi_uart huart4
    uint16_t temp = 0; //dma未使用数据位数
    //
    if (__HAL_UART_GET_FLAG(&wifi_uart,UART_FLAG_IDLE) != RESET) //如果接受到了一帧数据
    {
        __HAL_UART_CLEAR_IDLEFLAG(&wifi_uart); //清除标志位
        //暂停DMA才能读CNDTR
        HAL_UART_DMAStop(&wifi_uart);
        //获取未使用数据传输数量
        temp = (uint16_t) __HAL_DMA_GET_COUNTER(&hdma_usart4_rx);
        //得到 有效数据量
        wifi_msg.msg_count = wifi_msg.msg_buff_size - temp;
        //接收标志置位,等待处理
        wifi_msg.msg_flag = SET;
    }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

usart.c 中开启 空闲中断 只加一行代码__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//空闲中断

#include "usart.h"

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
   //使能IDLE中断
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//空闲中断
  /* USER CODE END USART1_Init 2 */

}

main 添加 代码

//串口接收信息
struct UART_DMA_recv
{
    FlagStatus msg_flag;
    uint16_t msg_count;
    uint16_t msg_buff_size;
    uint8_t msg_data[512];
};
volatile struct UART_DMA_recv wifi_msg = { .msg_buff_size = sizeof(wifi_msg.msg_data) };

main需添加的代码


int main(void)
{
  
//  �?要主动开启才能接收消�?

  HAL_UART_Receive_DMA(&huart1, (uint8_t *)recbuff, RX1_BUFF_SIZE);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  HAL_Delay(10);
	  if( reccount)
	  		{
	  			//发�?�接收到的有效数�?
//	  			HAL_UART_Transmit_DMA(&huart1, (uint8_t *)recbuff, reccount);
		  HAL_UART_Transmit(&huart1, (uint8_t *)recbuff, reccount, 200);
	  			//等待消息发送完成
	  			while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)==RESET);

	  			memset( (uint8_t *)recbuff,0,reccount);
	  			reccount=0;
	  			recflag = RESET;
	  			//打开dma接收
	  			HAL_UART_Receive_DMA(&huart1, (uint8_t *)recbuff, RX1_BUFF_SIZE);
	  		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

注意事项

  • 给MCU的数据 不能超过缓存数组 大小。超过会导致串口一直忙,不能触发空闲中断,也就不能处理数据了。有时间在研究下 超量数据的保证处理。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值