Dallas CRC16 Routines


Closed Thread
Results 1 to 1 of 1
  1. #1
    Join Date
    Jan 2004
    Location
    Grand Lake O' Cherokees USA
    Posts
    15

    Default Dallas CRC16 Routines

    Three separate Dallas CRC16 routines.

    Note: for some reason spaces are being added to some of the table entries. I tried to edit them out but they returned. They need to be removed before the table version is used.


    ' PIC16F628
    ' This program contains three subroutines for calculating the Dallas 1Wire 16Bit CRC.
    ' The computationally intensive short version is called CRC16. Use this one when
    ' you don't have enough PIC memory to store the table version (approx 550 words).
    ' and/or can afford the processing time.
    ' The table version CRC16LU is computationally fast since it works on byte at a
    ' time rather than bit at a time as CRC16 does.
    ' The assembly language version of the computationally intensive version is CRC16AL
    ' Times per 16 bit CRCWord consisting of CRCHI and CRCLO:
    ' CRC16LU - 62usec
    ' CRC16AL - 130usec
    ' CRC16 - 330usec


    DEFINE OSC 4

    @ DEVICE XT_OSC
    @ DEVICE MCLR_OFF
    @ DEVICE LVP_OFF
    CMCON = 7

    CRCData var Byte ' CRC16 & CRC16LU & CRC16AL
    CRCLo var Byte ' CRC16 & CRC16LU & CRC16AL
    CRCHi var Byte ' CRC16 & CRC16LU & CRC16AL
    I var Byte ' CRC16 & CRC16AL
    TestByte var Byte ' CRC16AL
    TestBit var Bit ' CRC16
    LUIndex var Byte ' CRC16LU
    OldCRCHi var Byte ' CRC16LU

    ' Test Data
    CRCHi = $90
    CRCLo = $F1
    CRCData = $75
    ' New CRCLo = $63, CRCHi = $90
    GoSub CRC16LU
    'GoSub CRC16
    'Call CRC16AL
    END

    ' ********** Subroutine CRC16 **********
    ' Subroutine expects CRCLo and CRCHi to be initialized to zero or some starting value
    ' and expects data to be CRC'd in CRCData
    ' CRCLo and CRCHi will contain new CRC Values. CRCData is destroyed.
    ' Need variables I-Byte, TestBit-Bit, CRCHi-Byte, CRCLo-Byte, CRCData-Byte
    CRC16:
    For I = 0 to 7 ' Do for all 8 bits in Data Byte
    TestBit = CRCData.0 ^ CRCLo.0 ' XOR bit0 of Data Byte and Low CRC
    CRCData = CRCData >> 1 ' Position Data Byte for next bit test
    If TestBit = 0 then Shift ' If Test Bit not set, just shift CRC's
    CRCHi.6 = CRCHi.6 ^ 1 ' If Test Bit set, compliment bit 14 of CRC
    CRCLo.1 = CRCLo.1 ^ 1 ' And compliment bit 1 of CRC as well
    Shift: ' Shift right whole CRC word.
    CRCLo = CRCLo >> 1 ' Low CRC bit 0 is to bit bucket
    CrcLo.7 = CRCHi.0 ' Make sure High CRC bit 0 shifts to Low CRC bit 7
    CRCHi = CRCHi >> 1 ' High CRC bit 0 can now go to bit bucket
    CRCHi.7 = TestBit ' Replace bit 15 of CRC with TestBit.
    Next I
    Return


    ' ********** Subroutine CRC16AL **********
    ' Subroutine expects CRCLo and CRCHi to be initialized to zero or some starting value
    ' and expects data to be CRC'd in CRCData
    ' CRCLo and CRCHi will contain new CRC Values. CRCData will be destroyed.
    ' Need variables I-Byte, TestByte-Byte, CRCHi-Byte, CRCLo-Byte, CRCData-Byte
    ASM
    _CRC16AL ; Dallas CRC16 Assembly Language PIC16F628
    MOVLW 8
    MOVWF _I ; Do this for all 8 bits of CRCByte
    CRCLOOP
    MOVF _CRCLo,0 ; Put CRCLo into W
    XORWF _CRCData,0 ; XOR CRCLo with CRCData
    MOVWF _TestByte ; Put results in TestByte
    RRF _TestByte,1 ; Shift TestByte.0 into Carry bit
    BTFSS STATUS,C ; If Carry = 1, account for EXOR feedback gates
    GOTO CRCSHIFT ; Otherwise just shift CRC's and CRCByte
    MOVF _CRCHi,0 ; Get latest copy of CRCHi
    XORLW 0x40 ; Compliment CRCHi.6
    MOVWF _CRCHi ; Keep a copy of results
    MOVF _CRCLo,0 ; Get latest copy of CRCL0
    XORLW 0x02 ; Compliment CRCLo.1
    MOVWF _CRCLo ; Keep a copy of results
    CRCSHIFT
    RRF _CRCHi,1 ; Rotate both CRCs as a word, incorporate
    RRF _CRCLo,1 ; c flag into CRCHi.7
    RRF _CRCData,1 ; Shift remaining data bits right once
    DECFSZ _I,1 ; Keep track of #times through loop
    GOTO CRCLOOP ; Go to start if not looped through the 8 bits
    RETURN ; Return if all 8 bits analyzed
    ENDASM


    ' ********** Subroutine CRC16LU **********
    ' Subroutine expects CRCLo and CRCHi to be initialized to zero or some starting value
    ' expects data to be CRC'd in CRCData
    ' CRCLo and CRCHi will contain the new CRC values
    ' Needs variables LUIndex-Byte, CRCLo-Byte, CRCHi-Byte, OldCRCHi-Byte, CRCData-Byte
    CRC16LU:
    OldCRCHi = CRCHi
    LUIndex = CRCLo ^ CRCData
    LookUp LUIndex, [$00,$C0,$C1,$01,$C3,$03,$02,$C2,$C6,$06,$07,$C7,$0 5,$C5,$C4,$04,_
    $CC,$0C,$0D,$CD,$0F,$CF,$CE,$0E,$0A,$CA,$CB,$0B,$C 9,$09,$08,$C8,_
    $D8,$18,$19,$D9,$1B,$DB,$DA,$1A,$1E,$DE,$DF,$1F,$D D,$1D,$1C,$DC,_
    $14,$D4,$D5,$15,$D7,$17,$16,$D6,$D2,$12,$13,$D3,$1 1,$D1,$D0,$10,_
    $F0,$30,$31,$F1,$33,$F3,$F2,$32,$36,$F6,$F7,$37,$F 5,$35,$34,$F4,_
    $3C,$FC,$FD,$3D,$FF,$3F,$3E,$FE,$FA,$3A,$3B,$FB,$3 9,$F9,$F8,$38,_
    $28,$E8,$E9,$29,$EB,$2B,$2A,$EA,$EE,$2E,$2F,$EF,$2 D,$ED,$EC,$2C,_
    $E4,$24,$25,$E5,$27,$E7,$E6,$26,$22,$E2,$E3,$23,$E 1,$21,$20,$E0,_
    $A0,$60,$61,$A1,$63,$A3,$A2,$62,$66,$A6,$A7,$67,$A 5,$65,$64,$A4,_
    $6C,$AC,$AD,$6D,$AF,$6F,$6E,$AE,$AA,$6A,$6B,$AB,$6 9,$A9,$A8,$68,_
    $78,$B8,$B9,$79,$BB,$7B,$7A,$BA,$BE,$7E,$7F,$BF,$7 D,$BD,$BC,$7C,_
    $B4,$74,$75,$B5,$77,$B7,$B6,$76,$72,$B2,$B3,$73,$B 1,$71,$70,$B0,_
    $50,$90,$91,$51,$93,$53,$52,$92,$96,$56,$57,$97,$5 5,$95,$94,$54,_
    $9C,$5C,$5D,$9D,$5F,$9F,$9E,$5E,$5A,$9A,$9B,$5B,$9 9,$59,$58,$98,_
    $88,$48,$49,$89,$4B,$8B,$8A,$4A,$4E,$8E,$8F,$4F,$8 D,$4D,$4C,$8C,_
    $44,$84,$85,$45,$87,$47,$46,$86,$82,$42,$43,$83,$4 1,$81,$80], CRCHi
    ' PBP only handles 255 constants in the list (256 for 18Cxxx) so special case for $FF
    If LUIndex = $FF then
    CRCHi = $40
    EndIF
    LookUp LUIndex, [$00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81,$40,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81,$40,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81,$40,_
    $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81,$40,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81,$40,_
    $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81,$40,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81,$40,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $01,$C0,$80,$41,$00,$C1,$81,$40,$00,$C1,$81,$40,$0 1,$C0,$80,$41,_
    $00,$C1,$81,$40,$01,$C0,$80,$41,$01,$C0,$80,$41,$0 0,$C1,$81], CRCLo
    If LUIndex = $FF then
    CRCLo = $40
    EndIF
    CRCLo = CRCLo ^ OldCRCHi
    Return
    Last edited by Tom Estes; - 16th May 2005 at 15:37. Reason: Draw attention to spaces in table
    Tom

Similar Threads

  1. Dallas CRC8 Routines
    By Tom Estes in forum Code Examples
    Replies: 23
    Last Post: - 8th May 2018, 18:07
  2. dallas ibutton to pics
    By CBUK in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 25th October 2006, 12:55
  3. Dallas 1-wire search Routine
    By jimbab in forum Code Examples
    Replies: 0
    Last Post: - 7th April 2006, 16:14
  4. Interfacing with Dallas 1-Wire weather station
    By bcd in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 1st January 2006, 11:44
  5. Crc16 Ds2406
    By IceCube in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 26th February 2004, 14:33

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts