[STM32C0] 【STM32C092RC 测评】+ 04 空闲中断+DAM接收不定长数据,并返回至串口2

 在STM32,串口接收数据时的经常使用的方式就是使用STM32的串口中断的方式,即串口每次接收到一个字节时候,就会产生串口中断,将接收到数据放到接收数组内,同时清除标志位。这种接收方式比较简单,之前的学习记录中也尝试过该接收方式,这种接收方式比较浪费CPU的资源。在串口通讯中,经常会遇到接收不定长的数据,这时候没有必要采用上述方式进行数据的接收处理,比如STM32的标准库和HAL中对串口接收中断的处理中,再到中断处理函数,CPU需要执行很多的程序,频繁的中断为CPU的运行增加了不少的负担,也可能会出现接收出错的情况,而且不确定接收数据长度时,也不确定处理函数应该何时进行处理。
  为了解决上述问题,我们尝试使用串口的空闲中断与DMA接收数据,即开始STM32的空闲中断时,告知CPU本次接收数据完成了,可以进行下一步骤的处理;当然串口中断判断的依据,我个人的理解就是:使用串口与DMA接收字节数据时,当串口检测到在1-2个字节通讯时间内,串口没有接收到数据时,就会判定串口空闲了,使用DMA将数据拷贝到其他数据内进行处理即可。
二:STM32 cube MX 软件配置
 这里我们要使能STM32的DMA发送和接收中断
 


三:软件代码程序编写思路
1:首先需要清楚空闲中断标志,以便再次进入该串口空闲中断,
2:停止DMA的接收,防止计算长度时候出错
3:计算一下DMA数据中有效数据
4:将有效数据拷贝至其他的定义的数据内,以便程序处理
5:将接收完一包有效数据的标志位置位,同时需要再次开启DMA接收,
四:程序编写:
4.1 串口2初始化函数

复制

 
  1. void MX_USART2_UART_Init(void)
  2. {
  3.   /* USER CODE BEGIN USART2_Init 0 */
  4.   /* USER CODE END USART2_Init 0 */
  5.   /* USER CODE BEGIN USART2_Init 1 */
  6.   /* USER CODE END USART2_Init 1 */
  7.   huart2.Instance = USART2;
  8.   huart2.Init.BaudRate = 115200;
  9.   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  10.   huart2.Init.StopBits = UART_STOPBITS_1;
  11.   huart2.Init.Parity = UART_PARITY_NONE;
  12.   huart2.Init.Mode = UART_MODE_TX_RX;
  13.   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  14.   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  15.   huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  16.   huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  17.   huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  18.   if (HAL_UART_Init(&huart2) != HAL_OK)
  19.   {
  20.     Error_Handler();
  21.   }
  22.   /* USER CODE BEGIN USART2_Init 2 */
  23.         __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);    //IDLE interrupt
  24.         //��DMA���գ�ָ�����ջ������ͽ��մ�С
  25.         HAL_UART_Receive_DMA(&huart2, (uint8_t *)&RecBuffer2, 256);
  26.   /* USER CODE END USART2_Init 2 */
  27. }

4.2 串口空闲中断处理函数

复制

 
  1. /**
  2.   * 函数功能: 串口接收空闲中断
  3.   * 输入参数: huart:串口句柄
  4.   * 返 回 值: 无
  5.   * 说    明: 无
  6.   */
  7. void UsartReceive_IDLE(UART_HandleTypeDef *huart)
  8. {
  9.         //当触发了串口空闲中断
  10.   if((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET))
  11.         {
  12.                  if(huart->Instance == USART2)
  13.                 {
  14.                         /* 1.清除标志 */
  15.                         __HAL_UART_CLEAR_IDLEFLAG(huart);         //清除空闲标志
  16.                         /* 2.读取DMA */
  17.                         HAL_UART_DMAStop(huart);                         //先停止DMA,暂停接收               
  18.                         /* 3.搬移数据进行其他处理 */
  19.                         usart2_rx_len = 256 - (__HAL_DMA_GET_COUNTER(&hdma_usart2_rx)); //接收个数等于接收缓冲区总大小减已经接收的个数
  20.                         memcpy(Usart2_DEAL_RX_Buf, RecBuffer2, usart2_rx_len);
  21.                         usart2_Flag = 1;                        
  22.                         /* 4.开启新的一次DMA接收 */
  23.                         HAL_UART_Receive_DMA(&huart2, (uint8_t *)&RecBuffer2, 256);
  24.                 }
  25.         }
  26. }

4.3 主程序返回数据:

复制

 
  1. HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);  
  2.                 HAL_Delay(200);
  3.                 if(usart2_Flag == 1)
  4.                 {
  5.                         usart2_Flag = 0 ;
  6.                         HAL_UART_Transmit(&huart2,Usart2_DEAL_RX_Buf,usart2_rx_len,1000);
  7.                 }        

五:实物验证如下:
 


实测,串口的数据回传功能正常。。。
六:程序测试文件
 

 LED0.zip (9.71 KB, 下载次数: 2)


---------------------
作者:聪聪哥哥
链接:https://bbs.21ic.com/icview-3453974-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值