单片机模块化程序: CRC校验
前言
這一節(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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jpg/png格式图片转eps格式的方法
- 下一篇: Python 读取 .mdb文件信息