News:

Let's find out together what makes a PIC Tick!

Main Menu

CRC calculation

Started by Giuseppe MPO, Sep 23, 2023, 10:51 AM

Previous topic - Next topic

Giuseppe MPO


I need to communicate with a photovoltaic inverter via the RS232 port, in the connection I need to generate and decode a CRC which in this case is CRC-16/XMODEM, I've been banging my head about it for a while but I can't get out of it. Does anyone have any code or even a piece of code that I can start with?

Yasin

I hope it does its job.
Proc CRC16_CALC(pCount1 As Byte,pCount2 As Byte)
    MODBUS_CRC = $FFFF
    For CRC_COUNT1 = pCount1 To (pCount2 - 1)
        MODBUS_CRC.Byte0 = MODBUS_CRC.Byte0 ^ TCP_STRING[CRC_COUNT1]
        For CRC_COUNT2 = 0 To 7
            If MODBUS_CRC.0 = 1 Then
                MODBUS_CRC = MODBUS_CRC >> 1
                MODBUS_CRC = MODBUS_CRC ^ $A001
            Else
                MODBUS_CRC = MODBUS_CRC >> 1
            EndIf               
        Next
    Next
EndProc


Frizie

The code snippet from above:

If MODBUS_CRC.0 = 1 Then
    MODBUS_CRC = MODBUS_CRC >> 1
    MODBUS_CRC = MODBUS_CRC ^ $A001
Else
    MODBUS_CRC = MODBUS_CRC >> 1
EndIf

Could be shortened to:

MODBUS_CRC = MODBUS_CRC >> 1
If MODBUS_CRC.0 = 1 Then MODBUS_CRC = MODBUS_CRC ^ $A001
Ohm sweet Ohm | www.picbasic.nl

Yasin

No, this would be wrong. After "MODBUS_CRC = MODBUS_CRC >> 1", the zeroth bit may change.

Frizie

I see it Yasin, you're right  :-[
Ohm sweet Ohm | www.picbasic.nl

Giuseppe MPO


Thanks for the answers, but I already had my old procedures for calculating the Modbus CRC, but what I need now is the CRC16 XModem

Mapo

Hi Giuseppe,
I created this routine for the CRC16 X25.
By changing the table and a few changes you can adapt it

' VARIABILI               
                Dim CRC As Word
                Dim TempLng As Word
                Dim TempLng2 As Word
                Dim Temp As Byte
                Dim DataByte[8] As Byte
                Dim CRCTab[256] As Word
                Dim N_Byte As Byte
                Dim X As Byte
                Dim Ind_Tab As Byte
               

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                CRCTab= $0000, $1021, $2042, $3063, $4084, $50A5, $60C6, $70E7, $8108, $9129, $A14A, $B16B, $C18C, $D1AD, $E1CE, $F1EF,_
                        $1231, $0210, $3273, $2252, $52B5, $4294, $72F7, $62D6, $9339, $8318, $B37B, $A35A, $D3BD, $C39C, $F3FF, $E3DE,_
                        $2462, $3443, $0420, $1401, $64E6, $74C7, $44A4, $5485, $A56A, $B54B, $8528, $9509, $E5EE, $F5CF, $C5AC, $D58D,_
                        $3653, $2672, $1611, $0630, $76D7, $66F6, $5695, $46B4, $B75B, $A77A, $9719, $8738, $F7DF, $E7FE, $D79D, $C7BC,_
                        $48C4, $58E5, $6886, $78A7, $0840, $1861, $2802, $3823, $C9CC, $D9ED, $E98E, $F9AF, $8948, $9969, $A90A, $B92B,_
                        $5AF5, $4AD4, $7AB7, $6A96, $1A71, $0A50, $3A33, $2A12, $DBFD, $CBDC, $FBBF, $EB9E, $9B79, $8B58, $BB3B, $AB1A,_
                        $6CA6, $7C87, $4CE4, $5CC5, $2C22, $3C03, $0C60, $1C41, $EDAE, $FD8F, $CDEC, $DDCD, $AD2A, $BD0B, $8D68, $9D49,_
                        $7E97, $6EB6, $5ED5, $4EF4, $3E13, $2E32, $1E51, $0E70, $FF9F, $EFBE, $DFDD, $CFFC, $BF1B, $AF3A, $9F59, $8F78,_
                        $9188, $81A9, $B1CA, $A1EB, $D10C, $C12D, $F14E, $E16F, $1080, $00A1, $30C2, $20E3, $5004, $4025, $7046, $6067,_
                        $83B9, $9398, $A3FB, $B3DA, $C33D, $D31C, $E37F, $F35E, $02B1, $1290, $22F3, $32D2, $4235, $5214, $6277, $7256,_
                        $B5EA, $A5CB, $95A8, $8589, $F56E, $E54F, $D52C, $C50D, $34E2, $24C3, $14A0, $0481, $7466, $6447, $5424, $4405,_
                        $A7DB, $B7FA, $8799, $97B8, $E75F, $F77E, $C71D, $D73C, $26D3, $36F2, $0691, $16B0, $6657, $7676, $4615, $5634,_
                        $D94C, $C96D, $F90E, $E92F, $99C8, $89E9, $B98A, $A9AB, $5844, $4865, $7806, $6827, $18C0, $08E1, $3882, $28A3,_
                        $CB7D, $DB5C, $EB3F, $FB1E, $8BF9, $9BD8, $ABBB, $BB9A, $4A75, $5A54, $6A37, $7A16, $0AF1, $1AD0, $2AB3, $3A92,_
                        $FD2E, $ED0F, $DD6C, $CD4D, $BDAA, $AD8B, $9DE8, $8DC9, $7C26, $6C07, $5C64, $4C45, $3CA2, $2C83, $1CE0, $0CC1,_
                        $EF1F, $FF3E, $CF5D, $DF7C, $AF9B, $BFBA, $8FD9, $9FF8, $6E17, $7E36, $4E55, $5E74, $2E93, $3EB2, $0ED1, $1EF0

' BYTE TEST               
                DataByte[0] = $01
                DataByte[1] = $02
                DataByte[2] = $03
                DataByte[3] = $04
                DataByte[4] = $05
                DataByte[5] = $06
                DataByte[6] = $07
                DataByte[7] = $08
               
                N_Byte = 8
               
                HRSOut 13,"Test CRC",13

CRC_Routine: 
                CRC = $FFFF                                           

' Calcolo CRC16 X25
                For X = 0 To N_Byte -1                                   
                    Temp = DataByte[X]
                    Temp = Temp @8
                    TempLng2 = Temp << 8                           
                    TempLng = CRC ^ TempLng2
                    Ind_Tab = ((TempLng.Byte1 >> 4) * 16) + (TempLng.Byte1 & %00001111) 
                    TempLng2 = CRCTab[Ind_Tab]
                    CRC = (CRC << 8) ^ TempLng2   
                Next
                CRC = CRC @16
                CRC = CRC ^ $FFFF

                HRSOut "CRC      ", Hex4 CRC ,13
                End

Giuseppe

hi Giuseppe but how many bytes does the string consist of?

Mapo

The calculation is on 8 bytes, but you can change the quantity to N_Bytes

N_Byte = 8


Mapo


Giuseppe MPO

Quote from: Giuseppe on Sep 24, 2023, 09:54 PMhi Giuseppe but how many bytes does the string consist of?

Hi Giuseppe, unfortunately the number of bytes is variable depending on the command

Giuseppe MPO

Quote from: Mapo on Sep 24, 2023, 10:01 PMhere you can test and copy the table

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

I understand the calculation of the CRC and its result, what is less clear to me is what the table is for.

Pepe

It is a faster algorithm using the table