zoukankan      html  css  js  c++  java
  • 单片机模块化程序: CRC校验

    前言

      这一节说明一下数据传输中常用的CRC校验

      所谓CRC校验,说白了就是对数据做下计算,然后把计算结果放到最后面

      平时用的最多的算是CRC16

    直接上菜

    计算CRC

    /**
    * @brief calculate CRC
    * @param *modbusdata: Source data address
    * @param length: data length
    * @param
    * @retval CRC16 Value
    * @example
    **/
    int crc16_modbus(u8 *modbusdata, int length)
    {
      int i, j;
      int crc = 0xffff;//0xffff or 0
      for (i = 0; i < length; i++)
      {
        crc ^= modbusdata[i];
        for (j = 0; j < 8; j++)
        {
          if ((crc & 0x01) == 1)
          {
            crc = (crc >> 1) ^ 0xa001;
          }
          else
          {
            crc >>= 1;
          }
        }
      }

      return crc;
    }

      

     判断接收的数据CRC是否正确

    /**
    * @brief check CRC for data
    * @param *modbusdata: Read data address
    * @param length: Read data length
    * @param
    * @retval 1:CRC16 OK
    * @example
    **/
    int crc16_flage(u8 *modbusdata, int length)
    {
      int Receive_CRC=0,calculation=0;

      if(length<=2)
      {
        return 0;
      }

      Receive_CRC = crc16_modbus(modbusdata, length-2);
      calculation = modbusdata[length-2];
      calculation <<= 8;
      calculation += modbusdata[length-1];
      if(calculation != Receive_CRC)
      {
        return 0;
      }
      return 1;
    }

    发送的数据加上CRC

      我想发送 01 00 55 aa 数据

        

      最终发送的数据

        

      说明: 

      1.最后两位 F7 和 BE就是经过CRC16计算之后的数据;高位在前,低位在后

      2.整个数据发给另一个设备以后,另一个设备用同样的方式计算 01 00 55 aa 的CRC16值

      然后判断下自己计算的值是不是 F7,BE

    判断接收的数据CRC是否正确

      

      

    上位机(C# / JAVA)CRC16校验程序

      /// <summary>
      /// calculate CRC
      /// </summary>
      /// <param name="modbusdata">Source data address</param>
      /// <param name="length">data length</param>
      /// <returns></returns>
      private int crc16_modbus(byte[] modbusdata, int length)
      {
        int i, j;
        int crc = 0xffff; //0xffff or 0
        try
        {
          for (i = 0; i < length; i++)
          {
            crc ^= modbusdata[i]&0xff;
            for (j = 0; j < 8; j++)
            {
              if ((crc & 0x01) == 1)
              {
                crc = (crc >> 1) ^ 0xa001;
              }
              else
              {
                crc >>= 1;
              }
            }
          }
        }
        catch (Exception)
        {
          throw;
        }
        return crc;
      }

      /// <summary>
      ///
      /// </summary>
      /// <param name="modbusdata"></param>
      /// <param name="length"></param>
      /// <returns></returns>
      private int crc16_flage(byte[] modbusdata, int length)
      {
        int Receive_CRC = 0, calculation = 0;//接收到的CRC,计算的CRC
        if(length<=2) return 0;
        Receive_CRC = crc16_modbus(modbusdata, length-2);
        calculation = modbusdata[length -2];
        calculation <<= 8;
        calculation += modbusdata[length-1];
        if (calculation != Receive_CRC)
        {
          return 0;
        }
        return 1;
      }

      注:对于上位机byte类型需要&0xff

        

        

        

    扩展

      大部分设备的CRC16计算方式,这个地方是 0xffff, 但是也有0的情况

      

  • 相关阅读:
    Python的一些版本分析
    2006年的长春.NET俱乐部
    大病了一场,不过闲时对AJAX探索时,实现了IE TREE无刷新
    关于AJAX开发
    提供可在WSS上使用的MYTREE
    关于WSS搜索的问题
    转发:使用JavaScript删除ASP.NET生成的HttpCookie
    AJAX(2)
    在将WEBPART打包成*.CAB包和*.MSI安装包后,竟然无法将其安装到指定的WSS网站
    转发:Session研习笔记
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/12117491.html
Copyright © 2011-2022 走看看