学海荡舟手机网

主页 > 实用文摘 > 教育文摘_18 > > 详细内容

计算法简单实现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 )
 

[1]