Hallo Gleich zu Beginn: ich nutze den Code von....tatatata...einem alten Bekannten, von Ulrich Radig. Nutze den Software-SPI. Bei Herrn Radigs "Read-Routine" wird ja das 1. von der Karte gesendete Bit an Bitposition 7 der jeweiligen Antwort-Variable geschrieben. Das letzte Bit ist demnach an Position 0 der Antwort-Variable. In angefügter Application Note befindet sich auf Seite 4 die Aufschlüsselung der Antwortbits. Bei meiner Initialisierung, also erstmal dem Senden von CMD0 bekommt bei mir das Bit 7 der Antwortvariable eine 1 und alle anderen Bits sind 0.(Ich lasse mir die Bits durch unterschiedlich langes Blinken einer LED ausgeben) Doch dies bedeutet ja, dass die Reihenfolge genau umgekehrt ist. Jetzt ist halt die Frage: ist der Code von Ulrich Radig verkehrt(wohl eher auszuschließen), die Reihenfolge in diesem PDF vertauscht(in anderen PDFs ists aber auch so rum), oder was anderes nicht in Ordnung. Mich macht ja stutzig, dass im Radig-Code ja auch auf 0x01 abgefragt wird, also 0b00000001. Wenn ich den Code richtig deute, sieht es in meiner Antwortvariable aber so aus: 0b10000000. Bin grad ganz konfus, bitte gebt mir etwas Support.
>Nutze den Software-SPI. Selber schuld ;) >Wenn ich den Code richtig deute, sieht es in >meiner Antwortvariable aber so aus: 0b10000000. Da wird sicherlich einiges an Bitschiebereien drin sein. Du deutest den Code falsch.
"Da wird sicher..." Also wenn du den Code gar nicht kennst, kannst du doch nicht solche Vermutungen anstellen. Das mit dem Software-SPI ging halt nicht anders. Aber so wie's aussieht haut das ja hin, nur stimmt halt die Reihenfolge der Bits aus irgendeinem Grund nicht, den es hier noch rauszufinden gilt. Hier noch mal die relevante Stelle:
1 | unsigned char Input=0; |
2 | unsigned char a; |
3 | |
4 | for (a=8; a>0; a--) //(das Byte wird Bitweise nacheinander Empangen MSB First) |
5 | { |
6 | SD_WRITE &=~ (1<<SD_SCLK); //(erzeugt ein Clock Impuls Low) |
7 | |
8 | if (bit_is_set(SD_READ,SD_GET_DATA) > 0) //(Lesen des Pegels von SD_GET_DATA) |
9 | Input |= (1<<(a-1)); |
10 | |
11 | else |
12 | Input &=~(1<<(a-1)); |
13 | |
14 | |
15 | _delay_us(3); |
16 | |
17 | SD_WRITE |= (1<<SD_SCLK); //setzt Clock Impuls wieder auf (High) |
18 | } |
19 | |
20 | return(Input); |
Hallo, ohne jetzt irgendwo nachzuschauen: dann schieb eben anderslang... Kostet doch nur 2 Minuten, das zu testen und spätestens bei der nächsten Antword der Karte weißt Du, ob es so ist. Gruß aus Berlin Michael
Sehr seltsam. Laut Spezifikation wird von der Antwort zuerst das MSB, also Bit 7 gesendet und das muss ja immer 0 sein. Bei mir kommt aber zuerst eine 1. Nach dem Reset erhalte ich zuerst 0xFF und im nächsten Durchlauf kommt dann 0x80. Das hab ich mit 3 SD-Karten ausprobiert. Immer das selbe Bild. Es ist zum Verzweifeln.
>Nach dem Reset erhalte ich zuerst 0xFF und im nächsten Durchlauf kommt >dann 0x80. Vieleicht wartet die eigentliche 1 ja noch darauf abgeholt zu werden. Ulrich benutzt da eine merkwürdige Clock Reihenfolge. Bei meinen Hardware SPI Routinen nehme ich immer Mode 0. Dort ist Clock Idle Low. Also versuch doch mal Clock erst auf high und dann auf low zu ziehen. Genau umgekehrt wie in seinem Code. Beim lesen und beim schreiben dann natürlich.
Hat leider nix gebracht.jetzt ist es nämlich so, dass als Antwort nur noch 0x00 kommt. Ich habe als SD-Slot einen alten USB-Kartenleser genommen. Da hängen auf der Unterseite noch ein IC und paar Bauelemente dran. Könnten die evtl nen Einfluss auch die Werte nehmen? Ich habe meine Drähte direkt an die rausschauenden Kontakte dieses SD-Slots angeschlossen.
Ich habe der SD-Karte jetzt mal diese Kommando geschickt:
1 | unsigned char CMD[] = {0x40,0,0,0,0,0}; |
und es kommt immer dieselbe Antwort: 0x01 Da stimmt doch irgendwas nicht.
>Da stimmt doch irgendwas nicht.
Was sollte daran nicht stimmen?
Das Kommando heißt GO_IDLE_STATE.
Die Antwort ist IDLE_STATE.
Was erwartest du als Antwort? "Guten morgen" etwa?
Ach Mensch ich meinte natürlich 0x80 so wie in den Antworten vorher. Wenn's doch endlich mal 0x01 wäre!
So ich hab mal in der Routine(siehe oben) den Zählindex von 8 auf 16 erhöht und das kommt dabei heraus: 00111111 00000001 Bei einer anderen SD-karte: 01111111 00000001 Im 2. Byte scheint also der Idle-State drin zu sein. Wenn ich den Zählwert aber nun auf 8 zurücksetze, gibts folgendes Muster: 00111111 11111111 bzw. 01111111 11111111 Was ist denn da intern los???
Habe gerade selber SW für SD-Karten im SPI mode geschrieben. Den Code von U.R. habe ich mir auch mal angesehen und scheint grundsätlich korrekt zu sein (aber auch sehr experimentell). Habe jetzt meine eigene Implementierung auf Basis der Spec gemacht. Also die SD-Karte synchronisiert (byteweise) auf das Chip Select Signal. Das GO_IDLE Kommando muss eine korrekte CRC haben (0x95). Nach dem Senden des Kommandos musst du solange ganze Bytes lesen bis in einem Byte Bit7 '0' ist (oder Tiemout). Das ist die Antwort der Karte auf dein Kommando.
So es läuft jetzt(voraussichtlich, ich bekomme auf CMD0 ne 0x01 und auf CMD1 eine 0x00). Evtl. hatte ich in meiner Visualisierung irgendwo nen Fehler und intern hat's schon wunderbar funktioniert.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.