你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
查看全部评分
举报
SquallBest 发表于 2016-11-11 12:16' \+ h: H- ^/ u$ E! r- s% x- C crc校验有两种方式的,一种是计算法,还有一种是恶心的查表法。
jtc_88 发表于 2016-11-10 16:549 J5 x3 {8 A5 Z5 C /*modbus CRC16 ) P- ~& x' k* {0 |% Z+ R3 B生成 CRC 的过程为: , i, F0 ` G9 [, a) ]4 P1. 将一个 16 位寄存器(称作 CRC 寄存器)初始赋值为十六进制 F ...
土司Apple 发表于 2018-5-30 14:42 $ l* L1 v% N+ BCRC的多项式为什么是同0xA001异或而不是0x8005呢??
意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。关注该话题即可发布文章!
生成 CRC 的过程为:
1. 将一个 16 位寄存器(称作 CRC 寄存器)初始赋值为十六进制 FFFF (全 1);
2. 将报文的第一个字节( 8位)与 16 位 CRC 寄存器的低字节异或,结果置于 CRC 寄存器;
3. 将 CRC 寄存器右移 1位 (向 LSB 方向), MSB 充零,并检测 LSB:
4. (如果 LSB(移出来的那一位) 为 0): 重复步骤 3 (另一次移位). (如果 LSB 为 1): 对 CRC 寄存器异或多项式值 0xA001 (1010 0000 0000 0001). + i% W. @' J0 ?$ j
5. 重复步骤 3 和 4,直到完成 8 次移位操作后,一个字节的处理完毕。 . y- E4 Q6 }" P/ O
6. 对报文中的下一个字节重复步骤 2 到 5继续此操作,直至所有报文被处理完毕。 ; v6 s' g/ c2 E- n F* m& W
7. CRC 寄存器中的最终值为 CRC 值. 8. 当放置 CRC 值于报文时,注意高低字节必须交换。
*/
unsigned int CRC16 ( uchar *arr_buff, uchar len)
{- _9 K( B7 @$ D
uint crc=0xFFFF;: d. }. |; G" ^/ g
uchar i, j, Data;
for ( j=0; j < len;j++ )+ l! i3 b+ ]( o$ E. a
{
crc=crc ^*arr_buff++;
for ( i=0; i<8; i++)6 |0 }" ]( I7 S% P/ w; |4 B
{# I! r- F0 `8 p0 D% J4 \& R/ E* Z
if( ( crc&0x0001) >0)7 K# F/ c. {* s$ c! \
" L! ^; w' Z, R* P( u5 m( Z, i) |
{6 r( b/ k5 q" Y0 r8 i' k' y
# w! N' T5 S5 ^5 w
crc=crc>>1;8 S4 |9 p$ \+ v
crc=crc^ 0xa001;0 h2 L4 s6 R) ?, C P1 }0 M" q
+ w# e. M. t0 J# P' x8 g6 ^
}
else
" h# e5 b2 j8 V' `
crc=crc>>1;
}
}2 p9 X* v! ~4 J) c
return ( crc);
}4 [) e" x: j5 S- I& k
我用的就是恶心的查表法,
不过,查表比较计算的要快,我倾向于查表* R$ C5 o+ _$ D$ R5 O) z# j
3 L: A& V/ Z8 n/ @" l3 D
另外,封装起来调用就省事儿一些,感觉CRC8基本不用,所以就把CRC32和CRC16一起封装了
顶,有理论,有代码
你看他用的是右移,一般我们用0x8005实现的时候,用的都是左移。
0x A001 =1010 0000 0000 0001B
反过来写就是:1000 0000 0000 0101B=0x8005 Q7 I- _$ r& Z/ W8 c