你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
查看全部评分
举报
SquallBest 发表于 2016-11-11 12:16 & l) Z1 O; W2 I$ K, m$ D" gcrc校验有两种方式的,一种是计算法,还有一种是恶心的查表法。
jtc_88 发表于 2016-11-10 16:54 : r/ F) _ }3 Q! g2 e+ D7 Q, {/*modbus CRC16& H9 D) H, E) y1 {( |- ?/ G 生成 CRC 的过程为: 6 s, S7 I- S9 r1 ]1 q' J 1. 将一个 16 位寄存器(称作 CRC 寄存器)初始赋值为十六进制 F ...
土司Apple 发表于 2018-5-30 14:428 P. [2 z2 a- C2 u: S CRC的多项式为什么是同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:9 p! L3 c' C: r
4. (如果 LSB(移出来的那一位) 为 0): 重复步骤 3 (另一次移位). (如果 LSB 为 1): 对 CRC 寄存器异或多项式值 0xA001 (1010 0000 0000 0001).
5. 重复步骤 3 和 4,直到完成 8 次移位操作后,一个字节的处理完毕。
6. 对报文中的下一个字节重复步骤 2 到 5继续此操作,直至所有报文被处理完毕。
7. CRC 寄存器中的最终值为 CRC 值. 8. 当放置 CRC 值于报文时,注意高低字节必须交换。
*/
unsigned int CRC16 ( uchar *arr_buff, uchar len)( f: R9 ]7 ^; G
{: e- r4 F: o+ u$ R
9 B. c3 R9 Z r
uint crc=0xFFFF;
uchar i, j, Data;7 P6 d4 u7 r3 p2 U/ i4 h
for ( j=0; j < len;j++ )" P9 U4 Y5 J& y# {
{6 v. i) d( x0 W. V
/ x4 ?7 ~6 ~' T
crc=crc ^*arr_buff++;
for ( i=0; i<8; i++)
{
# Z# a5 H8 k+ M4 M9 y. ]
if( ( crc&0x0001) >0)! ] Z9 J% {4 z( A% e% v; h6 _5 ], f
. e% U7 q& E- G; A
{ `2 w) {% {# \1 d0 b1 R
8 T( [6 t/ n [% z( f$ S7 L0 B& ?
crc=crc>>1;
' @8 L& A/ \& H( f/ @2 m3 m& E
crc=crc^ 0xa001;) D( t% v! v( M5 \7 X
}
else+ z8 X; a3 [ A& t
crc=crc>>1; e7 Y" @, T* ^: a8 b
}: S# p5 R& r/ K" P0 G
}: k6 W. p; c/ X& M M
return ( crc);
}0 G: _: ~0 W( O/ G% l: x( g
我用的就是恶心的查表法,
& L8 R& A) P9 |" U( ?
不过,查表比较计算的要快,我倾向于查表$ k u5 t# G& z: M" E: K$ J6 u
另外,封装起来调用就省事儿一些,感觉CRC8基本不用,所以就把CRC32和CRC16一起封装了
顶,有理论,有代码
你看他用的是右移,一般我们用0x8005实现的时候,用的都是左移。4 R F8 W% _1 K" R# t/ F. M! c* ]
0x A001 =1010 0000 0000 0001B
反过来写就是:1000 0000 0000 0101B=0x8005