理解和运用maxim ibutton产品中的循环冗余校验(crc) - maxim.htm

来自「CRC的使用」· HTM 代码 · 共 908 行 · 第 1/5 页

HTM
908
字号
	233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
	116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53);

Begin
	CRC := Table[CRC xor X];
End;
</PRE><SPAN class=btext>表1. 查表方式计算DOW CRC</SPAN> 

                                <TABLE cellSpacing=1 cellPadding=2 border=0>
                                <TBODY>
                                <TR class=tablehead>
                                <TD class=tablehead>Current CRC Value (= Current 
                                Table Index)</TD>
                                <TD class=tablehead>Input Data</TD>
                                <TD class=tablehead>New Index (= Current CRC xor 
                                Input Data)</TD>
                                <TD class=tablehead>Table (New Index) (= New CRC 
                                Value)</TD></TR>
                                <TR class=tablebody>
                                <TD>0000 0000 = 00 Hex</TD>
                                <TD>0000 0010 = 02 Hex</TD>
                                <TD>(00 H xor 02 H) = 02 Hex = 2 Dec</TD>
                                <TD>Table[2]= 1011 1100 = BC Hex = 188 
                                Dec</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>1011 1100 = BC Hex</TD>
                                <TD>0001 1100 = 1C Hex</TD>
                                <TD>(BC H xor 1C H) = A0 Hex = 160 Dec</TD>
                                <TD>Table[160]= 1010 1111 = AF Hex = 175 
                                Dec</TD></TR>
                                <TR class=tablebody>
                                <TD>1010 1111 = AF Hex</TD>
                                <TD>1011 1000 = B8 Hex</TD>
                                <TD>(AF H xor B8 H) = 17 Hex = 23 Dec</TD>
                                <TD>Table[23]= 0001 1110 = 1E Hex = 30 
                                Dec</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>0001 1110 = 1E Hex</TD>
                                <TD>0000 0001 = 01 Hex</TD>
                                <TD>(1E H xor 01 H) = 1 F Hex = 31 Dec</TD>
                                <TD>Table[31]= 1101 110 = DC Hex = 220 
                                Dec</TD></TR>
                                <TR class=tablebody>
                                <TD>1101 1100 = DC Hex</TD>
                                <TD>0000 0000 = 00 Hex</TD>
                                <TD>(DC H xor 00 H) = DC Hex = 220 Dec</TD>
                                <TD>Table[220]= 1111 0100 = F4 Hex = 244 
                                Dec</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>11110100 = F4 Hex</TD>
                                <TD>0000 0000 = 00 Hex</TD>
                                <TD>(F4 H xor 00 H) = F4 Hex = 244 Dec</TD>
                                <TD>Table [244]= 0001 0101 = 15 Hex = 21 
                                Dec</TD></TR>
                                <TR class=tablebody>
                                <TD>0001 0101 = 15 Hex</TD>
                                <TD>0000 0000 = 00 Hex</TD>
                                <TD>(15 H xor 00 H) = 15 Hex = 21 Dec</TD>
                                <TD>Table[21]= 1010 0010 = A2 Hex = 162 
                                Dec</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>1010 0010 = A2 Hex</TD>
                                <TD>10100010 = A2 Hex</TD>
                                <TD>(A2 H xor A2 H) = Hex = 0 Dec</TD>
                                <TD>Table[0]=0000 0000 = 00 Hex = 0 
                                Dec</TD></TR></TBODY></TABLE><BR>
                                <H3>带有CRC寄存器1的补码CRC寄存器</H3><SPAN class=btext>表2. 
                                CRC寄存器值输入</SPAN> 
                                <TABLE cellSpacing=1 cellPadding=2 border=0>
                                <TBODY>
                                <TR class=tablebody>
                                <TD>X<SUB>0</SUB></TD>
                                <TD>X<SUB>1</SUB></TD>
                                <TD>X<SUB>2</SUB></TD>
                                <TD>X<SUB>3</SUB></TD>
                                <TD>X<SUB>4</SUB></TD>
                                <TD>X<SUB>5</SUB></TD>
                                <TD>X<SUB>6</SUB></TD>
                                <TD>X<SUB>7</SUB></TD>
                                <TD>X<SUB>7</SUB>*</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>1</TD>
                                <TD>X<SUB>0</SUB></TD>
                                <TD>X<SUB>1</SUB></TD>
                                <TD>X<SUB>2</SUB></TD>
                                <TD>X<SUB>3</SUB>*</TD>
                                <TD>X<SUB>4</SUB>*</TD>
                                <TD>X<SUB>5</SUB></TD>
                                <TD>X<SUB>6</SUB></TD>
                                <TD>X<SUB>6</SUB>*</TD></TR>
                                <TR class=tablebody>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>X<SUB>0</SUB></TD>
                                <TD>X<SUB>1</SUB></TD>
                                <TD>X<SUB>2</SUB>*</TD>
                                <TD>X<SUB>3</SUB></TD>
                                <TD>X<SUB>4</SUB>*</TD>
                                <TD>X<SUB>5</SUB></TD>
                                <TD>X<SUB>5</SUB>*</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>X<SUB>0</SUB></TD>
                                <TD>X<SUB>1</SUB>*</TD>
                                <TD>X<SUB>2</SUB>*</TD>
                                <TD>X<SUB>3</SUB></TD>
                                <TD>X<SUB>4</SUB>*</TD>
                                <TD>X<SUB>4</SUB>*</TD></TR>
                                <TR class=tablebody>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>X<SUB>0</SUB></TD>
                                <TD>X<SUB>1</SUB>*</TD>
                                <TD>X<SUB>2</SUB></TD>
                                <TD>X<SUB>3</SUB></TD>
                                <TD>X<SUB>3</SUB>*</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>X<SUB>0</SUB>*</TD>
                                <TD>X<SUB>1</SUB>*</TD>
                                <TD>X<SUB>2</SUB></TD>
                                <TD>X<SUB>2</SUB>*</TD></TR>
                                <TR class=tablebody>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>X<SUB>0</SUB>*</TD>
                                <TD>X<SUB>1</SUB>*</TD>
                                <TD>X<SUB>1</SUB>*</TD></TR>
                                <TR class=tablebodyalt>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>X<SUB>0</SUB>*</TD>
                                <TD>X<SUB>0</SUB>*</TD></TR>
                                <TR class=tablebody>
                                <TD>0</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>0</TD>
                                <TD>1</TD>
                                <TD>Final CRC Value = 35 Hex, 53 
                                Decimal</TD></TR></TBODY></TABLE><BR><SPAN 
                                class=small>注释: X<SUB>i</SUB>* = 
                                X<SUB>i</SUB>的反码</SPAN><BR><BR>
                                <H2><U>i</U>Button 
                                RAM中CRC-16的算法</H2>如前所述,一些<U>i</U>Button器件除了内部唯一的8字节ROM码,还有RAM存储器。与内部的8字节ROM码相比,RAM中存储的数据量要大得多,因此Maxim推荐使用16位CRC码而不是ROM所使用的8位DOW 
                                CRC,以确保数据的完整性。这种特殊的16位CRC通常称为CRC-16。<B>图3</B>给出了这种16位CRC的移位寄存器的硬件实现图和相应的多项表达式,图中的移位寄存器有16阶,其表达式也有16次幂项。如前所述,<U>i</U>Button器件自身并不产生CRC码,而是由主机生成16位CRC码并将其附加在实际数据之后。由于<U>i</U>Button的“通信通道”,如两个金属接触面,存在不确定性,数据传输可能会出现一些错误,分为三类:第一,短暂的连接中断引起的数据传输中小部分数据位出错,CRC-16可检测出这类错误;第二类错误是完全脱离接触引起的,如:当<U>i</U>Button器件快速移离读写头时。<BR><BR>将导致后续部分的读入数据为逻辑1,这是因为未连接<U>i</U>Button器件时,主机将解释所有的接收数据为1。 
                                CRC-16在大多数情况下可以检测出这类错误。第三类错误是由读写头短路引起的,这可能因为<U>i</U>Button器件没有正确插入或<U>i</U>Button器件在阅读器内大幅度翘起导致的。读写头短路会使主机把数据全读为0,此时采用CRC进行校验时,就会出现问题。由于确认数据是否有效的方法是判断主机在读取数据和附加的CRC之后,计算出的CRC码是否全为0000H 
                                (采用16位CRC)。当阅读器短路时,读到的数据和CRC值全部为0,此时读操作已经出错,但由主机计算出的CRC值将错误地指示该读操作是有效的。为了避免这种情况的发生,Maxim推荐将CRC-16反码(CRC-16*)随同数据一起写入RAM。当采用无补码的CRC-16时,<U>i</U>Button的数据验证过程与DOW 
                                CRC相似,即,主机把CRC寄存器初始化成0000H,然后从<U>i</U>Button读取全部数据和存储的CRC-16,则最终计算出来的结果应为0000H。如果采用CRC-16*,在<U>i</U>Button中保存的就是CRC-16的反码和数据。进行CRC校验时,主机同样把CRC寄存器初始化成0H,然后从<U>i</U>Button读取数据和CRC-16*,如果操作没有错误的话,最后的结果应该是B001H。这样大大地提高了系统可靠性,读写头短路造成的错误就不会被漏检。至于为什么CRC-16具有这些特性,可通过与之相似的DOW 
                                CRC的分析(见图3和图5)来解释。在理论上16位CRC的操作与此前介绍的8位CRC完全相同,只是由于采用的是16的CRC,性能有所改善。对于CRC-16函数,可以检测到以下几类错误:<BR><BR>
                                <OL>
                                <LI>任何数据记录中的奇数个错误; 
                                <LI>任何数据记录中的双位错误; 
                                <LI>任何16位区间中的位错误(1至16位错误); 
                                <LI>绝大多数长字符串的错误。 </LI></OL><IMG 
                                alt="图3. CRC-16硬件实现及其多项式表示" 
                                src="理解和运用Maxim iButton产品中的循环冗余校验(CRC) - Maxim.files/542Fig04.gif"><BR><I>图3. 
                                CRC-16硬件实现及其多项式表示</I><BR><BR>图3给出了CRC-16函数的硬件实现图,例4则列出了与其硬件相对应的软件实现方案,采用位操作计算CRC-16值。之前很少有高效的查询表软件解决方案,8位DOW 
                                CRC查询表的基础概念也同样适用于CRC-16,只需对8位的程序稍加改动即可。但是,如果仍然采用DOW 
                                CRC实现方法的话,要把CRC-16全部16位结果全部放进一个查询表,则表中就会有2<SUP>16</SUP>也就是65536个记录(占用的空间将会很大)。与DOW 
                                CRC不同的实现方法如例5所示,图中采用两个256位表来计算和存储16位CRC值,其中一个表包含CRC的高8位,另一个存放低8位。任何一个16位CRC都可以分为代表高8位的Current_CRC16_Hi和代表低8位的Current_CRC16_Lo两部分。对于任何一个输入字节,在高阶字节表中决定新的CRC值高阶字节(New_CRC16_Hi)的索引计算公式如下:<BR><BR>New_CRC16_Hi 
                                = CRC16_Tabhi[I], I = 0至255; 这里: I = 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?