串口接收数据处理的另一种方法

这段代码主要展示了在Linux环境下,通过UART进行串口通信的实现,包括数据接收、CRC校验以及不同命令的处理。当接收到数据时,会检查数据的完整性和CRC,然后根据不同的命令(如读写存储器)进行响应,并返回相应的数据。
摘要由CSDN通过智能技术生成

void Link_Linux(void)
{
  static u16 RxdLenCp;
  static u8 cnt = 0;
  static TIMER_STRUCT T1; TimeMs(&T1);
  u16 RxdLen = *RxdLength;
  if(cnt == 0)
  {
    cnt++;
    drv_uart1_get_buff(115200, &TxdBuff, &RxdBuff, &TxdLength, &RxdLength);
  }
  else if(RxdLenCp != RxdLen) //接收完成长度和正接收长度不相等时,(RxdLen 一位一位传过来的,所以当接收到数据T1.Delay就会清零,当不清零延时到10MS时就说明接收完成)
  {
    T1.Delay = 0;
    RxdLenCp = RxdLen;
  }
  else if(RxdLen > 0 && T1.Delay >= 10)  //当不清零延时到10MS时就说明接收完成)
  {
    if(RxdLen >= 5 && RxdBuff[0] == 0x55 && RxdBuff[1] >= 5)
    {
      u16 crc1 = GetCRC16(RxdBuff, RxdBuff[1] - 2);
      u16 crc2 = ((u16)RxdBuff[RxdBuff[1] - 2]<<0) + ((u16)RxdBuff[RxdBuff[1] - 1]<<8);
      if(crc1 == crc2)
      {
        if(RxdBuff[2] == 0x01 || RxdBuff[2] == 0x02)
        {
          u8 *data = 0;
          u16 len = RxdBuff[5];
          if(RxdBuff[2] == 0x02){len = RxdBuff[1] - 7;}
          u16 addr = (((u16)RxdBuff[3]<<8) + ((u16)RxdBuff[4]<<0));
               if(addr < IAP_VER_ADDR  + IAP_VER_LEN)  {data = &gs.IapVer.data[addr - IAP_VER_ADDR];}
          else if(addr < APP_VER_ADDR  + APP_VER_LEN)  {data = &gs.AppVer.data[addr - APP_VER_ADDR];}
          else if(addr < IO_OUT_ADDR   + IO_OUT_LEN)   {data = &gs.io.out.data[addr - IO_OUT_ADDR];}
          else if(addr < IO_IN_ADDR    + IO_IN_LEN)    {data = &gs.io.in.data[addr - IO_IN_ADDR];}
          else if(addr < STATE_ADDR    + STATE_LEN)    {data = &gs.State.data[addr - STATE_ADDR];}
          else if(addr < MOTOR_ADDR    + MOTOR_LEN)    {data = &gs.motor.data[addr - MOTOR_ADDR];}
          else if(addr < DISTANCE_ADDR + DISTANCE_LEN) {data = &gs.Distance.data[addr - DISTANCE_ADDR];}
          else if(addr < BAT_ADDR + BAT_LEN)           {data = &gs.bat.data[addr - BAT_ADDR];}
          else if(addr < SHOW_ADDR + SHOW_LEN)         {data = &gs.show.data[addr - SHOW_ADDR];}
          
          if(RxdBuff[2] == 0x01)
          {
            if(data != 0)
            {
              TxdBuff[0] = 0xaa;            //帧头
              TxdBuff[1] = 0x05;            //帧长度
              TxdBuff[2] = 0x01;            //命令
              TxdBuff[3] = RxdBuff[3];      //地址
              TxdBuff[4] = RxdBuff[4];      //地址
              for(u8 i=0; i<len; i++)
              {
                TxdBuff[TxdBuff[1]++] = data[i];
              }
              TxdBuff[1] += 2;
              crc1 = GetCRC16(TxdBuff, TxdBuff[1]-2);
              TxdBuff[TxdBuff[1]-2] = (crc1>>0)&0xff;  //CRC16
              TxdBuff[TxdBuff[1]-1] = (crc1>>8)&0xff;  //CRC16
              *TxdLength = TxdBuff[1];
            }
          }
          else if(RxdBuff[2] == 0x02) //
          {
            if(data != 0)
            {
              TxdBuff[0] = 0xaa;            //帧头
              TxdBuff[1] = 0x08;            //帧长度
              TxdBuff[2] = 0x02;            //命令
              TxdBuff[3] = RxdBuff[3];      //地址
              TxdBuff[4] = RxdBuff[4];      //地址
              TxdBuff[5] = 0;               //状态
              crc1 = GetCRC16(TxdBuff, 6);
              TxdBuff[6] = (crc1>>0)&0xff;  //CRC16
              TxdBuff[7] = (crc1>>8)&0xff;  //CRC16
              *TxdLength = TxdBuff[1];
              u8 WriteLength = RxdBuff[1] - 7;
              for(u8 i=0; i < WriteLength; i++)
              {
                data[i] = RxdBuff[i + 5];
              }
            }
          }
        }
        else if(RxdBuff[2] == 0x10)     //读存储器
        {
          if(RxdBuff[7] < 200)
          {
            u32 addr = 0;
            addr |= (u32)RxdBuff[3]<<24;
            addr |= (u32)RxdBuff[4]<<16;
            addr |= (u32)RxdBuff[5]<<8;
            addr |= (u32)RxdBuff[6]<<0;
            TxdBuff[0] = 0xaa;            //帧头
            TxdBuff[1] = RxdBuff[7] + 9;  //帧长度
            TxdBuff[2] = 0x10;            //命令
            TxdBuff[3] = RxdBuff[3];      //地址
            TxdBuff[4] = RxdBuff[4];      //地址
            TxdBuff[5] = RxdBuff[5];      //地址
            TxdBuff[6] = RxdBuff[6];      //地址
            HK32_FLASH_ReadBytes(addr, &TxdBuff[7], RxdBuff[7]);
            crc1 = GetCRC16(TxdBuff, TxdBuff[1]-2);
            TxdBuff[TxdBuff[1]-2] = (crc1>>0)&0xff;  //CRC16
            TxdBuff[TxdBuff[1]-1] = (crc1>>8)&0xff;  //CRC16
            *TxdLength = TxdBuff[1];
          }
        }
        else if(RxdBuff[2] == 0x20) //写存储器
        {
          
        }
      }
    }
    *RxdLength = 0;
  }
  drv_uart1();
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值