📄 crc16.asm
字号:
CRCHi EQU 4FH ;
CRCLo EQU 4EH ;储存CRC校验码的高字节
CRC_DATA_BUF EQU 0A0H;...47H;校验数据缓冲区
TEST_DATA EQU 0B0H;
CRC1 EQU 4EH ;
CRC2 EQU 4FH ;
Data_lenth EQU 4DH ; 要校验数据的长度
Lrc equ 33H ;
;============================================================
ORG 0000H
AJMP MAIN
;============================================================
;快速CRC校验
;A: 新输入的数据一个字节(76543210)
;(CRCHi,CRCLo):原先CRC校验数据(yxwu tsrq,hgfe dcba)
;经过校验运算以后的新的校验码还是在
;(CRCHi,CRCLo):(YXWU TRSQ,HGFE DCBA)
;计算公式:设ab=a xor b
;P:= abcdefgh01234567
;then: Y=P, X=Ph7,W=gh67,U=fg56,T=ef45,R=de34,S=cd23,Q=bc12
; H=ab01y,G=xa0,F=w, E=u, D=t, C=s, B=r, A=qP
;============================================================
CRC16_CAL: XRL A,CRCLo ;A:=(h7 g6 f5 e4 d3 c2 b1 a0)
MOV CRCLo,CRCHi ;CRCLo:=(yxwu tsrq)
MOV CRCHi,A ;CRCHi:=(h7 g6 f5 e4 d3 c2 b1 a0)
MOV C,P ;P:=abcdefgh01234567(psw.0)校验奇偶位
JNC CRC16_CAL0 ;if P=0,说明A=qP=0 xor q=q
XRL CRCLo,#00000001B ;else A=qP=1 xor q
CRC16_CAL0:RRC A ;右移一次,则 A:=(P h7 g6 f5 e4 d3 c2 b1) 且C:=a0
JNC CRC16_CAL1 ;因为 G=xa0=x xor a0
XRL CRCLo,#01000000B;if a0=0,then G=x;else G:=1 xor x
CRC16_CAL1:MOV C,ACC.7 ;C:=Acc.7:=P
XRL A,CRCHi ;A:=(Ph7 h7g6 g6f5 f5e4 e4d3 d3c2 c2b1 b1a0)
RRC A ;右移一次后 A:=(P Ph7 h7g6 g6f5 f5e4 e4d3 d3c2 c2b1 )且C:=b1a0
MOV CRCHi,A ;校验高字节已经得到
JNC CRC16_CALQ ;因为 H=ab01y:=b1a0 xor y,所以 当 C:=b1a0:=0,H=y
XRL CRCLo,#10000000B ;否则 H:=1 xor y
CRC16_CALQ:RET
;=============================================================
;CRC校验码生成程序
; @R0 是存放数据的首地址
; R6 数据长度
; CRC_DATA_BUF:存放数据的地址
; 生成的校验位在 CRC2(H) CRC1(L)
;程序说明:发送方在发送之前先算好N个数据的校验码,然后直接跟在要发送的数据后面
; 接收方总共接受(N+2)个数据,然后计算校验码,
; 如果接收到的校验码为:0000H;说明接收正确
; 校验一组8位的数据要228uS
; 6 170uS
; 4 114uS
; 校验一次只要用:27uS
;------------------------------------------------------------
GetD_CRC16:MOV R0,#CRC_DATA_BUF
MOV R6,Data_lenth
Get_CRC16: MOV CRC1,#0
MOV CRC2,#0
Get_CRC16L:MOV A,@R0
LCALL CRC16_CAL
INC R0
DJNZ R6,Get_CRC16L
;将校验码加入数据最后
MOV @R0,CRC1
INC R0
MOV @R0,CRC2
RET
;-------------------------------------------------------------
CHECK_CRC: MOV R0,#CRC_DATA_BUF
MOV R6,Data_lenth
ACALL Get_CRC16
RET
;-------------------------------------------------------------
Data_to_CRC:MOV R0,#TEST_DATA
MOV R1,#CRC_DATA_BUF
MOV B,Data_lenth
Data_To_CRC0:MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ B,Data_To_CRC0
MOV R0,#TEST_DATA
MOV R1,#CRC_DATA_BUF
MOV B,Data_lenth
RET
;=============================================================
DATA_BUF_INIT:
MOV R0,#TEST_DATA
MOV @R0,#1H
INC R0
MOV @R0,#11H
INC R0
MOV @R0,#11H
INC R0
MOV @R0,#11H;1
INC R0
MOV @R0,#11H
INC R0
MOV @R0,#11H;1
;MOV CRC_DATA_BUF+4,#55H;1
;MOV CRC_DATA_BUF+5,#66H;71
;MOV CRC_DATA_BUF+6,#77H;61
;MOV CRC_DATA_BUF+7,#88H;61
RET
;-------------------------------------------------------------
;================================================
CLR_RAM: ;清理内存
POP DPH
POP DPL
MOV R0,#0FFH
CLRGO: MOV @R0,#00H
DJNZ R0,CLRGO
MOV @R0,#00H
CLR A
JMP @A+DPTR
;-------------------------------------------------
;===========MAIN==============================================
MAIN: MOV SP,#7
ACALL CLR_RAM
ACALL DATA_BUF_INIT
MOV Data_lenth,#1
LCALL Data_to_CRC
ACALL GetD_CRC16
MOV Data_lenth,#3
ACALL CHECK_CRC
SJMP $
;=============================================================
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -