Hallo Leute,
ich versuche eine SD-Karte über SPI anzusteuern. uC (Atmega32) hängt an
einem 4Mhz Quarz. SPI Clock liegt bei 250kHz. Für den Fall, dass die
SD-Card nicht mit dem antwortet, was ich erwarte bzw. garnicht
antwortet, schreibt der uC mir den Response mit einer 1 als MSB auf mein
LCD (MSB sollte eigentlich immer 0 sein). Auf dem LCD landet eine 128,
also gibt SD_Command eine 0 zurück. Das sollte nur passieren, wenn die
SD Karte garnicht antwortet.
- Pegel an der SD-Card stimmen (3,3V und 0V)
- Anschluss des SPI über kleine Kabel ~17cm (schon zu lang?)
- x-Mal richtigen Anschluss geprüft.
- /SS Pin als Output
- keine Warnungen / Fehler des Compilers (avr-gcc mit Atmel Studio 4)
Hat jemand eine gute Idee (ich nehm auch ne blöde - wenns klappt ;) ),
woran es liegen könnte?
Hier der Code (eigentlich schön in Header und C-Files ausgegliedert)
Das sind genau die Antworten die ich haben will :D
Ist wie mit Rechtschreibfehlern in seinem eigenem Text - man sieht die
offensichtlichen Sachen nicht.. Keine Ahnung was ich da wollte ;)
Ich probiers mal aus! Danke
@ Klaus Peter (phoenix89)
>leider immer noch nicht :(
Betreibe eine systematische Fehlersuche. Erstmal muss deine SPI
Daten, Takt, und SS ausspucken, egal ob die Karte reagiert oder nicht.
Prüfe das mit einem Oszi oder Logic Analyzer. Dann geht es weiter.
>Hier der Code (eigentlich schön in Header und C-Files ausgegliedert)
Warum kopierst du das dann zusammen anstatt sinnvollerweise die
einzelnen Dateien als Anhang zu senden? Siehe Netiquette.
Versuche mal eine der vorhandenen Libs für SD Karten an Deine
Pinbelegung anzupassen, das wird einfacher sein. Die Ansteuerung ist
nicht ganz trivial,
und Deine Kommandos funktionieren spätestens bei SDHC Karten so nicht
mehr.
Deine SD_Command() Funktion würde IMHO im Zweifelsfalle wichtige
Antwortbytes verschlucken, z.B. beim Lesen von Registern.
// response isnt 0xFF, so wait until something else is send
9
for(i=0; i<read; i++) {
10
if(buffer[i] != 0xFF)
11
resp = buffer[i];
12
}
Der part ist wohl Fehlerhaft. Die Karte muss die Response nicht sofort
nach dem Command schicken. Es wird aber direkt angefangen die Anzahl
bytes von "read" zu lesen, ohne zu prüfen ob die Karte tatsächlich Daten
schickt. Danach wird die Karte unselektiert, der untere Code bewirkt
also nichts mehr.
Ein korrektes CMD 0 sollte indes ausreichen.
Nachtrag: Habs nochmal angeguckt und jetzt kapiert was hier passieren
soll.
Bei welchem Command bekommst du denn die Response 0, wo genau bleibt es
hängen? Response 0 bedeutet eigentlich "OK".
a = SD_Command(_SD_Init, 0x00000000, 0xFF, 8)) != 1
SD_Init bzw. CMD1 SEND_OP_CMD wird dir eine response 01 zurück liefern
solange die Karte beschäftigt ist, sobald sie bereit für weitere
Commands ist wird sie eine Response 00 Antworten.
Gruss
und resp = 0xFF initialisiert.
Auf dem LCD erscheint nun "255". Heißt, auf dem BUS liegt ständig
"high".(?)
Hab blöderweise grade kein Logic Analyzer zur Hand und komme auch erst
nächste Woche an einen ran...
Falk B. schrieb:> @ Klaus Peter (phoenix89)>>> ... da fehlt doch was! (; am Ende von while..)>> Eine der bösen Stolperfallen von C, die man der Sprache zu recht> anlastet!
Das sehe ich anders. Viele moderne Sprachen wie Java, Javascript, PHP,
glsl, etc. ermöglichen genau das auch. Nur in alten sprachen wie z.B.
bash, wo es ein "done" oder basic mit end while, oder die Andersartigen
wie Python mit Einrückung haben dass nicht. Ich persönlich will die
Sonderzeichen nicht missen.
for(i=0;i<10&&SPI_Write(0xFF)!=0x00;i++);// wait for 0
15
for(i=0;i<10&&SPI_Write(0xFF)!=0xFE;i++);// wait for data
16
17
for(i=0;i<offset;i++)// "skip" bytes
18
SPI_Write(0xFF);
19
20
for(i=0;i<length;i++)// read length bytes
21
buffer[i]=SPI_Write(0xFF);
22
23
for(i+=offset;i<512;i++)// "skip" again
24
SPI_Write(0xFF);
25
26
// skip checksum
27
SPI_Write(0xFF);
28
SPI_Write(0xFF);
29
30
CS_DISABLE();
31
}
In der Main aufgerufen mit:
1
SD_read(0,3,&SD_Buffer,8);
In der angehängten Datei gibts den Verlauf + den ersten Sektor der
SD-Card.
Was mich verwundert ist, dass das "Gerümpel" immer das gleiche ist,
jedoch nicht auf der SD-Card zu finden (muss ja aber irgendwo sein?).
Die letzten 2 Bytes sind CRC und die davor stimmen mit dem was drauf
sein soll überein..
@ Daniel Abrecht (daniel-a)
>> Eine der bösen Stolperfallen von C, die man der Sprache zu recht>> anlastet!>Das sehe ich anders. Viele moderne Sprachen wie Java, Javascript, PHP,>glsl, etc. ermöglichen genau das auch.
Das macht es nicht besser.
> Nur in alten sprachen wie z.B.>bash, wo es ein "done" oder basic mit end while, oder die Andersartigen>wie Python mit Einrückung haben dass nicht. Ich persönlich will die>Sonderzeichen nicht missen.
Welche Sonderzeichen? Das ;?
In Pascal wäre das nicht passiert, denn dort gibt es IMMER ein begin und
end; Wenn es in C wengigstens immer die Klammern zwingend gäbe, würde so
ein (Tipp)fehler nicht passieren. Was gewinnt man effektiv durch das
Weglassen von ZWEI Klammern?