Forum: Mikrocontroller und Digitale Elektronik Brauche Hilfe bei SHT11 CRC Berechnung


von Shtler (Gast)


Lesenswert?

Hallo Leute,

Möchte bei einem SHT11 einen CRC Check einbauen.
Der verwendete Compiler ist Mikroe Mikrobasic Pro 5.6
Die CRC_Table ist vom APPnote übernommen worden.
Aber irgendwie klappt es nicht.

Habe nun folgenden Code:

sub Function Check_SHT_CRC(dim 
Commandbyte,Databyte1,Databyte2,CRC_FromSensor As Byte) As Boolean

    Dim CRC_calculation As Byte
    CRC_calculation = 0
    CRC_calculation = CRC_Table[Commandbyte]
    CRC_calculation = CRC_calculation Xor Databyte1
    CRC_calculation = CRC_Table[CRC_calculation]
    CRC_calculation = CRC_calculation Xor Databyte2
    CRC_calculation = CRC_Table[CRC_calculation]
    CRC_calculation =  CRC_calculation xor 255 'Reverse
    If CRC_calculation = CRC_FromSensor Then
       Check_SHT_CRC = True
    Else
        Check_SHT_CRC = False
    End If

End sub


Woran könnte es liegen?
Finde im Netz leider nur Beispiele in C.
(Bitte kein Krieg über den besseren Compiler)

mfG
Shtler

von Ketner (Gast)


Lesenswert?

Muss man da nicht mit den einzelnen Bits hantieren?

von Tastkopf (Gast)


Lesenswert?

was für ein CRC soll das denn sein, geben tut es viele:
http://regregex.bbcmicro.net/crc-catalogue.htm#crc.cat.xmodem
was die eigentlich berechnung angeht(Punkt 18):
http://www.ross.net/crc/download/crc_v3.txt

wo liegt eigentlich dein problem?
SRP16 und FsumFrontEnd sind sehr nützlich tools wenn man checken will ob 
der eigene crc algoritmus richtig funzt.

von MaWin (Gast)


Lesenswert?

Kein Basic, aber so geht der ASlgorirthmus

[c]
unsigned char sbus_read(unsigned char ack,unsigned char reverse)
// reads a byte form the Sensibus and gives an acknowledge in case of 
"ack=1"
{
  unsigned char i, val;

  val=0;
  datadir(0);                        // DATA als Eingang zum Lesen
  i=(reverse?0x01:0x80);           // shift bit for masking
  while(i)
  {
    clk1();                        // clk for SENSI-BUS
    if(datain()) val|=i;       // read bit
    clk0();
    if(reverse) i<<=1; else i>>=1;
  }
  datadir(1);                        // DATA als Ausgang
  data(!ack);                     // in case of "ack==1" pull down 
DATA-Line
  clk1();                     // clk #9 for ack
  clk0();
  datadir(0);                        // DATA als Eingang zum Lesen
  return val;
}

unsigned char lut[] =
{
  0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219,
  234, 125, 76, 31, 46, 67, 114, 33, 16, 135,
  182, 229, 212, 250, 203, 152, 169, 62, 15,
  92, 109, 134, 183, 228, 213, 66, 115, 32,
  17, 63, 14, 93,108, 251, 202, 153, 168,
  197, 244, 167, 150, 1, 48, 99, 82, 124, 77,
  30, 47, 184, 137, 218, 235, 61, 12, 95,
  110, 249, 200, 155, 170, 132, 181, 230,
  215, 64, 113, 34, 19, 126, 79, 28, 45, 186,
  139, 216, 233, 199, 246, 165, 148, 3, 50,
  97, 80, 187, 138, 217, 232, 127, 78, 29,
  44, 2, 51, 96, 81, 198, 247, 164, 149, 248,
  201, 154, 171, 60, 13, 94, 111, 65, 112,
  35, 18, 133, 180, 231, 214, 122, 75, 24,
  41, 190, 143, 220, 237, 195, 242, 161, 144,
  7, 54, 101, 84, 57, 8, 91, 106, 253, 204,
  159, 174, 128, 177, 226, 211, 68, 117, 38,
  23, 252, 205, 158, 175, 56, 9, 90, 107, 69,
  116, 39, 22, 129, 176, 227, 210, 191, 142,
  221, 236, 123, 74, 25, 40, 6, 55, 100, 85,
  194, 243, 160, 145, 71, 118, 37, 20, 131,
  178, 225, 208, 254, 207, 156, 173, 58, 11,
  88, 105, 4, 53, 102, 87, 192, 241, 162,
  147, 189, 140, 223, 238, 121, 72, 27, 42,
  193, 240, 163, 146, 5, 52, 103, 86, 120,
  73, 26, 43, 188, 141, 222, 239, 130, 179,
  224, 209, 70, 119, 36, 21, 59, 10, 89, 104,
  255, 206, 157, 172
};

int sbus_measure(unsigned char command)
{
  int i,msb,lsb;
  unsigned char crc;

    if(sbus_send(command)) return -1;
  for ( i=0; i<655; i++ ) if ( !datain() ) break; // wait until sensor 
has finished the measurement
  if (datain()) return -1; // or timeout is reached
  msb = sbus_read(ACK,0); // read the first byte (MSB)
  lsb = sbus_read(ACK,0); // read the second byte (LSB)
  crc = sbus_read(noACK,1); // read checksum
  // 4 status register bits go into sent crc, but they are 0 if sensor 
is as we want it
  if(crc!=lut[lut[lut[command]^msb]^lsb]) return -1;  // crc check fails
  return (msb<<8)|lsb;
}
[/c)
Wichtig ist die 1 bei sbus_read, das kombiniert die Bits in anderer 
Reihenfolge (Bits rückwätrs) als bei den Messwerten.

von Shtler (Gast)



Lesenswert?

@MaWin
Der Code müsste "der selbe" sein wie der meinige.
Schon 10 Sensoren probiert (Plausible Werte.Erprobter Code),nur die CRC 
Prüfung geht in die Hose :-(
Habe mal das Manual für die CRC Berechnung angehängt.

Was mache ich nur falsch?

von eProfi (Gast)


Lesenswert?


von crcler (Gast)


Lesenswert?

Das ist dein Fehler:
CRC_calculation =  CRC_calculation xor 255 'Reverse

Der vom Sensor gelieferte CRC-Wert hat die Bits in umgekehrter 
Reihenfolge siehe MaWins Beitrag.
>Wichtig ist die 1 bei sbus_read, das kombiniert die Bits in anderer
>Reihenfolge (Bits rückwätrs) als bei den Messwerten.

Hab das am PC getestet
00000000 -     -     - Status
00000101 -     -     - Command
00000101 -   5 - 245
11110101 - 245
00001001 -     -     - DataByte1
11111100 - 252 - 255
11111111 - 255
00110001 -     -     - DataByte2
11001110 - 206 -  88
01011000 -  88 -     - Final CRC
10100111 -     -     - Wrong Reversed CRC (XOR 255)
11000111 -     -     - Wrong Reversed CRC (LUT)
00011010 -     -     - Sensor CRC value

Du musst also die Bits entweder beim Einlesen oder in der Berechnung 
reversieren.

von Shtler (Gast)


Lesenswert?

@: Das wars. Hatte einen Denkfehler. Dachte ich müsste die Bits 
negieren. Dankeschön :-D

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.