;
;
; CRC16_MODBUS 2014-12-25
;
; 基于MODBUS 协议的CRC16程序
; 多项式码: A001= 1010 0000 0000 0001
; 算法:
;1) 设置1个16 位的寄存器(高字节和低字节)称此寄存器为 CRC寄存器。填充为: 0FFFFH
;2) 把(待处理的)第一字节数据与 CRC寄存器的低字节相异或, 结果放于 CRC寄存器。
;3) 把 CRC 寄存器的内容右移一位,最高位(Bit15)填0, 移出位(Bit0)在标志寄存器的C内。
;4) 如果移出位为 0, 重复第 3 步 ( 再次右移一位); 如果移出位为 1, CRC 寄存器与多项式A001 ( 1010 0000 0000 0001) 进行异或。
;5) 重复步骤 3 和步骤 4, 直到右移 8 次,这样一个字节数据处理结束。
;6) 重复步骤 2 到步骤 5, 进行下一个字节的处理。
;7) 将所有字节数据按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换。
;8) 最后得到的 CRC寄存器内容即为 CRC码。
;
;
; 使用资源:
;
; ###########################################################
;
CRC16_RAM EQU 52H ; CRC使用的内存开始地址,
CRC_H DATA CRC16_RAM+0 ; CRC寄存器高位
CRC_L DATA CRC16_RAM+1 ; CRC寄存器低位
CRC_CNT DATA CRC16_RAM+2 ; 进行CRC运算的数据字节数
CRC_DATA DATA CRC16_RAM+4 ; 进行CRC校验的数据缓冲区开始地址
; ###########################################################
ORG 0000
JMP START
;******************************************************
;---------------|-------|---------------|--------------
START:
;******************************************************
;---------------|-------|---------------|--------------
; 一个实例, 待处理数据为: 01H,06H,00H,03H,00H,04H
MOV CRC_DATA+0, #01 ; 待处理数据首字节
MOV CRC_DATA+1, #06 ; 待处理数据第二字节
MOV CRC_DATA+2, #00 ; 类推
MOV CRC_DATA+3, #03
MOV CRC_DATA+4, #00
MOV CRC_DATA+5, #04
MOV CRC_CNT, #6 ; 待处理数据字节数=6
;******************************************************
;---------------|-------|---------------|--------------
main_prog:
MOV R0, #CRC_DATA ; 待处理数据开始地址送R0
CALL CRC16_MODBUS
main_prog_end:
JMP main_prog_end
;******************************************************
; MODBUS 协议的CRC16过程
; 入口:
; R0 = 待处理数据缓冲区地址
; CRC_CNT = 待处理数据字节数
; 出口: CRC_H + CRC_L = 2字节CRC
;---------------|-------|---------------|--------------
CRC16_MODBUS:
; MOV R0, #CRC_DATA ; 待处理数据开始地址送R0
MOV CRC_H, #0FFH ; CRC寄存器置0FFH
MOV CRC_L, #0FFH
;---------------|-------|---------------|--------------
CRC16_MODBUS_2:
MOV A, CRC_L ; CRC寄存器的低字节送到 A
XRL A, @R0 ; CRC寄存器低字节与数据相异或
MOV CRC_L, A ; 结果放回CRC寄存器低字节内
MOV R7, #8 ; 每字节数据位数 = 8
;---------------|-------|---------------|--------------
CRC16_MODBUS_3:
; CRC寄存
器右移一位,高位 bit15置0
; 高字节右移一位,高位置0,低位进入C
MOV A, CRC_H
CLR C
RRC A ; 带进位循环右移一位
MOV CRC_H, A
; 低字节右移一位
MOV A, CRC_L
RRC A
MOV CRC_L, A ; 低字节移除位在C内
;---------------|-------|---------------|--------------
; 判断移除的bit0
CRC16_MODBUS_4:
JNC CRC16_MODBUS_3_END ; C=0, 转移
; bit0=1, CRC寄存器与多项式码: A001 异或
; CRC寄存器高字节与 A0H 异或
MOV A, CRC_H
XRL A, #0A0H
MOV CRC_H, A
; CRC寄存器低字节与 01H 异或
MOV A, CRC_L
XRL A, #01H
MOV CRC_L, A
CRC16_MODBUS_3_END:
DJNZ R7, CRC16_MODBUS_3 ; 右移8次
;---------------|-------|---------------|--------------
; 处理下一个字节
INC R0
DJNZ CRC_CNT, CRC16_MODBUS_2
;---------------|-------|---------------|--------------
; 所有数据处理结束,CRC寄存器高低字节交换
CRC16_MODBUS_7:
MOV A, CRC_L
MOV CRC_L, CRC_H
MOV CRC_H, A
;---------------|-------|---------------|--------------
RET
; ###########################################################
END
本文来源:https://www.2haoxitong.net/k/doc/4a9d4358f111f18583d05a96.html