mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SD Karte - CRC Berechnung


Autor: Konstantin R. (kribel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HI Leute!

Ich habe ein bisschen Probleme mit der Checksummenberechnung der 
SD/MMC-Speicherkarten.

Das Generatorpolynom ist: G(x) = x^7 + x^3 + 1
M(x) ist die zu übertragende Nachricht.

CRC = Rest( ( M(x) * x^7) / G(x) )

So steht es im HITACHI-Datenblatt.

Sendet man nun CMD0 an die Speicherkarte hängt man als CRC 1001010 an. 
Warum?

Eigentlich müsste es doch 0 sein, oder?

Und kann es sein, dass das Generatorpolynom falsch ist? Müsste es 
eigentlich nicht G(x) = x^6 + x^3 + x^2 + 1 heißen?

Gruß
Konstantin

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht alles auch ohne CRC-Berechnung. Wenn du es doch mit machen 
möchtest, schaun noch ein weiters mal ins Datenblatt, oder nimm dir ein 
anderes Datenblatt zur Hand, oder schau dir die 100000 von Beispielen im 
Internet an.

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was konstruktives:
1. Schau dir CMD59 an.
2. G(x) = x^7 + x^3 + 1 ist richtig.
3. Da CMD0 eine Konstante ist, kannst du als CRC auch eine Konstante 
nehmen, also brauchst du die CRC nicht berechnen.

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was.

Die CRC ist 7 Bit lang. Diese 7 Bit werden in Bit 7 bis Bit 1 
gespeichert und Bit 0 ist immer 1. Steht aber alles im Datenblatt.

Autor: Konstantin R. (kribel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK Danke.

Folgendes noch. Im Datenblatt steht:

M(x) = (first bit) * x^n + (second bit) * x^(n-1) + ... + (last bit) * 
x^0

müsste es nicht so heißen?:

M(x) = (last bit) * x^n + ... + (second bit) * x^1 + (first bit) * x^0

Gruß
Konstantin

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier mal den Code den ich benutze
#ifdef MMC_CALC_CRC7
uint8_t mmcCRC7(uint8_t crc, uint8_t data) {

    crc ^= data;
    unsigned char poly = 0x89;
    for (unsigned char i = 8; i > 0; i--) {
      if ((crc & 0x80) != 0) crc ^= poly;
      crc <<= 1;
    }
    return(crc);
}
#endif

und hier in der Anwendung beim Senden eines Kommandos
uint8_t mmcCommandParam(uint8_t command, uint32_t address, uint16_t expected) {

    mmcDisable();
    mmcSend(data);

    uint8_t crc = 0;
#ifdef MMC_CALC_CRC7
    crc = mmcCRC7(crc, command);
    crc = mmcCRC7(crc, (uint8_t)(address >> 24));
    crc = mmcCRC7(crc, (uint8_t)(address >> 16));
    crc = mmcCRC7(crc, (uint8_t)(address >> 8));
    crc = mmcCRC7(crc, (uint8_t)(address));
    crc = crc | 1;
#else
    crc = 0x95;
#endif

    uint8_t result;
    uint8_t data = 0xFF;

    mmcWait();
    mmcEnable();
    for (uint8_t i = MMC_COMMAND_TRIALS; i > 0; i--) {
      mmcSend(command);
      mmcWait();
      mmcSend((uint8_t)(address >> 24));
      mmcWait();
      mmcSend((uint8_t)(address >> 16));
      mmcWait();
      mmcSend((uint8_t)(address >> 8));
      mmcWait();
      mmcSend((uint8_t)(address));
      mmcWait();
      mmcSend(crc);
      mmcWait();

      for (uint8_t j = MMC_RESPONSE_TRIALS; j > 0; j--) {
        mmcSend(data);
        mmcWait();
        result = mmcRead();
        if ((result & 0x80) == 0) break;
      }

      if ((result >= (uint8_t)(expected >> 8)) && (result <= (uint8_t)(expected))) break;

      mmcDisable();
      mmcSend(data);
      for (uint8_t j = MMC_COMMAND_DELAY -1; j > 0; j--) {
        mmcWait();
        mmcSend(data);
      }
      mmcWait();
      mmcEnable();
    }
    return(result);
}


Gruß Hagen

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.