打印
[资料工具]

单片机模块化程序--CRC校验

[复制链接]
619|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jerow|  楼主 | 2019-12-30 10:27 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
计算CRC
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] calculate CRC
* @param *modbusdata: Source data address
* @param length: data length
* @param
* @retval CRC16 Value
* [url=home.php?mod=space&uid=389923]@example[/url]
**/
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;
}


使用特权

评论回复

相关帖子

沙发
jerow|  楼主 | 2019-12-30 10:28 | 只看该作者
判断接收的数据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;
}

使用特权

评论回复
板凳
jerow|  楼主 | 2019-12-30 10:29 | 只看该作者
发送的数据加上CRC
我想发送 01 00 55 aa 数据

最终发送的数据

说明:

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

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

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

使用特权

评论回复
地板
jerow|  楼主 | 2019-12-30 10:30 | 只看该作者
判断接收的数据CRC是否正确


使用特权

评论回复
5
jerow|  楼主 | 2019-12-30 10:31 | 只看该作者
上位机(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

使用特权

评论回复
6
jerow|  楼主 | 2019-12-30 10:32 | 只看该作者
扩展
大部分设备的CRC16计算方式,这个地方是 0xffff, 但是也有0的情况

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

520

帖子

3

粉丝