计算法简单实现crc校验_单片机论文
前一段时间做协议转换器的时间用到crc-16校验,查了不少资料发现都不理想。查表法要建表太麻烦,而计算法觉得那些例子太罗嗦。最后只好自己写了,最后发现原来挺简单嘛:)
两个子程序搞定。这里用的多项式为:
crc-16 = x16 + x12 + x5 + x0 = 2^0+2^5+2^12+2^16=0x11021
因最高位一定为“1”,故略去计算只采用0x1021即可
crc_byte:计算单字节的crc值
crc_data:计算一帧数据的crc值
crc_high crc_low:存放单字节crc值
crc16_high crc16_low:存放帧数据crc值
;<>-------------------------------------------------------------
; function: crc one byte
; input: crcbyte
; output: crc_high crc_low
;<>-------------------------------------------------------------
crc_byte:
clrf crc_low
clrf crc_high
movlw 09h
movwf v_loop1
movf crcbyte, w
movwf crc_high
crc:
decfsz v_loop1 ;8次循环,每一位相应计算
goto crc10
goto crcend
crc10
bcf status, c
rlf crc_low
rlf crc_high
btfss status, c
goto crc ;为0不需计算
movlw 10h ;若多项式改变,这里作相应变化
xorwf crc_high, f
movlw 21h ;若多项式改变,这里作相应变化
xorwf crc_low, f
goto crc
crcend:
nop
nop
return
;<>-------------------------------------------------------------
; crc one byte end
;<>-------------------------------------------------------------
;<>-------------------------------------------------------------
; function: crc date
; input: bufstart(a,b,c)(一帧数据的起始地址) v_count (要做crc的字节数)
; output: crc16_high crc16_low(结果)
;<>-------------------------------------------------------------
crc_data:
clrf crc16_high
clrf crc16_low
crc_data10
movf indf, w
xorwf crc16_high,w
movwf crcbyte
call crc_byte
incf fsr
decf v_count ;需计算的字节数
movf crc_high, w
xorwf crc16_low, w
movwf crc16_high
movf crc_low, w
movwf crc16_low
movf v_count, w ;计算结束?
btfss status, z
goto crc_data10
return
;<>-------------------------------------------------------------
; crc date end
;<>-------------------------------------------------------------
说明: crc 的计算原理如下(一个字节的简单例子)
11011000 00000000 00000000 <- 一个字节数据, 左移 16b
^10001000 00010000 1 <- crc-ccitt 多项式, 17b
--------------------------
1010000 00010000 10 <- 中间余数
^1000100 00001000 01
-------------------------
10100 00011000 1100
^10001 00000010 0001
-----------------------
101 00011010 110100
^100 01000000 100001
---------------------
1 01011010 01010100
^1 00010000 00100001
-------------------
01001010 01110101 <- 16b crc
仿此,可推出两个字节数据计算如下:d 为数据,p 为项式,a 为余数
dddddddd dddddddd 00000000 00000000 <- 数据 d ( d1, d0, 0, 0 )
 
两个子程序搞定。这里用的多项式为:
crc-16 = x16 + x12 + x5 + x0 = 2^0+2^5+2^12+2^16=0x11021
因最高位一定为“1”,故略去计算只采用0x1021即可
crc_byte:计算单字节的crc值
crc_data:计算一帧数据的crc值
crc_high crc_low:存放单字节crc值
crc16_high crc16_low:存放帧数据crc值
;<>-------------------------------------------------------------
; function: crc one byte
; input: crcbyte
; output: crc_high crc_low
;<>-------------------------------------------------------------
crc_byte:
clrf crc_low
clrf crc_high
movlw 09h
movwf v_loop1
movf crcbyte, w
movwf crc_high
crc:
decfsz v_loop1 ;8次循环,每一位相应计算
goto crc10
goto crcend
crc10
bcf status, c
rlf crc_low
rlf crc_high
btfss status, c
goto crc ;为0不需计算
movlw 10h ;若多项式改变,这里作相应变化
xorwf crc_high, f
movlw 21h ;若多项式改变,这里作相应变化
xorwf crc_low, f
goto crc
crcend:
nop
nop
return
;<>-------------------------------------------------------------
; crc one byte end
;<>-------------------------------------------------------------
;<>-------------------------------------------------------------
; function: crc date
; input: bufstart(a,b,c)(一帧数据的起始地址) v_count (要做crc的字节数)
; output: crc16_high crc16_low(结果)
;<>-------------------------------------------------------------
crc_data:
clrf crc16_high
clrf crc16_low
crc_data10
movf indf, w
xorwf crc16_high,w
movwf crcbyte
call crc_byte
incf fsr
decf v_count ;需计算的字节数
movf crc_high, w
xorwf crc16_low, w
movwf crc16_high
movf crc_low, w
movwf crc16_low
movf v_count, w ;计算结束?
btfss status, z
goto crc_data10
return
;<>-------------------------------------------------------------
; crc date end
;<>-------------------------------------------------------------
说明: crc 的计算原理如下(一个字节的简单例子)
11011000 00000000 00000000 <- 一个字节数据, 左移 16b
^10001000 00010000 1 <- crc-ccitt 多项式, 17b
--------------------------
1010000 00010000 10 <- 中间余数
^1000100 00001000 01
-------------------------
10100 00011000 1100
^10001 00000010 0001
-----------------------
101 00011010 110100
^100 01000000 100001
---------------------
1 01011010 01010100
^1 00010000 00100001
-------------------
01001010 01110101 <- 16b crc
仿此,可推出两个字节数据计算如下:d 为数据,p 为项式,a 为余数
dddddddd dddddddd 00000000 00000000 <- 数据 d ( d1, d0, 0, 0 )
 
[1]