- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 7 von 7

Thema: CRC8 <==> SAE J1850 - Was mache ich falsch?

  1. #1

    CRC8 <==> SAE J1850 - Was mache ich falsch?

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    auf Empfehlung bin ich nun hier im Robonetz gelandet - wenn es hier keine Lösung gibt geht es nicht, hieß es

    Mein Problem: Ich muss eine CRC-Checksumme nach SAE J1850-Standart über 10 Datenbytes erstellen. Die Bascom-CRC-Routine kann ich nicht nehmen weil sie 8C (Dallas) als Generatorpolynom nimmt. Nach Wiki muss ich 1D als Polynom nehmen. Also hab ich mir eine Routine geschrieben bei der ich das Polynom frei einsetzen kann:

    Dim Ar(10) As Byte
    Dim Temp1 As Byte ' Temporäre Variable
    Dim Temp2 As Byte ' Temporäre Variable

    Dim X As Byte

    Dim Crc As Byte
    Dim Crcpoly As Byte

    Dim Bytecounter As Byte
    Dim Bitcounter As Byte


    Ar(1) = &HB2
    Ar(2) = &HD0
    Ar(3) = &HE0
    Ar(4) = &H70
    Ar(5) = &H00
    Ar(6) = &H00
    Ar(7) = &H00
    Ar( = &H00
    Ar(9) = &H00
    Ar(10) = &H00


    Crcpoly = &H1D

    Gosub Calc_crc


    Print Hex(crc)
    Crc = Crc8(ar(1) , 10)
    Print Hex(crc)

    End

    Calc_crc:
    Crc = 0

    For Bytecounter = 1 To 10
    Temp2 = Ar(bytecounter)
    For Bitcounter = 0 To 7

    Temp1 = Temp2 Xor Crc
    Temp1 = 1 And Temp1

    Shift Crc , Right
    Crc = Crc And &HFF

    Shift Temp2 , Right
    Temp2 = Temp2 And &HFF

    If Temp1 <> 0 Then
    Crc = Crc Xor Crcpoly

    End If


    Next


    Next

    Return
    Die Routine funktioniert, wenn ich 8C einsetzte bekomme ich das gleiche Ergebnis wie die CRC8-Routine berechnet.

    Setze ich aber die 1D ein bekomme ich nicht das richtige Ergebnis nach J1850 zurück. Hat SAE J1850 noch andere Eigenheiten von denen ich nichts weiß? Habe hier noch zwei Beispiele von kompletten Datensätzen, das letzte Byte ist die CRC die zurückkommen müsste.

    'A2 82 50 00 00 00 00 00 00 00 4D
    'B2 D0 E0 70 00 00 00 00 00 00 88
    Bitte helft mir - Google ist schon heißgelaufen und in der Suche hab ich auch nichts weiteres gefunden.

    Gruß Frank

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.08.2004
    Ort
    Graz
    Beiträge
    342
    Ich habe mal einen Testlauf für CRCPoly von 0 bis 255 durchlaufen lassen, bei keinem Wert kam als Ergebnis &H88, ich vermute also dass deine Routine doch nicht so richtig funktioniert.

    Ich weiß nicht ob du bei deiner Recherche darüber gestolpert bist: http://en.wikipedia.org/wiki/Cyclic_redundancy_check , steht eigentlich alles da drin. (Habe auch statt &H1D &HB8, wie in der Tabelle angegeben, probiert, ohne Ergebnis).

    mfg

  3. #3
    Hallo,

    jep, das hatte ich auch mal gemacht. Auch die ganzen englischen und deutschen Wiki-Seiten hab ich durch....aber irgendwie ist die Nuss zu hart für mich
    Mit 8C als Polynom bekomme ich identische Ergbenisse wie die Bacom-Routine, daher gehe ich davon aus das die Routine funktioniert.

    Ich hab hier noch ein Beispiel welches funktionieren soll, leider in einer Sprache der ich nicht mächtig bin:

    // Define Global variables
    // message buffer variables
    unsigned char msg_buf[20], nbytes, bit_point;
    unsigned char * byte_point;
    // Switch to select VPW PWM or ISO 0, 1, 2, respectively
    unsigned char protocol;
    // values to define protocol variable
    #define vpw 0
    #define pwm 1
    #define iso 2
    /************************************************** *******************
    CRC CALCULATION SUBROUTINE
    Calculates the crc as defined by SAE, or the checksum for ISO
    ************************************************** *******************/
    // This routine assumes that all the data bytes are in the array msg_buf[]
    // Starting with msg_buf[0] as the first byte.
    // nbytes indicates how many bytes are in the array.
    // The subroutine calculates both the checksum and the CRC byte as
    // defined by SAE and ISO specifications.
    // Either the CRC or the Checksum is returned, depending on what
    // protocol is selected.
    unsigned char crc(void)
    {
    unsigned char crc_reg=0xff,poly,i,j, checksum=0;
    for (i=0, byte_point=msg_buf; i<nbytes; ++i, ++byte_point)
    {
    for (j=0, bit_point=0x80 ; j<8; ++j, bit_point>>=1)
    {
    if (bit_point & *byte_point) // case for new bit =1
    {
    if (crc_reg & 0x80) poly=1; // define the polynomial
    else poly=0x1c;
    crc_reg= ( (crc_reg << 1) | 1) ^ poly;
    }
    else // case for new bit =0
    {
    poly=0;
    if (crc_reg & 0x80) poly=0x1d;
    crc_reg= (crc_reg << 1) ^ poly;
    }
    }
    checksum += *byte_point; // Calculate checksum
    }
    if (protocol==iso) return checksum; // Iso uses checksum,
    return ~crc_reg; // Otherwise, use CRC
    Ohne den Code richtig zu verstehen sind IMHO doch Unterschiede zur "normalen" CRC-Berechnung zu sehen.....vieleicht kann das ja jemand in Bascom übersetzen....

    Gruß Frank

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.08.2004
    Ort
    Graz
    Beiträge
    342
    ich habe mich mal daran versucht, bekomme aber kein richtiges Ergebnis.
    Da haperts wahrscheinlich noch an der Übersetzung C->BASCOM...

    mein bisheriger Fortschritt:
    Code:
    $regfile = "m32def.dat"
    
    Declare Function Crc_sae(byref Datapointer As Word , Byval Datalength As Byte) As Byte
    
    Dim Ar(10) As Byte , Pointer As Word
    Dim Crc As Byte
    
    Ar(1) = &HB2
    Ar(2) = &HD0
    Ar(3) = &HE0
    Ar(4) = &H70
    Ar(5) = &H00
    Ar(6) = &H00
    Ar(7) = &H00
    Ar(8) = &H00
    Ar(9) = &H00
    Ar(10) = &H00
    Pointer = Varptr(ar(1))
    
    Crc = Crc_sae(pointer , 10)
    Print Crc
    
    End
    
    
    Function Crc_sae(byref Datapointer As Word , Byval Datalength As Byte) As Byte
       Dim Temp As Byte , Temp2 As Byte
       Dim I As Byte , J As Byte , Crc_reg As Byte , Poly As Byte
       Crc_reg = &HFF
    
       For I = 1 To Datalength
          Temp = Inp(datapointer)
          Incr Datapointer
          For J = 7 To 0 Step -1
             If Temp.j = 1 Then
                Temp2 = Crc_reg And &H80
                If Temp2 <> 0 Then
                   Poly = 1
                Else
                   Poly = &H1C
                End If
                Shift Crc_reg , Left , 1
                Crc_reg = Crc_reg Or 1
                Crc_reg = Crc_reg ^ Poly
             Else
                Poly = 0
                Temp2 = Crc_reg And &H80
                If Temp2 <> 0 Then Poly = &H1D
                Shift Crc_reg , Left , 1
                Crc_reg = Crc_reg ^ Poly
             End If
          Next
       Next
       Crc_reg = Not Crc_reg
       Crc_sae = Crc_reg
    End Function
    mfg

  5. #5
    Hallo Netzman?,

    vielen Dank erst mal das Du Dir die Mühe gemacht hast. Jetzt wo die grobe Syntax aufgebröselt ist komme ich vieleicht selber wieder weiter....setze mich Morgen noch mal dran....

    Gruß Frank

  6. #6

    Strike !!

    ....ich hab den Code - Vielen Dank an Netzmann =D> \/

    Nur die ^ durch Xor ersetzt und es lief.

    Hier noch mal für alle die funktionierende Version:

    Crc_reg = &HFF

    For I = 1 To 10
    Temp = Ar(i)

    For J = 7 To 0 Step -1
    If Temp.j = 1 Then
    Temp2 = Crc_reg And &H80
    If Temp2 <> 0 Then
    Poly = 1
    Else
    Poly = &H1C
    End If
    Shift Crc_reg , Left , 1
    Crc_reg = Crc_reg Or 1
    Crc_reg = Crc_reg Xor Poly
    Else
    Poly = 0
    Temp2 = Crc_reg And &H80
    If Temp2 <> 0 Then Poly = &H1D
    Shift Crc_reg , Left , 1
    Crc_reg = Crc_reg Xor Poly
    End If
    Next
    Next
    Crc_reg = Not Crc_reg

    Das war die härteste Nuss im Projekt, jetzt kanns weiter gehen

    Bis Bald
    Frank

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.08.2004
    Ort
    Graz
    Beiträge
    342
    *stirnklatsch*

    mfg

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad