打印
[DSP编程]

关于CRC-16检验问题

[复制链接]
2013|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
关于CRC校验困惑已久,对于CRC检验的原理,很容易明白,但是对于它的实现方法,尤其是软件实现方法感到很困惑,我看网上对于CRC-16校验软件编程实现步骤最多的一段描述是这样的:

1.预置1个16位的寄存器(下称CRC寄存器),初试化其内容为十六进制数0xFFFF;
2.把第一个待计算的数据即通讯信息帧的首字节与CRC寄存器的低8位相异或,把结果放回CRC寄存器的低八位;
3.把CRC寄存器的内容右移一位用0填补最高位即进行逻辑移位处理并检查右移后的移出位;
4.如果移出位为0重复第3步即再次右移一位,如果移出位为1则CRC寄存器与CRC生成多项式0xA001(1010 0000 0000 0001)进行异或运算,结果放回CRC寄存器;
5.重复步骤3和4,直到右移8次,对整个8位数据全部进行同样处理;
6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
7.将该通讯信息帧所有字节按上述步骤计算完成后,最后得到的CRC寄存器的内容即为CRC校验码,将其附着在原通讯信息帧后进行传输即可。如果用于Modbus协议设备则还需交换高低8位,非Modbus协议设备可以不必交换。接收方依同样方法进行计算,只是计算的内容不要包括最后两个字节,然后比较生成的CRC校验码和数据帧中的是否相同即可。如果发送方交换CRC校验码的高低8位,则接收方可以计算包括交换后的CRC码在内的整个数据帧,传输正确的话结果恒为0x0000。
但是我有几个问题不懂:
1.为什么预置一个全为1的寄存器,然后先跟数据位进行异或?
2.判断移出的位为1,剩下的和生成多项式异或? 移出位为0,则继续移位?
3.这是对CRC校验基本原理做了怎样的变换啊? 原理中的把数据后面补r个零,然后除以生成多项式,得到的余数就是CRC校验码,但是上面的步骤中到底是如何跟这个原理匹配的?

相关帖子

沙发
zhangmangui| | 2013-9-8 15:12 | 只看该作者
你是要代码吗   我做过这方面的东西   也写好了软件   
可以直接计算   代码在周一上班可以发给你  
到时候记得@我就可以啦

使用特权

评论回复
板凳
zhangmangui| | 2013-9-8 15:17 | 只看该作者
为什么还要分高8位和低8位 呢   如果用VB等语言写   由于变量类型的缘故可能要分高低8位
C语言的话则不需要分的   直接计算就可以啦
预制全为1的初始值代表着最后计算得到的CRC值是否需要取反
你可以看看它的理论计算原理   其实就是异或

使用特权

评论回复
地板
HD21425|  楼主 | 2013-9-8 19:06 | 只看该作者
zhangmangui 发表于 2013-9-8 15:17
为什么还要分高8位和低8位 呢   如果用VB等语言写   由于变量类型的缘故可能要分高低8位
C语言的话则不需要 ...

理论计算公式很简单,但是程序实现的方法感觉跟原理对不上啊,程序里为什么没有左移16位,然后用0代替,新的数据再除以生成多项式呢? 我上面说的那个程序步骤对原理做了什么变换呢?
我现在如果传输一个数据 0000 0001,左移16位换成0得到:0000 0001 0000 0000 0000 0000 ,然后除以1000 0000 0000 0101(8005),得到玉树1010,但是我用CRC16校验计算器得到的是807E,这不一致啊,另外我的程序调试结果也是807E,到底原理和程序实现怎么统一的? 想了好久了,没想通。
谢谢版主,费神了!

使用特权

评论回复
5
zhangmangui| | 2013-9-8 21:19 | 只看该作者
HD21425 发表于 2013-9-8 19:06
理论计算公式很简单,但是程序实现的方法感觉跟原理对不上啊,程序里为什么没有左移16位,然后用0代替, ...

时间过去久了  有些忘了   但是和理论是一致的   就是异或和原理中的计算对比

使用特权

评论回复
6
HD21425|  楼主 | 2013-9-9 08:03 | 只看该作者
zhangmangui 发表于 2013-9-8 21:19
时间过去久了  有些忘了   但是和理论是一致的   就是异或和原理中的计算对比 ...

好吧,我再想想吧

使用特权

评论回复
7
HD21425|  楼主 | 2013-9-10 07:52 | 只看该作者
依旧搞不懂啊! 感觉原理很简单,程序实现也很简单,就是两者对应不起来,求论坛哪位高手能指点一下?

使用特权

评论回复
8
zhangmangui| | 2013-9-10 09:57 | 只看该作者
HD21425 发表于 2013-9-10 07:52
依旧搞不懂啊! 感觉原理很简单,程序实现也很简单,就是两者对应不起来,求论坛哪位高手能指点一下? ...


看看  这样理解  就是异或运算

使用特权

评论回复
9
HD21425|  楼主 | 2013-9-18 07:46 | 只看该作者

使用特权

评论回复
10
zhangmangui| | 2013-9-20 12:29 | 只看该作者
HD21425 发表于 2013-9-18 07:46

还没搞定?

使用特权

评论回复
11
HD21425|  楼主 | 2013-9-25 10:00 | 只看该作者
没有

使用特权

评论回复
12
HD21425|  楼主 | 2013-9-25 10:00 | 只看该作者
zhangmangui 发表于 2013-9-20 12:29
还没搞定?

没有

使用特权

评论回复
13
HD21425|  楼主 | 2013-10-9 09:38 | 只看该作者
这是逼我结贴啊!

使用特权

评论回复
14
aresc| | 2013-10-10 19:44 | 只看该作者
1. crc寄存器的初始值可以是任意的,只要发送端和接收端按同一个初始值计算就可以。初始值如果为全0,当校验的数据由很多0开始,那crc寄存器的值在计算这些起始的0数据时总是保持不变为0。为避免上面的情形,选择0xffff即全1做为初始值。
2/3. 这个原理是在你理解的CRC算法上按镜像重新设计的CRC算法,据说是和硬件相关的。按这种算法计算出来的16位CRC结果,比如为0x3456,那添加到校验数据块的结尾时要交换高低字节,即变成0x5634,当对数据块+0x5634进行crc校验,得出的crc值为0.你可以在google上搜索一下reflect crc和reverse crc. 有原理介绍的。

使用特权

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

本版积分规则

6

主题

69

帖子

0

粉丝