• STM32 串口接收拼帧


     
    串口数据 指令 协议格式

      起始帧

    (1个字节)

          数据帧 

        (5个字节)

        结束帧

      (2 个字节)

      AA

     

      0D  0A

     

     

     

     

     

    typedef enum
    {
      STATUS_IDLE = (uint8_t)0,
      STATUS_HEAD, /* Rx Head */
      STATUS_TYPE, /* Rx Type */
      STATUS_DATA, /* Data filed */
      STATUS_TAIL, /* Tail */
      STATUS_END, /* End of this frame */
    } COMM_TRM_STATUS_TypeDef;

     

    数据帧长度

    #define CMD_DATA_LEN    8  /* 数据帧长度 */

     

    定义串口接收状态

    uint8_t CMD_UART_RX_STATUS = STATUS_IDLE;

     

    串口接收函数

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
      UNUSED(huart);
    
      if(huart == &CMD_UART)
      {   
        switch(CMD_UART_RX_STATUS)
        {
          case STATUS_IDLE:
            if(0xAA == Cmd_Uart_Rx_data)  //AA  起始帧
            {
              CMD_UART_RX_STATUS = STATUS_DATA;
              cmd_uart_recv_cnt = 0;
              cmd_uart_recv_buf[cmd_uart_recv_cnt] = Cmd_Uart_Rx_data;
              cmd_uart_recv_cnt++;
            }
    
            break;
    
          case STATUS_DATA:
            if(cmd_uart_recv_cnt < UART_RECV_BUF_SIZE)
            {
              cmd_uart_recv_buf[cmd_uart_recv_cnt] = Cmd_Uart_Rx_data;
    
              if(0x0D == Cmd_Uart_Rx_data)
              {
                if(cmd_uart_recv_cnt >= (CMD_DATA_LEN - 2))
                {
                  CMD_UART_RX_STATUS = STATUS_TAIL;
                }
              }
    
              cmd_uart_recv_cnt++;
            }
            else
            {
              cmd_uart_recv_cnt = 0;
              memset(cmd_uart_recv_buf, 0, sizeof(cmd_uart_recv_buf)); //接收缓冲区清零
              CMD_UART_RX_STATUS = STATUS_IDLE;
            }
    
            break;
    
          case STATUS_TAIL:
            if(cmd_uart_recv_cnt < UART_RECV_BUF_SIZE)
            {
              cmd_uart_recv_buf[cmd_uart_recv_cnt] = Cmd_Uart_Rx_data;
    
              if(0x0A == Cmd_Uart_Rx_data)
              {
    
                if((cmd_uart_recv_cnt >= (CMD_DATA_LEN - 1)) && (0xAA == cmd_uart_recv_buf[cmd_uart_recv_cnt - (CMD_DATA_LEN - 1)]))
                {
                  /* 完整一帧数据,此处添加处理函数,本例程是freeRTOS系统,使用消息队列来处理数据帧 */
                  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
                  xQueueSendFromISR(xUartQueue, (void *)&cmd_uart_recv_buf[cmd_uart_recv_cnt - (CMD_DATA_LEN - 1)], &xHigherPriorityTaskWoken);   //接收完一帧数据后,将数据发送到队列中
                  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
                }
                else
                {
                  /* 错误数据帧*/
                }
    
                CMD_UART_RX_STATUS = STATUS_IDLE;
                cmd_uart_recv_cnt = 0;
                memset(cmd_uart_recv_buf, 0, sizeof(cmd_uart_recv_buf)); //接收缓冲区清零
    
              }
              else if(0x0D == Cmd_Uart_Rx_data)
              {
                CMD_UART_RX_STATUS = STATUS_TAIL;
                cmd_uart_recv_cnt++;
              }
              else
              {
                CMD_UART_RX_STATUS = STATUS_DATA;
                cmd_uart_recv_cnt++;
              }
            }
            else
            {
              cmd_uart_recv_cnt = 0;
              memset(cmd_uart_recv_buf, 0, sizeof(cmd_uart_recv_buf)); //接收缓冲区清零
              CMD_UART_RX_STATUS = STATUS_IDLE;
            }
    
            break;
    
          default:
            break;
        }
    
        HAL_UART_Receive_IT(&CMD_UART, (uint8_t *)&Cmd_Uart_Rx_data, 1);    //重新开启接收中断
      }
    }

     

  • 相关阅读:
    Qt数据库集成应用封装
    Qt个人研究进展
    Qt仿win7自动顶部最大化左侧右侧半屏效果
    Qt编写QUI皮肤生成器
    java定时任务
    进程间通信(java)--队列
    单例设计模式-java
    Java RMI
    远程调用方式概述
    IO模型-java版
  • 原文地址:https://www.cnblogs.com/birdBull/p/15944191.html
Copyright © 2020-2023  润新知