SD-Karte initialisieren

#1199191
Lesenswert?

Hallo

Zu allererst: Ich habe mich hier im Forum belesen und auch anderweitige 
Beispiele durchforstet, komme aber trotzdem nicht zu Rande.

Ich möchte die Karte mittels Software-SPI betreiben.
Beispiele für die Startinitialisierung mit 74 Takten gibt es hier ja zu 
Hauf.
Wenn man dieses Beispiel nimmt:
1
void SD_INIT (void){
2

3
  for (int b = 0;b<0x0f;b++) //Sendet min 74+ Clocks an die MMC/SD-Karte
4
  {
5
     mmc_write_byte(0xff);
6
  } 
7
}

, was steckt denn eigentlich alles in dieser Funktion mmc_write_byte 
drin?
Die konnt ich nirgends finden.

Werden da bloß einfach 8 Bit in einer For-Schleife auf den Data-Out-Pin 
des Software SPI gegeben? Oder wie kann ich mir das vorstellen?

Es war ja auch oft zu lesen, dass die Initialisierung mit 100kHz 
erfolgen soll. Heißt das nun, dass ich einfach Delays in die 
SPI-Sende-Funktion einbaue um so den Takt runterzusetzen?

Ich hoffe, die Frage ist nicht allzu lästig.
Dank Euch.
Gast #1199224
Lesenswert?

>Aber der Inhalt dieser Funktion.
>Entspricht der in etwa dem, was ich schrieb?

Was soll die denn sonst noch machen?
Kaffee kochen?

>, was steckt denn eigentlich alles in dieser Funktion mmc_write_byte
>drin?
>Die konnt ich nirgends finden.

Die wird mit Sicherheit irgendwo im Quellcode mit
drin sein. Sonst könnte man das ganze ja nicht compilieren.
Gast #1199258
Lesenswert?

>Aber dieses Codeschnipsel hab ich hier aus nem Thread gezogen, deswegen
>frag ich ja.

Aus welchem? Eine SD Init sieht viel komplizierter aus.

>Kann ich das mit den Delays so machen,

Ja, allerdings solltest du dir dann zwei mmc_write_byte()
schreiben. Eine schnelle und eine langsame.

>oder gibt es noch ne elegantere Version?

Das Hardware SPI Modul benutzen.
Gast #1201060
Lesenswert?

> Kennt denn keiner eine Übersicht über alle SPI-relevanten C-Befehle?

Die SPI des AVR wird über einige SFR-Register initialisiert und auch 
verwendet. Wenn man nun nach "winavr spi" googlet ist gleich der erste 
Treffer das hier:

http://winavr.scienceprog.com/avr-gcc-tutorial/serial-peripheral-interface-spi-of-avr-microcontrollers.html

In der Codesammlung hier gibt es auch reichlich Beispielcode.

Um das Datenblatt zu deinem AVR wirst du aber kaum herum kommen.
#1201117
Lesenswert?

Eine saubere Init sieht so aus, mit ca 100khz SPI Clock, keine Abstände 
zwischen den SPI Befehlen, die Karte hat eine festverdrahtete 
Statemachine, keinen Prozessor. Ich kann Dir allerdings auch sagen,dass 
99% der Karten mit Full Speed einwandfrei aufstarten werden. Manche 
schlafen allerdings sofort wieder ein und müssen aufgeweckt werden, 
andere bleiben an und ziehen 20ma bis man sie schlafen legt.
1
/ *********************************************************************************
2
// Initialisieren der MMC Karte nach Power On
3
// Rückgabe: 1 = ok, 0 = Fehler
4
// *********************************************************************************
5

6
byte mmc_init()
7
{
8
  byte i;
9

10
    mmc_InitSPI(SPI_SPEED);
11
    ChipSelect(devSD,0);    // MMC Karte ausschalten
12

13
  for(i=0;i<100;i++)           // initialise the MMC card into SPI mode by sending clks on
14
     SPIMMC(0xFF);
15

16
  ChipSelect(devSD,1);    // MMC ein
17

18
  // Sende CMD0 an die Karte
19
  restart_wdt();
20
  i=0;
21

22
  do {
23
    SPIMMC(0xFF);
24
    SPIMMC(0x40);           // Sende Reset command
25
    SPIMMC(0x00);
26
    SPIMMC(0x00);
27
    SPIMMC(0x00);
28
    SPIMMC(0x00);
29
    SPIMMC(0x95);  
30
    if(++i >= 50)
31
    {
32
      f_mmc_Error   = TRUE;
33
      mmc_ErrorCode = MMC_ERR_INIT;
34
      ChipSelect(devSD,0);
35
            return (0);              // Timeout, Fehler!
36
          }  
37
  } while(!mmc_response(0x01));
38

39
  SPIMMC(0xFF);
40
  SPIMMC(0xFF);
41
  SPIMMC(0xFF);
42
  
43
  // Sendet CMD1 wiederkehrend an die Karte
44
  i = 0;
45
  restart_wdt();
46
  do  {
47
    SPIMMC(0xFF);
48
        SPIMMC(0x41);            // sende mmc Kommando um Idle Mode zu beenden
49
        SPIMMC(0x00);            // Alle Parameter sind 0x00
50
        SPIMMC(0x00);
51
        SPIMMC(0x00);
52
        SPIMMC(0x00);
53
        SPIMMC(0xFF);            // Checksumme ist immer 0xff
54
    if(++i >= 50)
55
    {
56
      f_mmc_Error = TRUE;
57
      mmc_ErrorCode = MMC_ERR_INIT1;
58
         return (0);              // Timeout, Fehler!
59
       }
60
  } while(!mmc_response(0));
61

62
  ChipSelect(devSD,0);
63
  f_mmc_Error = FALSE;
64
  mmc_ErrorCode = NO_ERROR;
65

66
  mmc_reset();
67

68
  return (1);
69
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren