单片机 用c语言编写 modbus rtu 通讯怎么写啊 主要是crc 校验部分不知道怎么写 怎么把一窜字符进行CRC计算

单片机 用c语言编写 modbus rtu 通讯怎么写啊 主要是crc 校验部分不知道怎么写 怎么把一窜字符进行CRC计算,第1张

我刚刚写好跟PLC连接测试过,可以的

/

CRC计算方法

1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;

2.把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低

8位相异或,把结果放于CRC寄存器;

3.把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;

4.如果移出位为0:重复第3步(再次右移一位);

如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;

5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;

6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;

7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC;

/

/

名称: UART_CRC16_Work()

说明: CRC16校验程序

参数: CRC_Buf:数据地址

CRC_Leni:数据长度

返回: CRC_Sumx:校验值

/

unsigned int UART_CRC16_Work(unsigned char CRC_Buf,unsigned char CRC_Leni)

{

unsigned char i,j;

unsigned int CRC_Sumx;

CRC_Sumx=0xFFFF;

for(i=0;i<CRC_Leni;i++)

{

CRC_Sumx^=(CRC_Buf+i);//异或

for(j=0;j<8;j++)

{

if(CRC_Sumx & 0x01)

{

CRC_Sumx>>=1;

CRC_Sumx^=0xA001;

}

else

{

CRC_Sumx>>=1;

}

}

}

return (CRC_Sumx);

}

CRC校验是循环冗余校验,下面是C#的代码。

protected byte[] GetCRC(byte[] b, int offset, int len)

{

byte CRC16Lo = 0;

byte CRC16Hi = 0;

byte bytC;

byte bytTreat;

byte bytBcrc;

for (int i = 0; i < len; i++)

{

bytC = b[i + offset];

for (int flag = 0; flag <= 7; flag++)

{

bytTreat = (byte)(bytC & 0x80);

bytC = (byte)((bytC 2) % 0x100);

bytBcrc = (byte)(CRC16Hi & 0x80);

CRC16Hi = (byte)(((CRC16Hi 2) % 0x100) + CRC16Lo / 0x80);

CRC16Lo = (byte)((CRC16Lo 2) % 0x100);

if (bytTreat != bytBcrc)

{

CRC16Hi = (byte)(CRC16Hi ^ 0x10);

CRC16Lo = (byte)(CRC16Lo ^ 0x21);

}

}

}

byte[] ReturnData = new byte[2];

ReturnData[0] = CRC16Hi;

ReturnData[1] = CRC16Lo;

return ReturnData;

}

基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(N,K)码。对于一个给定的(N,K)码,可以证明存在一个最高次幂为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码,而G(x)叫做这个CRC码的生成多项式。 校验码的具体生成过程为:假设要发送的信息用多项式C(X)表示,将C(x)左移R位(可表示成C(x)xR),这样C(x)的右边就会空出R位,这就是校验码的位置。用 C(x)xR 除以生成多项式G(x)得到的余数就是校验码。

任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。

以下内容可能对你有用呀。好好看看就明白了。

CRC校验

采用CRC-16,即2字节冗余循环码CRC,低字节在前。CRC码由发端计算,放置于发送消息帧的尾部,接收端再重新计算接收到信息的CRC码,比较计算得到的CRC码是否与接收到的相符,若不符则表明出错。CRC码的计算包括整个消息内容,计算时只用8位数据位,而起始位、停止位及可能的校验位均不参与CRC计算。

CRC校验可以100%检测出所有奇数个随机错误。CRC-16校验可以检测出长度小于等于16的突发错误,可以保证在1014 bit码元中只含有1位未被检测出的错误。CRC-16的具体算法有多种,以下是一个例子。

1置16位寄存器为全1,作为CRC寄存器。

2把一个8位数据与16位CRC寄存器的低字节相异或,把结果放于CRC寄存器中。

3把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位(移出位)。

4如果最低位为0,重复③(再移位);如果最低位为1,CRC寄存器与多项式A001H(1010 0000 0000 0001)进行异或。

5重复③、④,直到右移8次,这样整个8位数据全部进行了处理。

6重复②-⑤,进行下一个8位数据的处理。

7将一帧的所有数据字节处理完后得到CRC-16寄存器。

8将CRC-16寄存器的低字节和高字节交换,得到的值即为CRC-16码。

1系统先把所有的float转换为double类型运算,最终得到的结果截取前七个作为有效数字,这样做可以使计算结果更准确。

2有效数字:从左边第一个不是0的数字起,到精确到的位数止,所有的数字都叫做这个数的有效数字。比如:124的有效数字就是

1、2、4。024

的有效数字就是

2、4。

3

同样的二进制数,假定你定义有符号(signed)类型,则第一位表示的是正负号,0代表正数,1代表负数;而如果定义无符号型(unsigned)的话,第一位为值了。

4如果用指数表示,float类型有效数字为6~7位。double类型为15~16位,具体跟数字有关。

5这个你是在哪看的啊,不对!

整形常量分为十进制、八进制、十六进制:

八进制形式为012前面有个零,十六进制为0x12前面有个0x(注意x前面是零),

而在一个八进制数字前面加\表示是字符型常量,例如\012为ASCII码为10的字符!

这是我逐字敲上去的,还希望您能采纳!

unsigned int caculate_crc16(unsigned char DAT,unsigned char lenth)

{

//DAT指向要计算CRC的数组,lenth为数据的长度

unsigned int crc=0xffff;//crc的初始值为FFFF;

unsigned char i;

unsigned char j;

for(i=0;i<lenth;i++)

{

crc=crc^DAT[i];

for(j=0;j<8;j++)

{

if(crc&0x01)

{

crc=crc>>1;

crc=crc^0xA001;

}

else

{

crc=crc>>1;

}

}

}

return(crc);

}

unsigned int CZ;

CZ=caculate_crc16(comdata,lenth);

编译成功的

以上就是关于单片机 用c语言编写 modbus rtu 通讯怎么写啊 主要是crc 校验部分不知道怎么写 怎么把一窜字符进行CRC计算全部的内容,包括:单片机 用c语言编写 modbus rtu 通讯怎么写啊 主要是crc 校验部分不知道怎么写 怎么把一窜字符进行CRC计算、易语言CRC16效验程序、CRC16校验码查表法的原理是什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9700585.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存