www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SD Karte Initialisieren


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Habe ein Problem mit der Initialisierung einer SD-Karte(FAT16, 64MB, 
Panasonic). Ich benutze den Code von Ulrich Radig und einen AT90USB1287. 
Wenn ich die Karte nicht im Slot habe bleibt die Initialisierung stehen 
(Richtig so!) Wenn ich die Karte nun in den Slot schiebe funktioniert 
die Initialisierung bis zur While-Schleife, wo der Command 0 gesendet 
wird. Leider 'hängt' er sich dort auf und bricht wegen dem Timeout ab. 
Wenn ich nun die gesendeten Werte der SD Karte ausgebe, dann sieht es 
wie folgt aus:

Initialisiere SD Karte in SPI-Mode
SENDE Command CMD0
Byte: 63
While schleife verlassen: tmp = 63
Byte: 255
Byte: 5
While schleife verlassen: tmp = 5
Byte: 191
While schleife verlassen: tmp = 191
Byte: 255
Byte: 5
While schleife verlassen: tmp = 5
...
...
...
Byte: 255
Byte: 5
While schleife verlassen: tmp = 5
Timeout CMD0


Habe mal gelesen, dass eine 5 (MMC_ERR_OPEN_RD) ein Öffnungsfehler beim 
Lesen ist. Ist die SD-Karte schon defekt oder liegt der Fehler an einem 
anderen Ort?

Vielen Dank für die Hilfe

Gruss


Hier der Ausschnitt aus dem Code:
-------------------------------------
USART_Sende_String("Initialisiere SD Karte in SPI-Mode\n\r");
uint8_t b;
for (b = 0;b<0x0f;b++) //Sendet min 74+ Clocks an die MMC/SD-Karte
{
     mmc_write_byte(0xff);
}  

USART_Sende_String("SENDE Command CMD0\n\r");

uint8_t CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
while(mmc_write_command (CMD) !=1)
{
   if (Timeout++ > 200)
   {
  MMC_Disable();
USART_Sende_String("Timeout CMD0\n\r");
  return(1); //Abbruch bei Commando1 (Return Code1)
   }
}
-----------------------------
unsigned char mmc_write_command (unsigned char *cmd){
  unsigned char tmp = 0xff;
  unsigned int Timeout = 0;

  //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) 
  MMC_Disable();

  //sendet 8 Clock Impulse
  mmc_write_byte(0xFF);

  //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
  MMC_Enable();

  //sendet 6 Byte Commando
  unsigned char a;
  for (a = 0;a<0x06;a++) //sendet 6 Byte Commando zur MMC/SD-Karte
  {
    mmc_write_byte(*cmd++);
  }

  //Wartet auf ein gültige Antwort von der MMC/SD-Karte
  while (tmp == 0xff)  
    {
    tmp = mmc_read_byte();

    if (Timeout++ > 500)
      {
      break; 
      }
    }
  usart_write("While schleife verlassen: tmp = %i\n\r",tmp);
  return(tmp);
}

inline unsigned char mmc_read_byte (void){
  unsigned char Byte = 0;

  SPDR = 0xff;
  while(!(SPSR & (1<<SPIF))){};
  Byte = SPDR;
usart_write("Byte: %i\n\r",Byte);
  return (Byte);
}

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Karte ist nicht Defekt, kann sie unter Ubuntu ohne Probleme lesen 
und beschreiben. Das Problem muss an einer anderen Stelle sein...

Gruss

Autor: Christoph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wird die Karte angesprochen? Sehr wahrscheinlich über Hardware-SPI? 
Ich hatte das Problem, dass ich meine Karte nicht ansprechen konnte, 
solange ich den ISP-Programmer angeschlossen hatte. Evtl. hilft Dir das 
weiter.

Gruss
Christoph

Autor: roboterheld (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wahrscheinlich stimmen deine grundeinstellungswerte für den chip nicht. 
prüfe die nach.

Autor: roboterheld (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe mein kartenprogramm mit bascom geschrieben für eine sd-karte.

alles von hand reingebracht , mit shift right und links und so zu fuss 
erstellt. die zeiten sind stoppuhrzeiten und läuft. also es ist keine 
zauberei so eine billige karte zum laufen zu bringen.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christoph

Die Karte wird mit der Hardware SPI angesprochen. Über ISP programmiere 
ich den uP.

Gute Idee mit dem Ausstecken des ISP. Leider geht es damit aber 
immernoch nicht. Bekomme noch die gleichen Ausgaben...

Der uP läuft mit 16Mhz, kann es sein, dass die SPI Initialisierung 
fehlerhaft ist?

Gruss


Hier noch die SPI Initialisierung:
DDRB &= ~(1<<PINB3);  // PortB Pin 3 (SPI MISO) -> Eingang
DDRB |=  (1<<PINB2);  // PortB Pin 2 (SPI MOSI) -> Ausgang
DDRB |=  (1<<PINB1);  // PortB Pin 1 (SPI SCK) -> Ausgang
DDRB |=  (1<<PINB0);  // PortB Pin 0 (SPI CS) -> Ausgang

USART_Sende_String("Aktiviere SPI\n\r");

// Aktiviere SPI als Master mit OSC/128 
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);
// Aktiviere doppelte Geschwindigkeit
SPSR = (1<<SPI2X);

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo roboterheld

Mit welchem Datenblatt hast Du gearbeitet? Habe drum noch kein wirklich 
gutes gefunden...

Gruss

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei manchen Karten muss der SPI-Modus erst aktiviert werden.
Steht hier unter "Initialization Procedure for SPI Mode"
http://elm-chan.org/docs/mmc/mmc_e.html

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter

Das habe ich auch schon versucht, ergibt aber keinen Unterschied. Ich 
bekomme immer das gleiche Resultat.

Gruss

Autor: Gast (Gast)
Datum:
Angehängte Dateien:
  • preview image for sd.png
    sd.png
    4,65 KB, 682 Downloads

Bewertung
0 lesenswert
nicht lesenswert
Kann irgend Jemand die Zahlen deuten?

Habe noch den Schaltplan der SD-Karte und der Code SD.c angehängt. 
Vielleicht nützt es etwas...

DANKE!
// AT90USB1287 (16MHz)
//SD.c

#include "mmc.h"
#include "usart.h"

uint8_t mmc_init (void){
uint16_t Timeout = 0;

DDRB &= ~(1<<PINB3);    // PortB Pin 3 (SPI MISO) -> Eingang
DDRB |=  (1<<PINB1);    // PortB Pin 1 (SPI SCK) -> Ausgang
DDRB |=  (1<<PINB2);    // PortB Pin 2 (SPI MOSI) -> Ausgang
DDRB |=  (1<<PINB0);    // PortB Pin 0 (SPI CS) -> Ausgang

USART_Sende_String("Aktiviere SPI\n\r");

// Aktiviere SPI als Master mit OSC/128
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);

// Aktiviere doppelte Geschwindigkeit
SPSR = (1<<SPI2X);
  
int ii;
for (ii = 0;ii<0xff;ii++){};
// Setze MOSI und CS auf 1
PORTB |= (1<<PINB2);
PORTB |= (1<<PINB0);

//Initialisiert MMC/SD-Karte in den SPI-Mode
USART_Sende_String("Initialisiere SD Karte in SPI-Mode\n\r");
uint8_t b;
for (b = 0;b<0x0f;b++) //Sendet min 74+ Clocks an die MMC/SD-Karte
{
  mmc_write_byte(0xff);
}
// CS auf 0
PORTB &=~ (1<<PINB0);

//Sendet Commando CMD0 an MMC/SD-Karte (Go_Idle_State)
USART_Sende_String("SENDE Command CMD0\n\r");

uint8_t CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};

while(mmc_write_command (CMD) !=1)
{
   if (Timeout++ > 200)
   {
   MMC_Disable();
   USART_Sende_String("Timeout CMD0\n\r");
   return(1); //Abbruch bei Commando1 (Return Code1)
   }
}
USART_Sende_String("Sende Command CMD1\n\r");

//Sendet Commando CMD1 an MMC/SD-Karte
Timeout = 0;
CMD[0] = 0x41;//Commando 1
CMD[5] = 0xFF;
while( mmc_write_command (CMD) !=0)
{
   if (Timeout++ > 400)
   { 
   MMC_Disable();
   return(2); //Abbruch bei Commando2 (Return Code2)
   }
}
USART_Sende_String("SPI-MODe\n\r");
#if SPI_Mode
//SPI Bus auf max Geschwindigkeit
SPCR &= ~((1<<SPR0) | (1<<SPR1));
SPSR = SPSR|(1<<SPI2X);
#endif
  
USART_Sende_String("Disable MCC\n\r");
//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
MMC_Disable();
return(0);
}
//############################################################################
//Sendet ein Commando an die MMC/SD-Karte
unsigned char mmc_write_command (unsigned char *cmd)
//############################################################################
{
  unsigned char tmp = 0xff;
  unsigned int Timeout = 0;

  //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) 
  MMC_Disable();

  //sendet 8 Clock Impulse
  mmc_write_byte(0xFF);

  //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
  MMC_Enable();

  //sendet 6 Byte Commando
  unsigned char a;
  for (a = 0;a<0x06;a++) //sendet 6 Byte Commando zur MMC/SD-Karte
    {
    mmc_write_byte(*cmd++);
    }

  //Wartet auf ein gültige Antwort von der MMC/SD-Karte
  while (tmp == 0xff)  
    {
    tmp = mmc_read_byte();

    if (Timeout++ > 500)
      {
USART_Sende_String("Timeout Read Byte in (write command)\n\r");
      break; //Abbruch da die MMC/SD-Karte nicht Antwortet
      }
    }
usart_write("While schleife verlassen: tmp = %i\n\r",tmp);
  return(tmp);
}
//############################################################################
//Routine zum Empfangen eines Bytes von der MMC-Karte 
inline unsigned char mmc_read_byte (void)
//############################################################################
{
  unsigned char Byte = 0;

  SPDR = 0xff;
  while(!(SPSR & (1<<SPIF))){};
  Byte = SPDR;
usart_write("Byte: %i\n\r",Byte);
  return (Byte);
}
//############################################################################
//Routine zum Senden eines Bytes zur MMC-Karte
inline void mmc_write_byte (unsigned char Byte)
//############################################################################
{
  SPDR = Byte;   //Sendet ein Byte
  while(!(SPSR & (1<<SPIF))) //Wartet bis Byte gesendet wurde
  {
  }
}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll denn der Spannungsteiler an MISO ?
Das ist der Ausgang der SD Karte. Den musst
du direkt an den AVR anschließen. Und wie sind
deine 3V stabilisiert ?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Shit!!! Der MISO muss direkt mit dem uP verbunden sein!

Habe es korrigiert. Nun findet er die Karte und ich kann weitermachen.

VIELEN DANK FÜR DIE HILFE!!!

Gruss

Autor: Rudolph (Gast)
Datum:
Angehängte Dateien:
  • preview image for SD.png
    SD.png
    2,83 KB, 753 Downloads

Bewertung
0 lesenswert
nicht lesenswert
Also am MISO Spannungsteiler kann es ja wohl nicht gelegen haben?
Nun ja, vielleicht ist der ein wenig nieder-ohmig.
Aber von der SD-Karte zum Controller ist das kein Spannungs-Teiler 
sondern ein Pulldown und ein Reihen-Widerstand.

Ein Problem bekommt man ohne Spannungsteiler dann, wenn der Pin vom 
Controller aus irgendeinem Grund aktiv gegen +5V geht.

Genauso wie mit dem Spannungs-Teiler an CS der Karte diese immer dann 
aktiv geschaltet wird, wenn der Controller im Reset ist.


Die angehängte Schaltung funktioniert auf meiner Platine mit 2 MHz SPI 
ohne Probleme, schützt MISO und lässt CS nicht auf GND hängen.
Wobei meine Widerstände in 0805 sind und keine Leitung länger als 1,5 
cm...

Im Controller müssen an den Eingängen die Pullup-Widerstände aktiviert 
sein.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ist doch völlig übertrieben^^, einfach die spi-leitungen direkt mit 
dem controller verbinden und ein pull-up an den /CS, --> fertig!

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na klar kann man den Controller auch auf 3V betreiben, was aber,
wenn das nicht gewünscht ist?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
einen pegelwandler-chip nehmen, max1841 oder sowas. :-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Einfacher und billiger: 74HC4050. Verträgt Eingangsspannungen oberhalb 
Betriebsspannung.

MfG Spess

Autor: Rudolph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Blöd, dass in dem MAX1841 nur drei Level-Shifter drin sind und den man 
wahrscheinlich nur als Muster bekommen kann.

Und der 74HC4050 ist auch als TSSOP16 (5,1x6,6+ mm) ein wenig klobig. 
:-)

Autor: Hans Wurst (hans_wurst)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe mich bisher zwar noch nicht mit der Hardware für die SD-card 
beschäftigt, jedoch nutze ich sie mit Hilfe des Eval-boards EVK1100 von 
Atmel.
Vielleicht hilft dir dessen Schaltplan weiter? Ich füge ihn hier mit 
ein. Links oben siehst du die Ausgänge MOSI,usw. vom uP und rechts unten 
die Anschlüsse an den card-connector. Die nutzen dort externe pull-up 
Widerstände.

Falls dein uP jedoch keinen 3,3V Ausgang hat: laut spec 
(http://www.sdcard.org/about/memory_card/pls/Simpli...) 
darf die card nur max 3,6V erhalten.

Hoffe ich konnte weiter helfen.

Autor: Mario Eduardo (Firma: Vet. med. Uni Wien) (pfeife)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi alle,

Ichh abe so wie am Anfang des Thread beschrieben den gleichen Fehler.
Das CMD0 (0x40) kommt korrekt hinüber, die Karte Antwortet auch korrekt,
sonst ginge es ja nicht zu CMD1 (0x41) weiter. Dann kommt auch bei mir 
als Antwort die 5.

Wo war jetzt die Lösung des Problems, kann das aus dem Thread nicht ganz 
erkennen?! Auch wenn die obige Schaltung ein wenig einfach ist, die 5 
bedeutet ja, dass der Chip geantwortet hat.

Mein Adapter ist der von RIBU Elektronik mit integriertem Pegelwandler.

Gruß aus Wien, Mario

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.