| 
 
 前言
   这一节说明一下数据传输中常用的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;
 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校验程序
   /// /// calculate CRC
 ///
 /// Source data address
 /// data length
 ///
 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&0xff;
 for (j = 0; j < 8; j++)
 {
 if ((crc & 0x01) == 1)
 {
 crc = (crc >> 1) ^ 0xa001;
 }
 else
 {
 crc >>= 1;
 }
 }
 }
 }
 catch (Exception)
 {
 throw;
 }
 return crc;
 }
 
 
   /// ///
 ///
 ///
 ///
 ///
 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的情况 
 |