日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

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

發(fā)布時(shí)間:2023/12/13 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 单片机模块化程序: CRC校验 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

  這一節(jié)說明一下數(shù)據(jù)傳輸中常用的CRC校驗(yàn)

  所謂CRC校驗(yàn),說白了就是對(duì)數(shù)據(jù)做下計(jì)算,然后把計(jì)算結(jié)果放到最后面

  平時(shí)用的最多的算是CRC16

直接上菜

計(jì)算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;
}

  

判斷接收的數(shù)據(jù)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;
}

發(fā)送的數(shù)據(jù)加上CRC

  我想發(fā)送 01 00 55 aa 數(shù)據(jù)

    

  最終發(fā)送的數(shù)據(jù)

    

  說明:

  1.最后兩位 F7 和 BE就是經(jīng)過CRC16計(jì)算之后的數(shù)據(jù);高位在前,低位在后

  2.整個(gè)數(shù)據(jù)發(fā)給另一個(gè)設(shè)備以后,另一個(gè)設(shè)備用同樣的方式計(jì)算01 00 55 aa 的CRC16值

  然后判斷下自己計(jì)算的值是不是 F7,BE

判斷接收的數(shù)據(jù)CRC是否正確

  

  

上位機(jī)(C# / JAVA)CRC16校驗(yàn)程序

  /// <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,計(jì)算的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;
  }

  注:對(duì)于上位機(jī)byte類型需要&0xff

    

    

    

擴(kuò)展

  大部分設(shè)備的CRC16計(jì)算方式,這個(gè)地方是 0xffff, 但是也有0的情況

  

總結(jié)

以上是生活随笔為你收集整理的单片机模块化程序: CRC校验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。