首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

简单实用的单片机CRC快速算法(转)(2)

简单实用的单片机CRC快速算法(转)(2)

其中,Qa00是整数,与余式无关;而Ra00和Tbc都是二字节序列,因而,它们的和(模2加法,即异或运算)仍然是二字节序列(二进制16位,小于生成多项式的17位),因此,它就是 Tabc的余式Rabc,即

(9)

这说明,可以把三字节序列Tabc=[ a b c ]的运算分解成两个步骤来进行,如图2所示。

1. 通过查余式表(表1),读取Ta00=[a 0 0 ]的余式Ra00=[ ha00 la00 ];

2. 将Ra00与[ b c ]进行异或运算,从而得到[ a b c ]的余式Rabc=[ habc labc ],即habc=ha00 Å b,labc=la00 Å c。

由于[a 0 0 ]中只有一个字节不为零,因此,[a 0 0 ]余式表仅需要256个单元,即占用512个字节。



图2 三字节序列[ a b c ]的计算办法

4 适用于51系列等单片机的算法

前面所述的办法可以直接用于51系列等单片机,因为512字节的余式表对它们的程序存储容量来说是完全不成问题的。

计算直接通过上述的递推过程来进行,每一次递推都是对一个三字节序列进行的计算:第一次是[ m1 m2 m3 ],结果是[ h3 l3 ];第二次是[ h3 l3 m4 ],结果是[ h4 l4 ];......,第i次是[ hi+1 li+1 mi+2 ],结果是[ hi+2 li+2 ];......;最后是[ hk+1 lk+1 mk+2 ],最终结果是[ h l ]。如果有k个数据字节,则递推k次。下面给出一个三字节序列计算子程序,供每一次递推运算时调用。注意,在第一次被调用之前,先将m1、 m2和m3分别存入R0、R1和R2中(子程序返回时,计算结果将存放在R0和R1中)。从第二次调用时开始,每次在调用之前只需先将参与本次运算的字节存入R2即可(第二次是m4,第三次是m5,...,第i次是mi+2,...)。当最后一次调用返回后,R0和R1分别存放的就是最终结果h和l 。

CRC MOV  DPH, #table ; 指向余式表下半区
MOV DPL, R0 ; 指向对应单元
CLR A  ;  
MOVC A, @A+DPTR  ; 读余式的高字节
XRL A, R1 ; 计算余式的高字节
MOV  R0, A ; 存入R0
INC DPH ; 指向余式表上半区
CLR A ;  
MOVC A, @A+DPTR ; 读余式的低字节
XRL A, R2 ; 计算余式的低字节
MOV R1, A ; 存入R1
RET   

这一子程序只有12条指令,因此十分简捷,而且只占用16个机器周期,也就是说,相当于计算每一个字节只需16个机器周期即可完成,这将比传统的软件算法快十几倍。

 
  


表1 [ a 0 0 ] 余式表

a
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F


0000
1021
2042
3063
4084
50A5
60C6
70E7
8108
9129
A14A
B16B
C18C
D1AD
E1CE
F1EF


1231
0210
3273
2252
52B5
4294
72F7
62D6
9339
8318
B37B
A35A
D3BD
C39C
F3FF
E3DE


2462
3443
0420
1401
64E6
74C7
44A4
5485
A56A
B54B
8528
9509
E5EE
F5CF
C5AC
D58D


3653
2672
1611
0630
76D7
66F6
5695
46B4
B75B
A77A
9719
8738
F7DF
E7FE
D79D
C7BC


48C4
58E5
6886
78A7
0840
1861
2802
3823
C9CC
D9ED
E98E
F9AF
8948
9969
A90A
B92B


5AF5
4AD4
7AB7
6A96
1A71
0A50
3A33
2A12
DBFD
CBDC
FBBF
EB9E
9B79
8B58
BB3B
AB1A
继承事业,薪火相传
返回列表