mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SD Karten Ansteuerung


Autor: klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche zur Zeit eine SD-Karte anzusprechen. Ich weis das Thema 
wurde hier häufig besprochen, aber ich finde keinen Fehler mehr.
Ich hab dazu den Code von Herrn Radig genommen und für den Pic 
verständlich (glaub ich zumindest :) ) gemacht. Nun bricht er immer nach 
Commando 1 beim Initalisieren ab. Daher wollt ich mal ebent die netten 
Leute hier fragen ob ich einen fehler im Code hab, bevor ich die 
Schaltung auseinander nehme und neu zusammenbaue.

Über eine Antwort würd ich mich freuen.

Ich benutze den Pic 18f2685 mit 20MHz Quarz.

Portdeklaration
  TRISCbits.TRISC5=0;        //Ausgang SDO
  TRISCbits.TRISC4=1;        //Eingang SDI
  TRISCbits.TRISC3=0;        //Ausgang SCK
  TRISAbits.TRISA5=1;        //_SS

  //Timer2 
  TMR2=0x00;
  PR2=0x00;
  T2CON=0b01111111;    //Preteiler 16, Postteiler 16



   SSPSTATbits.SMP=0;       // Input ist gültig in der Mitte des Clock's
  SSPCON1bits.SSPM2=0;    
  SSPCON1bits.SSPM1=1;
  SSPCON1bits.SSPM0=1;  // TMP2 Output/2, Master
  //Mode (1,1)
  SSPSTATbits.CKE=0;    // Bei steigender Flanke Datenübernahme
  SSPCON1bits.CKP=1;    // High ist passiver Zustand

  SSPCON1bits.SSPEN=1;  // SPI Ein



Auzug aus der sd.c
//############################################################################
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
unsigned char sd_init ()
//############################################################################
{
  unsigned int Timeout = 0,b;
  unsigned int CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};



Delay1KTCYx(20);

  
  //Initialisiere MMC/SD-Karte in den SPI-Mode
  for (b = 0;b<0x0F;b++) //Sendet min 74+ Clocks an die MMC/SD-Karte
    {
    sd_write_byte(0xFF);
    }
  
  //Sendet Commando CMD0 an MMC/SD-Karte
  SD_Enable();

  while(sd_write_command (CMD) !=0x01)
  {
    if (Timeout++ > 0x200)
      {
      SD_Disable();
      return(1);  //Abbruch bei Commando1 (Return Code1)
      }
  }
  //Sendet Commando CMD1 an MMC/SD-Karte
  Timeout = 0;
  CMD[0] = 0x41;  //Commando 1
  CMD[5] = 0xFF;
  while( sd_write_command (CMD) !=0x00)
  {

    if (Timeout++ > 0x400)
      {
      SD_Disable();
      return(2); //Abbruch bei Commando2 (Return Code2)
      }
  }

  //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
  SD_Disable();
  return(0);
}

//############################################################################
//Sendet ein Commando an die MMC/SD-Karte
unsigned char sd_write_command (unsigned char *cmd)
//############################################################################
{
  unsigned int tmp = 0xFF , Timeout = 0,a;

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

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

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


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

  //Wartet auf ein gültige Antwort von der MMC/SD-Karte
  while (tmp == 0xFF)  
    {
    tmp = sd_read_byte();
  
    if (Timeout++ > 500)
      {
      break; //Abbruch da die MMC/SD-Karte nicht Antwortet
      }
    }
  return(tmp);
}

//############################################################################
//Routine zum Empfangen eines Bytes von der MMC-Karte 
unsigned char sd_read_byte (void)
//############################################################################
{
//#if SPI_Mode  //Routine für Hardware SPI
  SSPBUF = 0x00;
  while (!SSPSTATbits.BF);

  return (SSPBUF);
}


//############################################################################
//Routine zum Senden eines Bytes zur MMC-Karte
void sd_write_byte (unsigned char Byte)
//############################################################################
{
  SSPBUF = Byte;   //Sendet ein Byte
  while (!SSPSTATbits.BF); //warten bis fertig
}

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Versuch es mal mit 80 clocks statt 74.
Also am Anfang statt:
for (b = 0;b<0x0F;b++)
besser:
for (b = 0;b<0x10;b++)

2. bei sd_write_byte(0xFF);
sendest du allerdings schon 255 x 8 Clock-Impulse, das ist mehr als 
nötig.
Auch würde ich nach den ersten 80 clocks die Karte enablen (vorher 
disablen) und nur ganz zum Schluß einmal desablen, das reicht.
Wenn ein falscher Wert zurückkommt bzw. timeout, wiederholst du eben 
alles noch einmal von vorne, bis es klappt. Man muß so lange senden, bis 
es klappt. Das ist von Karte zu Karte unterschiedlich.

Bei mir gehen allerdings nur MMC- und (noch) keine SD-Karten.

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.