打印

大家一般情况下用哪种CRC校验多项式?

[复制链接]
楼主: bhsdlmj
手机看帖
扫描二维码
随时随地手机跟帖
21
checksum啥意思???:L
bhsdlmj 发表于 2009-10-10 09:15


和校验

使用特权

评论回复
22
ZRL700424| | 2009-10-10 09:56 | 只看该作者
得用手算一算才好啊!!!
bhsdlmj 发表于 2009-10-10 09:15


嗯,如果会用笔算了,说明你大概明白CRC的原理了

使用特权

评论回复
23
bhsdlmj|  楼主 | 2009-10-10 09:57 | 只看该作者
这个是哪门子除法啊 看不懂啊?谁指点一下!??

用一个CRC-4 编码的例子来说明CRC 的编码过程。
设待发送的数据 t(x)为12 位的二进制数据100100011100;CRC-4 的生成多项式为g(x)
= x4 + x +1,阶数r为4,即10011。首先在t(x)的末尾添加4 个0 构成x4t(x),数据块就成了
1001000111000000。然后用g(x)去除x4t(x),不用管商是多少,只需要求得余数y(x)。以下
给出了除法过程。

被除数1 001000111000000,除数为1 0011,那么余数为100111000000。

这是咋算的?余数我算了是1111啊!!:funk:

使用特权

评论回复
24
冷漠| | 2009-10-10 10:18 | 只看该作者
哈哈!真逗,余数9C0H 比除数13H 还大?当然不对。小学除法基本概念说不可能,因为可以接着除下去,直到余数小于除数为止。

使用特权

评论回复
25
冷漠| | 2009-10-10 10:56 | 只看该作者
都没算对。被除数=91CH,除数=13H,

91C0H 模二除 13H =884H ......余数= 0CH

23楼的所谓例子:余数=9C0H才计算了第一步,接着计算下去:
9C0H 模二除 13H =84H  余数同样为  0CH

使用特权

评论回复
26
bhsdlmj|  楼主 | 2009-10-10 11:38 | 只看该作者
模二的 “模”是啥意思?

使用特权

评论回复
27
bhsdlmj|  楼主 | 2009-10-10 12:02 | 只看该作者
都没算对。被除数=91CH,除数=13H,

91C0H 模二除 13H =884H ......余数= 0CH

23楼的所谓例子:余数=9C0H才计算了第一步,接着计算下去:
9C0H 模二除 13H =84H  余数同样为  0CH ...
冷漠 发表于 2009-10-10 10:56


模二的 “模”是啥意思?

使用特权

评论回复
28
bhsdlmj|  楼主 | 2009-10-10 12:07 | 只看该作者
都没算对。被除数=91CH,除数=13H,

91C0H 模二除 13H =884H ......余数= 0CH

23楼的所谓例子:余数=9C0H才计算了第一步,接着计算下去:
9C0H 模二除 13H =84H  余数同样为  0CH ...
冷漠 发表于 2009-10-10 10:56


9C0H 模二除 13H????这是啥意思???

使用特权

评论回复
29
冷漠| | 2009-10-10 12:41 | 只看该作者
本帖最后由 冷漠 于 2009-10-10 12:53 编辑

咦 ?这还看不懂?
被除数1001000111000000是不是等于91C0H 或者0x91C0 ?
除数  1 0011是不是等于13H / 0x13 ?

那么无论你手算还是编制程序计算,是不是按照模二除法91C0H /13H 进行?

是不是不知道什么叫模二除法 ?那什么叫CRC ?!

呵呵,真正通信技术中用到的实用CRC校验技术是由电路(移位寄存器+异或门)硬件实现的,离我们最近、最典型的例子就是CAN通信控制器芯片:
  CAN规程的G(x)=X14+X10+X8+X7+X4+X3+1.
  即除数G = 0100 0101 1001 1001 = 45999 H
还有以太网卡内部的CRC电路,它的G(X)=X32+.....

根本不用用户程序员知道内部CRC具体,更不需要用户去计算。

查查冷漠以前的贴子,“等你计算完CRC,MAC上的数据——黄花菜都凉啦。”

使用特权

评论回复
30
bhsdlmj|  楼主 | 2009-10-10 13:05 | 只看该作者
91C0H /13H?????

我用计算器算的是  91C0H 除以 13H  得7ABH 余数为0FH

使用特权

评论回复
31
hab2000| | 2009-10-10 13:24 | 只看该作者
CRC太多了,不同的多项式,算法稍有不同,首先要从电路原理上弄明白,什么变化都没关系。常用的8位CRC多项式:CRC=X^8+X^5+X^4+1 电路如图1

不久前我还遇到CRC=X^8+X^2+X^1+1的多项式
你要画出其等效电路,基本上就明白了。

至于12位、16位、32位算法相似。

crc85410.GIF (5.04 KB )

crc85410.GIF

使用特权

评论回复
32
bhsdlmj|  楼主 | 2009-10-10 14:09 | 只看该作者
模2除法! 恩 有点懂了! 继续 还有很多别的不懂得地方

使用特权

评论回复
33
冷漠| | 2009-10-10 14:19 | 只看该作者
能够计算CRC的计算器还没发明出来呢。

举个例子:CRC运算中采用的是模二运算系统,不是二进制运算(计算器系统):
  3(模二)加 7=4 ;也就是3和7的模二和(异或运算)是4.
呵呵,打不出异或符号,用⊙代替吧。即3⊙7=4;
你用计算器算3+7=?

例2:8⊙C=4 ;A⊙3=9 ;F⊙8=7 ;......计算器算?
例3:0x13 模二乘 7 = 0x79  ;
请计算一下10011 X(模二乘) 111 = 111 1001  ;肯定对的。
计算器算?0x13 X 7 = 0x85. 那是二进制系统,跟CRC是两回事。

使用特权

评论回复
34
bhsdlmj|  楼主 | 2009-10-10 14:26 | 只看该作者
冷漠,你很热情啊!!多谢!!

春阳说:https://bbs.21ic.com/viewthread.php?tid=18082&highlight=CRC


我按照他的方法写的,不知道对不对???

/*----------------------
    计算校验值
------------------------*/
INT16U generateValueCRC16(INT8U *ptr, INT16U count)
{
        INT8U *i;
        INT8U bitSeqNum;//一个字节的第几位(称做"位序号") (范围7--0)
        INT16U regCRC = 0xFFFF;       

        for (i = ptr; i < (ptr + count); i++) {
                regCRC =  (*ptr) ^ (regCRC & 0x00FF);
                for (bitSeqNum = 0; bitSeqNum < 8; bitSeqNum++) {
                        if (regCRC & 0x0001) { //如果移除位是1
                                regCRC = (regCRC ^ 0xA001);
                        }
                        else {                 //如果移除位是0
                                regCRC = (regCRC >> 1);
                        }
                }
        }
        return(regCRC);
}

使用特权

评论回复
35
bhsdlmj|  楼主 | 2009-10-10 14:43 | 只看该作者
而且是查表的
呵呵

非常同意春阳,首先要搞清楚为什么要搞这么个玩意儿
很多人到最后舍本逐末,都不知道自己要干什么了
wi2c 发表于 2009-10-9 20:28



是有点不知道CRC是干啥的?是不是因为CRC误码率低并且开销相对小啊??:P

使用特权

评论回复
36
bhsdlmj|  楼主 | 2009-10-10 16:22 | 只看该作者
冷漠,你很热情啊!!多谢!!

春阳说:https://bbs.21ic.com/viewthread.php?tid=18082&highlight=CRC


我按照他的方法写的,不知道对不对???

/*----------------------
    计算校验值
--------------------- ...
bhsdlmj 发表于 2009-10-10 14:26


错了 错啦

使用特权

评论回复
37
bhsdlmj|  楼主 | 2009-10-10 17:24 | 只看该作者
chunyang说:
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。
========================================================
如何判断我写的这个对不对呢??
/*----------------------
    计算校验值
------------------------*/
INT16U generateValueCRC16(INT8U *ptr, INT16U count)
{
        INT8U *i;
        INT8U bitSeqNum;//一个字节的第几位(称做"位序号") (范围7--0)
        INT16U regCRC = 0xFFFF;
        bit LSB;       

        for (i = ptr; i < (ptr + count); i++) {
                regCRC =  (*ptr) ^ (regCRC & 0x00FF);
                for (bitSeqNum = 0; bitSeqNum < 8; bitSeqNum++) {
                        LSB = (regCRC & 0x0001);
                        regCRC = (regCRC >> 1);
                        if (LSB) { //如果LSB是1
                                regCRC = (regCRC ^ 0xA001);
                        }

                }
        }
        return(regCRC);
}








晕倒了!!!!
求助啊!!!

使用特权

评论回复
38
冷漠| | 2009-10-10 17:35 | 只看该作者
书上现成的程序或表一大把,还要自己写?即使写出来,也不好验证。

例如:MODBUS的G(X ) 91C0H 的余数是多少?

手算是唯一检验正确的方法。但是一般人手算91C00000/A001,求余数,行吗?

使用特权

评论回复
39
yewuyi| | 2009-10-10 20:11 | 只看该作者
多用CRC8,速度快。。。

使用特权

评论回复
40
冷漠| | 2009-10-10 21:39 | 只看该作者
回37楼,判断自己写的程序对不对,输入几个实际数据算一下就行了:

1、假定发送数据是0x3C54,求CRC余数。
2、随便再取几个:0xc379,0x5a1864.

我笔算一下后贴上结果,对照答案。

使用特权

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

本版积分规则