Forum: Mikrocontroller und Digitale Elektronik SD-Karte mit Mega644 & Software von Ulrich Radig


von Pal .. (pal)


Lesenswert?

Hallo,

ich versuche gerade Dateien von eine SD-Karte einzulesen. Allerdings 
scheitere ich bereits am Anfang.

Ich habe eine Mega644 (mit 16MHz & Hardware SPI) und versuche über die 
Routine von Ulrich Radig die SD-Karte einzulesen.

Nach dem Einschalten der Spannung erhalten ich auch diese Meldungen:
1
System Ready!
2
Karte gefunden!!

Danach ist auch schon Schluss und der Code bleibt an der Stelle
1
while (mmc_read_byte() != 0xfe){};
stehen.

Ich kann leider nicht erkennen wo das Problem steckt. Kann mir jemand 
auf die Sprünge helfen?

Vielen Dank!


mfg
pal

von Falk B. (falk)


Lesenswert?

Zeile 42, siehe Netiquette.

von Pal .. (pal)


Lesenswert?

Sorry, Sorry, Sorry...... hab vergessen den Code zu posten
Danke für den Hinweis :-)
1
while (mmc_read_byte() != 0xfe){};

Die Funktion....
1
//############################################################################
2
//Routine zum Empfangen eines Bytes von der MMC-Karte 
3
unsigned char mmc_read_byte (void)
4
//############################################################################
5
{
6
  unsigned char Byte = 0;
7
#if SPI_Mode  //Routine für Hardware SPI
8
  SPDR = 0xff;
9
  while(!(SPSR & (1<<SPIF))){};
10
  Byte = SPDR;
11
12
#else      //Routine für Software SPI
13
  for (unsigned char a=8; a>0; a--) //das Byte wird Bitweise nacheinander Empangen MSB First
14
    {
15
    MMC_Write &=~(1<<SPI_Clock); //erzeugt ein Clock Impuls (Low) 
16
    
17
    if (bit_is_set(MMC_Read,SPI_DI) > 0) //Lesen des Pegels von MMC_DI
18
        {
19
        Byte |= (1<<(a-1));
20
        }
21
      else
22
        {
23
        Byte &=~(1<<(a-1));
24
        }
25
    MMC_Write |=(1<<SPI_Clock); //setzt Clock Impuls wieder auf (High)    
26
    }
27
#endif
28
  return (Byte);
29
}

von c-hater (Gast)


Lesenswert?

pal ... schrieb:

>   while(!(SPSR & (1<<SPIF))){};

Das ist die einzige Stelle in der ganzen Routine, wo was hängen bleiben 
könnte. Und es bleibt nur unter genau einem Umstand dort hängen: wenn 
das Hardware-SPI nicht korrekt initialisiert wurde.

Ich tippe darauf, daß du schlicht nicht die richtige Partdefinition 
included hast. Beachte insbesondere: es gibt einen Mega644 und auch 
einen Mega644_P_.

von Wusel D. (stefanfrings_de)


Lesenswert?

Und jetzt die Preisfrage: Nutzt Du Hardware SPI oder Software SPI?

Wenn Du Hardware SPI nutz, dann hängt er wohl dort:

while(!(SPSR & (1<<SPIF))){};

Oder anders gesagt: Die Karte antwortet nicht. Ist die 
Spannungsversorgung der SD zuverlässig aud ausreichend belastbar 
realisiert?  Bedenke, dass manche Karten einige hundert mA brauchen!

@edit: c-hater hat vermutlich Recht. Ich hatte nicht bedacht, dass der 
Empfang bei SPI Kommunikation vom AVR aus getaktet wird (ander als 
UART).

von Falk B. (falk)


Lesenswert?

@ Stefan Nie (stefanfrings_de)

>Wenn Du Hardware SPI nutz, dann hängt er wohl dort:

>while(!(SPSR & (1<<SPIF))){};

Das Problem ist, dass die SPI einen kleinen Bug hat. Vor der ersten 
Abfrage nach dem Programmstart und Initialisierung muss man ein 
Dummybyte senden, damit SPIF auf HIGH geht. Nach dem Reset ist es 
nämlich LOW :-(

von Pal .. (pal)


Angehängte Dateien:

Lesenswert?

Vielen Dank schon einmal für die Antworten!

Ich nutze den ATMEGA644 20PU und im AVRStudio include ich ebenfalls den 
ATmega644 (siehe Bild).

Stimmt, die Spannungsversorgung könnte ich noch prüfen.

mfg

von Pal .. (pal)


Lesenswert?

@Falk: Ich habe den Code jetzt wie folgt angepasst
1
#if SPI_Mode  //Routine für Hardware SPI
2
  SPDR = 0xff;
3
  SPSR = (1 << SPIF);    // TEST
4
  while(!(SPSR & (1<<SPIF))){};
5
  Byte = SPDR;

Leider keine Verbesserung.

von Davis (Gast)


Lesenswert?

pal ... schrieb:
> @Falk: Ich habe den Code jetzt wie folgt angepasst
>
>
1
#if SPI_Mode  //Routine für Hardware SPI
2
>   SPDR = 0xff;
3
>   SPSR = (1 << SPIF);    // TEST
4
>   while(!(SPSR & (1<<SPIF))){};
5
>   Byte = SPDR;
>
> Leider keine Verbesserung.

>>>> #if SPI_Mode

Wo ist SPI_Mode definiert?

Du musst deinen Code vollständig posten.

von Pal .. (pal)


Angehängte Dateien:

Lesenswert?

Wollte euch nicht mit mehr Code zumüllen wie notwendig.
Im Anhang der vollstänige Code von Ulrich Radig.

von Falk B. (falk)


Lesenswert?

@ pal ... (pal)

>@Falk: Ich habe den Code jetzt wie folgt angepasst

Nicht sinnvoll. Das Bit kann man nur lesen, nicht schreiben.
Ausserdem war ich etwas auf dem Holzweg. Den Fehler entsteht nur, wenn 
man ZUERST das Bit abfragt und dann das nächste Byte sendet. Das macht 
man so bei geschwindigkeitsoptimierter SPI-Übertragung.

Was ist denn dein Ziel? Bissel mit dem Code rumspielen oder eine einfach 
nutzbare SD-Kartenanbindung. Für letzteres kann ich wärmstens die Lib 
von ELM Chan empfehlen, hab ich vor einigen Wochen gemacht, lief 
problemlos von Anfang an.

http://elm-chan.org/fsw/ff/00index_e.html

von Pal .. (pal)


Lesenswert?

Falk Brunner schrieb:
> Was ist denn dein Ziel? Bissel mit dem Code rumspielen oder eine einfach
> nutzbare SD-Kartenanbindung.

--> SD-Kartenanbindung!

Ok, dann werde ich diesen Code mal probieren.

Mein Problem ist nur, dass ich auf meine 644er auch nich andere Aufgaben 
zu erledigen habe wie nur das bisschen SD-Karte lesen. Daher kam mir der 
Code von Ulrich Radig sehr gelegen, da dieser wenig Speicher benötigt.

Vielen Dank für Eure Bemühungen!

Und auf eine Neues :-)

von c-hater (Gast)


Lesenswert?

Falk Brunner schrieb:

> Das Problem ist, dass die SPI einen kleinen Bug hat.

Das ist kein Bug, sondern korrektes Verhalten, exakt entsprechend der 
Dokumentation.

Es ist halt nur anders, als vielleicht von den UARTs gewohnt. Davon wird 
es aber noch lange nicht nicht zum Bug.

> Vor der ersten
> Abfrage nach dem Programmstart und Initialisierung muss man ein
> Dummybyte senden, damit SPIF auf HIGH geht.

Genau das macht der Code doch auch völlig korrekt direkt vor der 
Warteschleife.

Wie schon gesagt: Die einzige Möglichkeit für den Hänger ist, daß das 
Hardware-SPI nicht korrekt initialisiert wurde, ansonsten würde zwingend 
nach acht SPI-Takten das Bit gesetzt sein. Jedenfalls, wenn der 
entsprechende Interrupt nicht erlaubt ist, was aber ohne entsprechende 
ISR zum Reset führen würde.

von Falk B. (falk)


Lesenswert?

@pal ... (pal)


>Mein Problem ist nur, dass ich auf meine 644er auch nich andere Aufgaben
>zu erledigen habe wie nur das bisschen SD-Karte lesen.

Dafür gibt es Einstellmöglichkeiten und wenn es SEHR klein sein 
soll/muss das PetitFS.

http://elm-chan.org/fsw/ff/00index_p.html

Mit nahezu voller Konfiguration braucht FatFS ca. 20kB Flash und etwas 
mehr als 1 kB RAM.

von holger (Gast)


Lesenswert?

>Danach ist auch schon Schluss und der Code bleibt an der Stelle
>
>while (mmc_read_byte() != 0xfe){};

Na dann hast du ja hoffentlich nicht auch die Beschaltung
von ihm mit Spannungsteilern am SPI benutzt. Das taugt nichts.

von Pal .. (pal)


Angehängte Dateien:

Lesenswert?

c-hater schrieb:
> Wie schon gesagt: Die einzige Möglichkeit für den Hänger ist, daß das
> Hardware-SPI nicht korrekt initialisiert wurde, ansonsten würde zwingend
> nach acht SPI-Takten das Bit gesetzt sein. Jedenfalls, wenn der
> entsprechende Interrupt nicht erlaubt ist, was aber ohne entsprechende
> ISR zum Reset führen würde.

Ok, aber wie kann ich das überprüfen?

> Na dann hast du ja hoffentlich nicht auch die Beschaltung
> von ihm mit Spannungsteilern am SPI benutzt. Das taugt nichts.

Nein, den Spannungsteiler habe ich nicht verwendet.
Im Anhang ist zu sehen, wie der Mega644 an die SD-Karte angeschlossen 
wurde.

von Jim M. (turboj)


Lesenswert?

pal ... schrieb:
> Im Anhang ist zu sehen, wie der Mega644 an die SD-Karte angeschlossen
> wurde.

Wenn der Mega644 mit 5 Volt betrieben wird - die 2 Dioden lassen das 
vermuten - dann fehlen da Levelshifter auf den Datenleitungen. Auch an 
den Datenleitungen darf nicht mehr als 3,6 Volt anliegen.

Außerdem fehlen Pullups an den Datenleitungen, eine SD Karte ist vor der 
Initialisierung "open drain".

Der gepostete Code funktioniert übrigens nicht mit SDHC Karten > 2 GB.

von Stefan E. (sternst)


Lesenswert?

pal ... schrieb:
> Im Anhang ist zu sehen, wie der Mega644 an die SD-Karte angeschlossen
> wurde.

DO(SD-Karte) ist mit SS(Mega644) verbunden?

von Falk B. (falk)


Lesenswert?

@ Jim Meba (turboj)

>Außerdem fehlen Pullups an den Datenleitungen, eine SD Karte ist vor der
>Initialisierung "open drain".

Hehe, das ist ein böser Fehler. 10K an MISO und es könnte laufen.

von Pal .. (pal)


Lesenswert?

Jim Meba schrieb:
> Der gepostete Code funktioniert übrigens nicht mit SDHC Karten > 2 GB.

Meine MicroSD hat nur 2 GB.
Den Rest werde ich einfach nochmal überprüfen.

> DO(SD-Karte) ist mit SS(Mega644) verbunden?
Ja, DO(SD-Karte) ist am Mega mit PB4 verbunden

von Chris (Gast)


Lesenswert?

pal ... schrieb:
> Ja, DO(SD-Karte) ist am Mega mit PB4 verbunden

Das sollte aber mit MISO verbunden sein, wenn du Hardware SPI nutzt.

von Stefan E. (sternst)


Lesenswert?

pal ... schrieb:
>> DO(SD-Karte) ist mit SS(Mega644) verbunden?
> Ja, DO(SD-Karte) ist am Mega mit PB4 verbunden

Dann ist es auch kein Wunder, wenn die Software vergeblich versucht, von 
der Karte ein 0xfe zu bekommen.

Oder etwas anders ausgedrückt: diese Verschaltung ist Unsinn.

von Pal .. (pal)


Lesenswert?

Ich setzte jetzt mal einen 10k Widerstand von MISO nach 5V.
Aber was kann ich hier noch tun?

Jim Meba schrieb:
> dann fehlen da Levelshifter auf den Datenleitungen. Auch an
> den Datenleitungen darf nicht mehr als 3,6 Volt anliegen.
>
> Außerdem fehlen Pullups an den Datenleitungen, eine SD Karte ist vor der
> Initialisierung "open drain".

Was sind Levelshifter? Auf der Seite von Radig ist da keine Rede von.

von Chris (Gast)


Lesenswert?

pal ... schrieb:
> Was sind Levelshifter? Auf der Seite von Radig ist da keine Rede von.

Er wird den µC mit 3.3 V versorgen, dann kann darauf verzichtet werden.

von Falk B. (falk)


Lesenswert?

@ pal ... (pal)

>Was sind Levelshifter? Auf der Seite von Radig ist da keine Rede von.

Neudeutsch für Pegelwandler.

von Chris (Gast)


Lesenswert?

Sorry eben geschaut, er hat auch 5 V aber dafür Spannungsteiler 
eingesetzt.

von Falk B. (falk)


Lesenswert?

Beitrag "Re: SD-Karte mit Mega644 & Software von Ulrich Radig"


Uups, übersehen. Da sind zwei fette Verdrahtungsfehler drin.

MISO gehört an DO
SS gehört an \CS

von Pal .. (pal)


Lesenswert?

Falk Brunner schrieb:
> Uups, übersehen. Da sind zwei fette Verdrahtungsfehler drin.

Stimmt! Habe ich hier: http://spurtikus.de/basteln/avr_sd_mmc.html
auch festgestellt.

Ich fasse jetzt noch mal zusammen
1. MISO gehört an DO
2. SS gehört an \CS
3. 10k Widerstand von MISO nach 5V

Gehört auch ein PullUp an MOSI?

Sobald die Fehler behoben sind gehts weiter :-)

Super, vielen Dank für Eure Hilfe!!!

mfg

von Holger S. (223rem)


Lesenswert?

lese Deinen Link noch mal durch und versuche speziell dieses zu 
verstehen:

"
Nach einem allgemein anerkannten Vorgehen wie beiUlrich Radig 
beschrieben, kann die Vcc für die Karte aus 5V über den Spannungsabfall 
an zwei Dioden (je 0,7V) gewonnen werden. Die Pins CS, DI und CLK müssen 
über Spannungsteiler an den AVR angeschlossen werden, wenn dieser mit 
Spannungen >3,6V betrieben wird. Für 5V werden üblicherweise 1,8K 
Richtung AVR und 3,3K gegen Masse genommen. DO wird direkt auf den 
AVR-Eingang gelegt.
"

und kaufe Dir 'ne neue Karte.

Gruß Holger

von Pal .. (pal)


Lesenswert?

Holger Sch schrieb:
> und kaufe Dir 'ne neue Karte.

Warum :-) Wenn ich die Karte in den PC schiebe kann ich sie noch 
beschreiben. Denke nicht, dass ich sie zerschossen habe. :-)

> Die Pins CS, DI und CLK müssen über Spannungsteiler an den AVR angeschlossen 
werden

Ok, aber man kann doch auch einen Pegelwandler nutzen? So wie ich es 
verstanden habe ist dieser doch besser?

von Falk B. (falk)


Lesenswert?

@ pal ... (pal)

>1. MISO gehört an DO
>2. SS gehört an \CS
>3. 10k Widerstand von MISO nach 5V

Ja.

>Gehört auch ein PullUp an MOSI?

Nein.


>> Die Pins CS, DI und CLK müssen über Spannungsteiler an den AVR >>angeschlossen 
werden

Nur, wenn der AVR mit 5V läuft. Wenn er mit 3,3V läuft, braucht man die 
nicht. Aber der 644er läuft bei 16 MHz nur bei 5V.

>Ok, aber man kann doch auch einen Pegelwandler nutzen? So wie ich es
>verstanden habe ist dieser doch besser?

Ja,

von Pal .. (pal)


Lesenswert?

Super, dann hab ich alles richtig verstanden. Werdem ich mal an die 
Umsetzung begeben.

Vielen Dank noch mal für die Hilfe.

mfg
pal

von Holger S. (223rem)


Lesenswert?

ok pal,
dann hast Du Glück gehabt.
Klar kannst Du einen Pegelwandler in IC Ausführung verwenden, aber es 
sollte für Hobby Anwendungen (und kurzen Leitungen) auch mit R's gehen 
(bei U. Radig geht's ja auch).

Gruß Holger

von Pal .. (pal)


Lesenswert?

ok Holger, da gebe ich die wiederum Recht :-)

von dummy (Gast)


Lesenswert?

>sollte für Hobby Anwendungen (und kurzen Leitungen) auch mit R's gehen

Es ist egal ob für Hobby oder nicht. Rs sind Mist.
Hier jammern doch ständig welche rum die es so versucht haben.
Erst mit schnellem Pegelwandler ging es dann immer.

von Pal .. (pal)


Lesenswert?

Danke für den Hinweis....
Die Tendenz geht jetzt doch zum Pegelwandler!

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.