你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32串口中断接收不定长报文并解析

[复制链接]
STMCU 发布时间:2020-10-20 15:21
STM32串口中断接收不定长报文并解析


功能实现背景介绍
本项目中,需要使用STM32的USART6串口与FPGA板(下位机)通信,需要发送和接收数据,有报文应答机制。

使用的报文规则如表格所示
11.png
板间报文的通信协议,校验使用的是和校验
  1. <font size="3">U8 TX_CheckSum(U8 *buf, U8 len) //buf为数组,len为数组长度
  2. {
  3.     U8 i, ret = 0;
  4.     for(i=0; i<len; i++)
  5.     {
  6.         ret += *(buf++);
  7.     }
  8.      ret = ~ret;
  9.     return ret;
  10. }
  11. U8 RX_CheckSum(U8 *buf, U8 len) //buf为数组,len为数组长度
  12. {
  13.     U8 i, ret = 0;
  14.      for(i=0; i<len; i++)
  15.     {
  16.         ret += *(buf++);
  17.     }
  18.     ret = ret;
  19.     return ret+1;
  20. }</font>
复制代码


发送和接收的报文要满足不定长
HAL库的中断接收函数
如果要直接使用HAL库的中断接收函数,也就是HAL_UART_Receive_IT()函数

  1. HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);              //下位机FPGA
复制代码


在使用时,选择串口,选择接收的缓冲区,选择接收长度。


  1. /**
  2.   * @brief  Receives an amount of data in non blocking mode.
  3.   * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  4.   *         the received data is handled as a set of u16. In this case, Size must indicate the number
  5.   *         of u16 available through pData.
  6.   * @param  huart Pointer to a UART_HandleTypeDef structure that contains
  7.   *               the configuration information for the specified UART module.
  8.   * @param  pData Pointer to data buffer (u8 or u16 data elements).
  9.   * @param  Size  Amount of data elements (u8 or u16) to be received.
  10.   * @retval HAL status
  11.   */
  12. HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  13. {
  14.   /* Check that a Rx process is not already ongoing */
  15.   if (huart->RxState == HAL_UART_STATE_READY)
  16.   {
  17.     if ((pData == NULL) || (Size == 0U))
  18.     {
  19.       return HAL_ERROR;
  20.     }

  21.     /* Process Locked */
  22.     __HAL_LOCK(huart);

  23.     huart->pRxBuffPtr = pData;
  24.     huart->RxXferSize = Size;
  25.     huart->RxXferCount = Size;

  26.     huart->ErrorCode = HAL_UART_ERROR_NONE;
  27.     huart->RxState = HAL_UART_STATE_BUSY_RX;

  28.     /* Process Unlocked */
  29.     __HAL_UNLOCK(huart);

  30.     /* Enable the UART Parity Error Interrupt */
  31.     __HAL_UART_ENABLE_IT(huart, UART_IT_PE);

  32.     /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
  33.     __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);

  34.     /* Enable the UART Data Register not empty Interrupt */
  35.     __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);

  36.     return HAL_OK;
  37.   }
  38.   else
  39.   {
  40.     return HAL_BUSY;
  41.   }
  42. }
复制代码


这个函数本质上其实不是中断接收函数,只是配置函数,配置开启中断的信息,并且接收多少定长的数据结束本数据接收,串口的中断接收还是在中断中进行。
我们本次的长度虽然也是定长,但是有两种长度数据的接收,所以还是从设计接收不定长的数据为最终效果。
状态机的运用
对于不定长数据的接收,使用了状态机,分两次中断来接收数据

12.png
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  2. {
  3.         if(huart->Instance == USART6)                                         // 判断是由哪个串口触发的中断
  4.         {
  5.                 if(StateMachine_USART6)                                      //状态机为1,都接收完毕,准备校验
  6.                 {       
  7.       if(re_flag6 == 1)
  8.                         {
  9.                                 UART6_RxCounter = 6;
  10.                                 re_flag6 = 0;
  11.                         }       
  12.       else
  13.                         {
  14.                                 len_counter6 = 2+5+UART6_RxBuffer[2]+(UART6_RxBuffer[3]<<8);  
  15.                           if(UART6_RxBuffer[len_counter6 - 1] == 0x55 && UART6_RxBuffer[0] == 0xAA)       
  16.                           {
  17.                                   UART6_RxCounter = len_counter6;
  18.                           }       
  19.         else
  20.                           {
  21.                                   memset(UART6_RxBuffer,0,0x400);
  22.                                         UART6_RxCounter = 0;
  23.                           }               
  24.                         }                               
  25.                      
  26.                         StateMachine_USART6 = 0;                                   //状态机为0
  27.       len_counter6 = 0;                       
  28.                         HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);               
  29.                 }
  30.                 else                                                         //状态机为0,只接受到了前五个字节,继续接收后面的字节
  31.                 {                                       
  32.                         if(UART6_RxBuffer[0] == 0xAA)
  33.                         {
  34.                                 StateMachine_USART6 = 1;
  35.                                 UART6_RxCounter = 5;
  36.                                 if(UART6_RxBuffer[2] == 0 && UART6_RxBuffer[3] == 0)
  37.                           {
  38.                                   HAL_UART_Receive_IT(&huart6,(uint8_t*)&UART6_RxBuffer[5], 1);
  39.                                         re_flag6 = 1;
  40.                           }
  41.                           else
  42.                             HAL_UART_Receive_IT(&huart6,(uint8_t*)&UART6_RxBuffer[5], 2 + UART6_RxBuffer[2] + (UART6_RxBuffer[3] << 8));
  43.                         }
  44.                         else
  45.                         {
  46.                                 memset(UART6_RxBuffer,0,0x400);
  47.                                 UART6_RxCounter = 0;
  48.                                 HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);
  49.                         }
  50.                        
  51.                 }
  52.         }
  53. }
复制代码


核心思想就是先接收报文的头,根据头来判断后面的长度,把应答报文和音量数据报文区分开,不合格的报文直接舍去同时开启新的接收。




文章出处:Outsider Hub
收藏 1 评论0 发布时间:2020-10-20 15:21

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版