PIC24FJ64GA002 - SD-Card ansteuern - falsche Response auf CMD0

OP #2833451
Lesenswert?

Hallo liebes Forum,

für ein Schulprojekt habe ich eine Platine erstellt, die mithilfe eines 
PIC24FJ64GA002 eine Micro-SD-Card beschreiben soll.

Folgenden Code habe ich dazu auf die Beine gestellt:
1
int spi_send (char u)
2
{
3
  SPI1BUF = u;
4
  while(SPI1STATbits.SPIRBF == 0);
5
  if (ucIndex < 180)
6
    {
7
    ucaInput[ucIndex] = SPI1BUF;
8
    ucIndex ++;
9
    }
10
  ucRec = SPI1BUF;
11
  return ucRec;
12
}
13

14

15
void spi_send_dummy (int k)  //sendet einen 0xFF "k-mal" mit "CS = high" !!
16
{
17
  CS = 1;
18
  while(k > 0)
19
  {
20
  k--;
21
  spi_send(0xFF);
22
  }
23
}
24

25
unsigned char spi_send_cmd (char cmd, char param1, char param2, char param3, char param4, char crc)
26
{
27
  CS = 0;
28
  cmd = cmd + 0x40;
29
  spi_send (cmd);
30
  spi_send (param1);
31
  spi_send (param2);
32
  spi_send (param3);
33
  spi_send (param4);
34
  spi_send (crc);
35
  
36
  while((ucRec && 0x80) != 0)
37
  spi_send (0xFF);
38

39
  ucResponse = ucRec;
40

41
  spi_send_dummy(1);      //lässt ein Dummy Byte durchlaufen, um der Karte clocks zu geben
42
  return ucResponse;
43
  
44
}
45

46
int main()
47
{
48
  init();
49
  int i = 125;      // 10ms bei 125kHz
50
  while(i--);
51
  
52
  CS = 1;
53

54
  spi_send_dummy (10);
55
  spi_send_cmd (0x00,0x00,0x00,0x00,0x00,0x95);
56

57
  if (ucResponse == 0x01)
58

59
  LED_ON = 1;
60

61
  else
62

63
  LED_ON = 0;
64

65
while(1);

die Antwort durch die SD-Card sollte "0x01" lauten, allerdings spuckt 
diese nur wahllose Daten aus. Ich verzweifle langsam, kann mir jemand 
sagen was ich falsch mache??

vielen Dank im Voraus, Patrick U.
OP #2833467
Lesenswert?

Codefehler meinerseits, danke!

allerdings hat es wohl nichts mit dem eigentlichen problem zu tun, da 
völlig wahllos geschickt wird, teilweise gar nichts

Edit: Bist du sicher, dass "&&" ein Fehler ist? soll eine 
"UND-Verknüpfung" darstellen und damit das MSB maskieren. (C30 von 
Microchip wird verwendet).
Gast #2833474
Lesenswert?

Bringt wahrscheinlich auch nichts, aber man weiss ja nie:
1
int spi_send (char u)
2
{
3
  SPI1BUF = u;
4
  while(SPI1STATbits.SPIRBF == 0);
5
  if (ucIndex < 180)
6
    {
7
    ucaInput[ucIndex] = SPI1BUF;
8
    ucIndex ++;
9
    }
10
  ucRec = SPI1BUF;
11
  return ucRec;
12
}

Du liest dort zweimal SPI1BUF. Das sollte man auf keinen
Fall tun wenn das SPI Modul einen FIFO hat. Mach es so:
1
int spi_send (char u)
2
{
3
 
4
  SPI1BUF = u;
5
  while(SPI1STATbits.SPIRBF == 0);
6
  ucRec = SPI1BUF;
7
  if (ucIndex < 180)
8
    {
9
    ucaInput[ucIndex] = ucRec;
10
    ucIndex ++;
11
    }
12
  return ucRec;
13
}
OP #2833503
Lesenswert?

das Problem bei deinem Code ist jedoch, dass wenn die antwort nicht 0xFF 
sondern z.B. 0x80 ist, wird die Schleife beendet (hatte ich schonmal).

Da die bits 0-6 irgendeinen Wert enthalten können, solange bit 7 (MSB) 
auf high ist, wäre das nicht gesund. (Die Weisheit kommt übrigens nicht 
von mir sondern die hab ich hier aus dem Forum)
Gast #2833598
Lesenswert?

Ein letzter Tipp:

Wenn du keinen Pullup am Ausgang der SD Karte hast sende
CMD0 einfach mehrmals. Dabei nicht zimperlich sein.
So 100 und mehr Wiederholungen versuchen.
Irgendwann klappt es dann schon.

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