LB Booster
Programming >> Liberty BASIC language >> MODBUS CRC16 calculation
http://lbb.conforums.com/index.cgi?board=lblang&action=display&num=1392311567

MODBUS CRC16 calculation
Post by flotulopex on Feb 13th, 2014, 4:12pm

Hello,

I'm working on a small MODBUS project and have a need for a CRC16 calculator. For a start, I found following explanation on the web and aslo a PIC Basic code to start with.

For now, I would like to convert this PIC Basic code to LBB so I get a nice tool to work with.

I know, I know: google. Pffff.....

But I don't want a "ready made" thing; I prefer to MAKE MY OWN tool!

Hereunder is the explanation of how to calculate a CRC16.

The 16-bits Cyclical Redundancy Check (CRC) field is two bytes, containing a 16-bit binary value.
The CRC value is calculated by the transmitting device, which appends the CRC to the message.
The receiving device recalculates a CRC during receipt of the message, and compares the calculated value to the actual value it received in the CRC field. If the two values are not equal, an error results.
The CRC is started by first preloading a 16-bit register to all 1's. Then a process begins of applying successive 8-bit bytes of the message to the current contents of the register.
Only the eight bits of data in each character are used for generating the CRC; start and stop bits, and the parity bit do not apply to the CRC.
During generation of the CRC, each 8-bit character is XORed with the register contents. Then the result is shifted in the direction of the least significant bit (LSB) and filled with a zero into the most significant bit (MSB) position. The LSB is extracted and examined. If the LSB was a 1, the register is then XORed with a preset fixed value. If the LSB was a 0, no XOR takes place. This process is repeated until eight shifts have been performed. After the last (eighth) shift, the next 8-bit character is XORed with the register's current value, and the process repeats for eight more shifts as described above.
The final content of the register, after all the characters of the message have been applied, is the CRC value.


Here's the PIC Basic code I started with:
Code:
'CRC=$FFFF ' initialize value
For X = 0 to 10 ' number of bytes to process
    CRC = CRC ^ dataCRC[X] ' read through data array
        For Z = 1 to 8
            IF CRC.Bit0 = 1 Then ' check bits
               CRC = $A001 ^ (CRC >> 1)
            Else
               CRC = CRC >> 1
            EndIF
        Next Z
Next X 


And here is what I came to with LBB:
Code:
'This example is ment to be correct: 0F 03 08 13 24 13 88 13 5B 00 01 = CRC16: 0x0FD2

DataCRC$(0)  = "0F"
DataCRC$(1)  = "03"
DataCRC$(2)  = "08"
DataCRC$(3)  = "13"
DataCRC$(4)  = "24"
DataCRC$(5)  = "13"
DataCRC$(6)  = "88"
DataCRC$(7)  = "13"
DataCRC$(8)  = "5B"
DataCRC$(9)  = "00"
DataCRC$(10) = "01"

[start]
    PRINT "MODBUS CRC-16 calculator"
    PRINT "ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ"
[calculate]
   CRCRegister = 65535 '&hFFFF
   FOR X = 0 to 10
      CRCRegister = CRCRegister XOR HEXDEC(DataCRC$(0))
      FOR Z = 0 TO 7
         IF (CRCRegister MOD 2) = 1 THEN        'chek if the LSB is a "1"
            CRCRegister = INT(CRCRegister / 2)  'shift CRCRegister one bit to the right
            CRCRegister = CRCRegister XOR 40961 '&hA001
         ELSE
            CRCRegister = INT(CRCRegister / 2)  'shift CRCRegister one bit to the right
         END IF
      NEXT Z
   NEXT X
   PRINT "CRC16 (0x0FD2) : "; CRCRegister, DECHEX$(CRCRegister)
END 

I just can't get the correct result that should be 0x0FD2.

What am I doing (or not doing) wrong?

BTW, is there a way to close the "***.lbb.tmp" window by a command instead of Alt+F4? Something like:
Code:
INPUT "Close this window?"; Y/N 


Roger
Re: MODBUS CRC16 calculation
Post by Richard Russell on Feb 13th, 2014, 10:14pm

on Feb 13th, 2014, 4:12pm, flotulopex wrote:
What am I doing (or not doing) wrong?

There's a typo. Change DataCRC$(0) to DataCRC$(X) as follows:

Code:
      CRCRegister = CRCRegister XOR HEXDEC(DataCRC$(X)) 

Quote:
BTW, is there a way to close the "***.lbb.tmp" window by a command instead of Alt+F4?

If you don't mind it being LBB-specific you can close the mainwin as follows:

Code:
    !QUIT 

(note the initial exclamation mark).

Richard.

Re: MODBUS CRC16 calculation
Post by flotulopex on Feb 14th, 2014, 05:59am

Thank you Richard; it works fine now.

Having my nose too close to the screen, I couldn't see that simple mistake that costed me more than 12 hours!!

Thanks again for that and also for the windows closing tip smiley