Code:
'********************************************************************************************************************** ' I needed these CRC-16 routines to calculate the CRC for each byte of data in a string, accumulate the value in ' CrcReg??, and then use the final value of CrcReg?? to calculte a final Block Check Character (two; one byte each). ' These may be useful to someone. Should be easy to modify. Kev Peel and Tom Hanlin (and possibly others) may ' remember helping me in translating some of these from C. Thanks again. Feel free to use/modify this code. ' ' - CRC-16 Routines ' - Create a unique CRC-16 lookup table by changing the values of c%(0) through c%(7) ' - Calculate CRC value by passing data one byte at a time to CalculateCRC16 as databyte? until all bytes are passed ' Can be used to calculate CRC16 for your transmit string, or to calculate the CRC16 of a received string ' Last two bytes of received string (for my purposes) are the Most Significant Byte and then Least Significant ' Byte of of the final Block Check Character - can be omitted if you don't need them. ' - Final BCC (Block Check Character) composed of two one byte pieces of data, BCC1?, and BCC2? ' Convert these to byte sized bit patterns with MKBYT$ before appending to end of string ' ' ' ' '********************************************************************************************************************** 'create a 256 element look up table based on a unique mask/rule set FUNCTION MakeLookUpTable () AS LONG GLOBAL CrcReg?? GLOBAL table?? () LOCAL c% () LOCAL d$ LOCAL i&, j&, mask& REDIM table??(0 TO 255) REDIM c%(0 TO 7) 'these hex values create a unique look up table, change values to change the table c%(0) = &h1001 c%(1) = &h2002 c%(2) = &h4004 c%(3) = &h8118 c%(4) = &h1221 c%(5) = &h2482 c%(6) = &h48A4 c%(7) = &h3AB8 FOR i& = 0 TO 255 table??(i&) = 0 mask& = &h0001 FOR j& = 0 TO 7 IF(i& AND mask&) THEN table??(i&) = table??(i&) XOR c%(j&) SHIFT LEFT mask&, 1 NEXT j& d$ = HEX$(table??(i&)) NEXT i& FUNCTION = 0 END FUNCTION '************************************************************************************************************* FUNCTION ResetCRC () AS LONG CrcReg?? = 0 'reset CrcReg?? before calculating new string END FUNCTION '************************************************************************************************************* ' calculate the CRC-16; call this routine until all bytes of data have been passed to it, then call GetBCC1BisyncByte FUNCTION CalculateCrc16 (databyte?) AS LONG LOCAL s??, CrcCopy?? CrcCopy?? = CrcReg?? 'make a copy because SHIFT changes the value of CrcReg?? s?? = 0 SHIFT RIGHT CrcCopy??, 8 s?? = (databyte? AND &h00ff) XOR (CrcCopy?? AND &h00ff) 'databye? is one byte of data extracted from data string SHIFT LEFT CrcReg??, 8 CrcReg?? = (CrcReg?? XOR table??(s??)) END FUNCTION '******************************************************************************************************************** 'get first block check character (MSB(yte)) FUNCTION GetBCC1BisyncByte () AS LONG STATIC BCC1? LOCAL a$, CRC?? CRC?? = CrcReg?? 'make a copy of the value of CrcReg?? SHIFT RIGHT CRC??, 8 BCC1? = NOT (CRC?? AND 255) CALL GetBCC2BisyncByte (BCC1?) END FUNCTION '****************************************************************************************************************************** 'get second block check character (LSB(yte)) FUNCTION GetBCC2BisyncByte (BCC1?) AS LONG STATIC BCC2? BCC2? = NOT(CrcReg?? AND 255) blockcheck$ = MKBYT$(BCC1?) + MKBYT$(BCC2?) 'blockcheck$ is a global variable declared elsewhere END FUNCTION ' ********************************************************************************************************************
Mark Pruitt
markspruitt@yahoo.com
[This message has been edited by mark pruitt (edited July 30, 2003).]