你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
查看全部评分
举报
SquallBest 发表于 2016-11-11 12:16 * l4 g! `% c2 j- y1 J6 ?8 D3 tcrc校验有两种方式的,一种是计算法,还有一种是恶心的查表法。
jtc_88 发表于 2016-11-10 16:54 2 q0 L8 }) ?# Y K/*modbus CRC16 0 U6 q, C& n8 a( W- l/ U生成 CRC 的过程为: , i5 q8 c$ d: J6 b% s1. 将一个 16 位寄存器(称作 CRC 寄存器)初始赋值为十六进制 F ...
土司Apple 发表于 2018-5-30 14:42 ! ]6 N" }6 R; Y5 L3 p1 ?+ S8 \1 fCRC的多项式为什么是同0xA001异或而不是0x8005呢??
意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。关注该话题即可发布文章!
生成 CRC 的过程为:
1. 将一个 16 位寄存器(称作 CRC 寄存器)初始赋值为十六进制 FFFF (全 1);' w& X# A) r" n3 q; b8 ?' F' m! A
2. 将报文的第一个字节( 8位)与 16 位 CRC 寄存器的低字节异或,结果置于 CRC 寄存器;( h& Z$ T, e& H5 ?" ]" U7 }0 E
3. 将 CRC 寄存器右移 1位 (向 LSB 方向), MSB 充零,并检测 LSB:. e( [0 b# ]" w* z9 F
4. (如果 LSB(移出来的那一位) 为 0): 重复步骤 3 (另一次移位). (如果 LSB 为 1): 对 CRC 寄存器异或多项式值 0xA001 (1010 0000 0000 0001). 0 J% F6 u2 L Z! d1 j& b4 E1 ^
5. 重复步骤 3 和 4,直到完成 8 次移位操作后,一个字节的处理完毕。
6. 对报文中的下一个字节重复步骤 2 到 5继续此操作,直至所有报文被处理完毕。
7. CRC 寄存器中的最终值为 CRC 值. 8. 当放置 CRC 值于报文时,注意高低字节必须交换。0 M O4 k6 j- k+ z/ g9 k
*/! e5 U8 E- r* d( w4 M* R1 h5 A/ w
unsigned int CRC16 ( uchar *arr_buff, uchar len)
{
uint crc=0xFFFF;' @, d& ?' S' A+ g+ e* I
uchar i, j, Data;
for ( j=0; j < len;j++ )
{
# h+ j# J- r, u& ^0 O7 B: A5 c
crc=crc ^*arr_buff++; t* t- A" {$ v! z. B
for ( i=0; i<8; i++)" e3 h8 j$ b9 q- R& E* w
{
: i/ s6 Y/ ^, M1 j. i; p
if( ( crc&0x0001) >0)- P% i4 C! U# G" z4 S
- Q, A K* a) Q9 |+ w
{
crc=crc>>1;
3 S7 J- H/ w3 i& @$ b2 y5 s+ m* t
crc=crc^ 0xa001;! P: d3 J# J/ Z# {, H
}
else& I+ `2 l* L( \9 x
crc=crc>>1;( Q6 k X5 o' _5 Y
}. l+ {; f, u$ t/ ^2 n
}) M Y( Q2 W; a8 g5 Q
return ( crc);
! c e! E# a1 b- H
}: A' d; m0 N* q, S* ]
我用的就是恶心的查表法,
3 E* P8 E% @* G8 N& w6 e
不过,查表比较计算的要快,我倾向于查表$ D4 k! S# n9 E6 K
& i4 U1 X: W2 v5 q
另外,封装起来调用就省事儿一些,感觉CRC8基本不用,所以就把CRC32和CRC16一起封装了
顶,有理论,有代码
你看他用的是右移,一般我们用0x8005实现的时候,用的都是左移。
0x A001 =1010 0000 0000 0001B! f; [2 ?/ K, ]+ N4 I& w$ x
反过来写就是:1000 0000 0000 0101B=0x8005* G4 }) q' n8 [! [8 n6 e% J/ G