Forum: Mikrocontroller und Digitale Elektronik SD Karten Ansteuerung


von klaus (Gast)


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
1
  TRISCbits.TRISC5=0;        //Ausgang SDO
2
  TRISCbits.TRISC4=1;        //Eingang SDI
3
  TRISCbits.TRISC3=0;        //Ausgang SCK
4
  TRISAbits.TRISA5=1;        //_SS
5
6
  //Timer2 
7
  TMR2=0x00;
8
  PR2=0x00;
9
  T2CON=0b01111111;    //Preteiler 16, Postteiler 16
10
11
12
13
   SSPSTATbits.SMP=0;       // Input ist gültig in der Mitte des Clock's
14
  SSPCON1bits.SSPM2=0;    
15
  SSPCON1bits.SSPM1=1;
16
  SSPCON1bits.SSPM0=1;  // TMP2 Output/2, Master
17
  //Mode (1,1)
18
  SSPSTATbits.CKE=0;    // Bei steigender Flanke Datenübernahme
19
  SSPCON1bits.CKP=1;    // High ist passiver Zustand
20
21
  SSPCON1bits.SSPEN=1;  // SPI Ein

Auzug aus der sd.c
1
//############################################################################
2
//Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
3
unsigned char sd_init ()
4
//############################################################################
5
{
6
  unsigned int Timeout = 0,b;
7
  unsigned int CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
8
9
10
11
Delay1KTCYx(20);
12
13
  
14
  //Initialisiere MMC/SD-Karte in den SPI-Mode
15
  for (b = 0;b<0x0F;b++) //Sendet min 74+ Clocks an die MMC/SD-Karte
16
    {
17
    sd_write_byte(0xFF);
18
    }
19
  
20
  //Sendet Commando CMD0 an MMC/SD-Karte
21
  SD_Enable();
22
23
  while(sd_write_command (CMD) !=0x01)
24
  {
25
    if (Timeout++ > 0x200)
26
      {
27
      SD_Disable();
28
      return(1);  //Abbruch bei Commando1 (Return Code1)
29
      }
30
  }
31
  //Sendet Commando CMD1 an MMC/SD-Karte
32
  Timeout = 0;
33
  CMD[0] = 0x41;  //Commando 1
34
  CMD[5] = 0xFF;
35
  while( sd_write_command (CMD) !=0x00)
36
  {
37
38
    if (Timeout++ > 0x400)
39
      {
40
      SD_Disable();
41
      return(2); //Abbruch bei Commando2 (Return Code2)
42
      }
43
  }
44
45
  //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
46
  SD_Disable();
47
  return(0);
48
}
49
50
//############################################################################
51
//Sendet ein Commando an die MMC/SD-Karte
52
unsigned char sd_write_command (unsigned char *cmd)
53
//############################################################################
54
{
55
  unsigned int tmp = 0xFF , Timeout = 0,a;
56
57
  //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) 
58
  SD_Disable();
59
60
  //sendet 8 Clock Impulse
61
  sd_write_byte(0xFF);
62
63
  //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
64
  SD_Enable();
65
66
67
  //sendet 6 Byte Commando
68
  for (a = 0;a<0x06;a++) //sendet 6 Byte Commando zur MMC/SD-Karte
69
    {
70
    sd_write_byte(*cmd++);
71
    }
72
73
  //Wartet auf ein gültige Antwort von der MMC/SD-Karte
74
  while (tmp == 0xFF)  
75
    {
76
    tmp = sd_read_byte();
77
  
78
    if (Timeout++ > 500)
79
      {
80
      break; //Abbruch da die MMC/SD-Karte nicht Antwortet
81
      }
82
    }
83
  return(tmp);
84
}
85
86
//############################################################################
87
//Routine zum Empfangen eines Bytes von der MMC-Karte 
88
unsigned char sd_read_byte (void)
89
//############################################################################
90
{
91
//#if SPI_Mode  //Routine für Hardware SPI
92
  SSPBUF = 0x00;
93
  while (!SSPSTATbits.BF);
94
95
  return (SSPBUF);
96
}
97
98
99
//############################################################################
100
//Routine zum Senden eines Bytes zur MMC-Karte
101
void sd_write_byte (unsigned char Byte)
102
//############################################################################
103
{
104
  SSPBUF = Byte;   //Sendet ein Byte
105
  while (!SSPSTATbits.BF); //warten bis fertig
106
}

von Walter (Gast)


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.

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.