I hope this helps someone.
Code:
'*********************************************************************
'* Name : CRC16.BAS [CCITT CRC16] *
'* Author : Ashley Roll, Phil Ciebiera *
'* Notice : Derived from works at: *
'* : www.digitalnemesis.com/info/codesamples/embeddedcrc16/ *
'* : Ported to Proton+ BASIC - www.protonbasic.co.uk/ *
'* Date : 2/21/2011 *
'* Version : 1.0 *
'* Notes : Test Vector: 0x313233343536373839 : 0x29B1 *
'* : Test Vector: 0x393837363534333231 : 0x84DF *
'* : Continuously calculates CRC16 CCITT on incoming USART1 *
'* : PIC®18F46K22 INTOSC 16x4PLL 64MHz - Connect 9600 8-N-1 *
'* : This code is shared under The MIT License *
'*********************************************************************
'--- BEGIN: Microchip™ PIC® INITIALIZATION ---
Device 18F46K22
Xtal 16
All_Digital True
Config_Start
FOSC = INTIO67 ' Internal oscillator block, port function on RA6 and RA7
PLLCFG = On ' Oscillator multiplied by 4
PRICLKEN = On ' Primary clock is always enabled
FCMEN = Off ' Fail-Safe Clock Monitor disabled
IESO = Off ' Oscillator Switchover mode disabled
PWRTEN = Off ' Power up timer disabled
BOREN = Off ' Brown-out Reset disabled in hardware and software
WDTEN = Off ' Watch dog timer is always disabled. SWDTEN has no effect.
'WDTPS = 1 ' 1:1
CCP2MX = PORTB3 ' CCP2 input/output is multiplexed with RB3
PBADEN = Off ' PORTB<5:0> pins are configured as digital I/O on Reset
CCP3MX = PORTB5 ' P3A/CCP3 input/output is multiplexed with RB5
HFOFST = On ' HFINTOSC output and ready status are not delayed by the oscillator stable status
T3CMX = PORTC0 ' T3CKI is on RC0
P2BMX = PORTD2 ' P2B is on RD2
MCLRE = EXTMCLR ' RE3 input pin enabled; MCLR disabled
STVREN = Off ' Stack full/underflow will not cause Reset
LVP = On ' Single-Supply ICSP disabled
XINST = Off ' Instruction set extension and Indexed Addressing mode enabled
Debug = Off ' Disabled
CP0 = Off ' Block 0 (000800-003FFFh) not code-protected
CP1 = Off ' Block 1 (004000-007FFFh) not code-protected
CP2 = Off ' Block 2 (008000-00BFFFh) not code-protected
CP3 = Off ' Block 3 (00C000-00FFFFh) not code-protected
CPB = Off ' Boot block (000000-0007FFh) not code-protected
CPD = Off ' Data EEPROM not code-protected
WRT0 = Off ' Block 0 (000800-003FFFh) not write-protected
WRT1 = Off ' Block 1 (004000-007FFFh) not write-protected
WRT2 = Off ' Block 2 (008000-00BFFFh) not write-protected
WRT3 = Off ' Block 3 (00C000-00FFFFh) not write-protected
WRTC = Off ' Configuration registers (300000-3000FFh) not write-protected
WRTB = Off ' Boot Block (000000-0007FFh) not write-protected
WRTD = Off ' Data EEPROM not write-protected
EBTR0 = Off ' Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
EBTR1 = Off ' Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
EBTR2 = Off ' Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
EBTR3 = Off ' Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
EBTRB = Off ' Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
OSCCON.4 = 1
OSCCON.5 = 1 'FOR 16MHZ
OSCCON.6 = 1
DelayMS 300
'--- END: Microchip™ PIC® INITIALIZATION ---
' Jump over CRC16 Definitions to the Demo
GoTo DemoStart
' --- BEGIN: CRC16 RELATED ---
' CRC16 Result Bytes
Dim bCRC16_High As Byte
Dim bCRC16_Low As Byte
' Internal Work Variables
Dim bCRC16_Work1 As Byte
Dim bCRC16_Work2 As Byte
' CRC16 I/O Bytes
Dim bCRC16_Input As Byte
Dim wCRC16_Output As Word
' Sets the initial CRC value
CRC16_Initialize:
bCRC16_High = $FF
bCRC16_Low = $FF
Return
' Processes the CRC16 from the byte at bCRC16_Input and updates the checksum at wCRC16_Output
CRC16_ProcessInput:
' process byte from CRC16_Input
' High Nibble
bCRC16_Work2 = bCRC16_Input >> 4
GoSub CRC16_ProcessNibble
' Low Nibble
bCRC16_Work2 = bCRC16_Input & $0F
GoSub CRC16_ProcessNibble
' Assemble output word
wCRC16_Output.LowByte = bCRC16_Low
wCRC16_Output.HighByte = bCRC16_High
Return
' Actually computes a 4-bit CRC
CRC16_ProcessNibble:
' Step one, extract the Most significant 4 bits of the CRC register
bCRC16_Work1 = bCRC16_High >> 4
' XOR in the Message Data into the extracted bits
bCRC16_Work1 = bCRC16_Work1 ^ bCRC16_Work2
' Shift the CRC Register left 4 bits
bCRC16_Work2 = bCRC16_Low >> 4
bCRC16_High = bCRC16_High << 4
bCRC16_High = bCRC16_High | bCRC16_Work2
bCRC16_Low = bCRC16_Low << 4
' Do the table lookups and XOR the result into the CRC Tables
' High byte
bCRC16_Work2 = CRead (CRC16_LookupTables + bCRC16_Work1)
bCRC16_High = bCRC16_High ^ bCRC16_Work2
' Low byte
bCRC16_Work2 = CRead (CRC16_LookupTables + 16 + bCRC16_Work1)
bCRC16_Low = bCRC16_Low ^ bCRC16_Work2
Return
' --- PAUSE: CRC16 RELATED ---
' --- BEGIN: DEMO RELATED ---
DemoStart:
;Calculated Baudrate = 9592 @ Xtal 16MHz, Error = -0.08%
RCSTA = 144 ; Enable continuous receive
TXSTA = 36 ; Enable transmit, BRGH = 1
SPBRG = 160 ; Baud Rate Generator Low Byte Value
SPBRGH = 1 ; Baud Rate Generator High Byte Value
BAUDCON.3 = 1 ; Enable the 16 bit Baud Rate Generator
Declare Hserial_Clear On
Dim ser_data As Byte
GoSub CRC16_Initialize
Demo:
HSerIn 100, Demo, [ser_data] ' Listen for a byte on the USART
bCRC16_Input = ser_data ' Assign the byte to the CRC16 routine input
GoSub CRC16_ProcessInput ' Process the CRC16 for the byte
HSerOut [ser_data,": ",Hex4 wCRC16_Output,13,10] ' Output the formatted result
GoTo Demo ' Loop
' --- END: DEMO RELATED ---
' --- RESUME: CRC16 RELATED ---
' CRC16 computational lookup tables
CRC16_LookupTables:
CData $00, $10, $20, $30, $40, $50, $60, $70, $81, $91, $A1, $B1, $C1, $D1, $E1, $F1 ' CRC16_Lookup High
CData $00, $21, $42, $63, $84, $A5, $C6, $E7, $08, $29, $4A, $6B, $8C, $AD, $CE, $EF ' CRC16_Lookup Low
' --- END: CRC16 RELATED ---


Menu
Recent Articles


Using PDS with SPI GLCD based on ST7565R Controller
Graphic LCDs based on the ST7565 are cheaper then GLCDs with other controllers. SPI requires only four pins. If the circuit