SD-Karte, Probleme mit CMD1

Gast #1362527
Morgen,

Ich habe eine SD-Karte an einen Atmega128 mit Pegelwandler MAX3378 
angeschlossen und kann diese Karte nicht initialisieren(eine 32MB SD und 
eine microSD mit 2GB). Ich schicke via SPI das CMD0 und erhalte 0x01, 
das ist ja auch gut so ;-). Wenn ich nun die Karte Initialisieren möchte 
(CMD1) erhalte ich zuerst ein paar mal 0xff, dann einmal 0xfc und ein 
0x07 ab dann wieder 0xff.

Preudocode:
1
SPI_Init();
2
for i=0 to 15 //sync.
3
  SPI_put_char(0xff);
4
wait(5);//5s waiting
5
SPI_cs_enable(); //set cs low
6

7
SPI_put_char(0x40);
8
SPI_put_char(0x00);
9
SPI_put_char(0x00);
10
SPI_put_char(0x00);
11
SPI_put_char(0x00);
12
SPI_put_char(0x95);
13
do
14
{
15
  answer=SPI_get_char();
16
}while(answer==0xff)
17

18
rs232_send_byte(answer);//PC rec. 0x01
19

20
SPI_put_char(0x41);
21
SPI_put_char(0x00);
22
SPI_put_char(0x00);
23
SPI_put_char(0x00);
24
SPI_put_char(0x00);
25
SPI_put_char(0x01);
26
do
27
{
28
  answer=SPI_get_char();
29
  rs232_send_byte(answer);//PC rec. 0xff 0xff 0xff 0xfc 0x07 0xff 0xff (point of no return)
30
}while(answer!=0x00)

Hat jemand eine Idee? Was mache ich falsch?

glg,

Stefan
Gast #1362588
hallo,

@Rex: wo liegt dort der unterschied zu meinem code? Das einzige was ich 
gesehen: Ich sende das CMD1 mit crc=0 und das Beispiel mit crc=0x7F. 
Weiters hole ich nach dem Senden von CMD1 immer nur ein Byte ab, in dem 
beispiel wird solange das CMD1 geschickt bis die richtige antwort kommt, 
habe ich beides bei mir auch verändert, dann kommt prinzipiell immer 
0xff und hinundwieder 0xfc oder oxfe.

@Gast: Ja ich schicke 0xff bei SPI_get_char();

lg,

Stefan
#1362591
Stefan_h schrieb:
> SPI_put_char(0x41);
> SPI_put_char(0x00);
> SPI_put_char(0x00);
> SPI_put_char(0x00);
> SPI_put_char(0x00);
> SPI_put_char(0x01);

Probier mal bei CMD 0x41 im letzten Byte 0xFF zu senden statt 0x01.
Gast #1362612
Command 1 :

Deine Version :

SPI_put_char(0x41);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x01);


Version Captain.at :

SPI_put_char(0x41);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0xFF);
SPI_put_char(0xFF);

Gruß
Gast #1362621
> Wenn ich nun die Karte Initialisieren möchte (CMD1) erhalte
> ich zuerst ein paar mal 0xff, dann einmal 0xfc und ein
> 0x07 ab dann wieder 0xff.

Ich bin jetzt zu faul fuer dich das Datenblatt zu lesen, aber
soll es bei diesem Kommando denn zwei Bytes als Antwort geben?
Wenn nicht dann hast du wohl ein Problem auf niedrigstem Level,
also falscher SPI-Mode, Flankensteilheit, Reflexion auf dem Kabel.

Olaf
#1362623
Noch ein Vorschlag:


...
rs232_send_byte(answer);//PC rec. 0x01

SPI_cs_disable(); //set cs high

SPI_put_char(0xFF);

SPI_cs_enable(); //set cs low
SPI_put_char(0x41);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0xFF);
do
{
  answer=SPI_get_char();
  rs232_send_byte(answer);//PC rec.
}while(answer!=0x00)
Gast #1362680
Hi,

Danke vielmals für die vielen antworten, es war eine Kombination aller 
Antworten.

Ich habe den Code so geändert:

do
{

  SPI_cs_disable(); //set cs high
  SPI_put_char(0xFF);
  SPI_cs_enable(); //set cs low

  SPI_put_char(0x41);
  SPI_put_char(0x00);
  SPI_put_char(0x00);
  SPI_put_char(0x00);
  SPI_put_char(0x00);
  SPI_put_char(0xFF);
  do
  {
    answer=SPI_get_char();
  }while(answer==0xff);
  rs232_send_byte(answer);//PC rec.
}while(answer!=0x00)

Anscheinend muss das Commando immerwieder an die Karte geschickt werden 
und davor jedesmahl das CS auf High - ein 0xff schicken - und wieder CS 
wieder auf Low, dann das Commando schicken und auf die Anwort warten, 
die ist bei den ersten 2x 0x01 und beim dritten mal dann 0x00, also 
initialisiert. Warum das so ist, weiß ic nicht, lt. Datenblatt sollte es 
anders gehen, vieleicht hab ichs auch falsch verstanden. Egal.

Ich werd dann mal versuchen Daten zu schreiben und zu lesen, wenns nicht 
geht melde ich mich wieder ;-)

lg,

Stefan
Gast #1362707
Schön dass es funktioniert :)

Anbei noch 2 Anmerkungen.


Stefan_h wrote :

>Anscheinend muss das Commando immerwieder an die Karte geschickt werden

Richtig , was der captain.at Code ja auch beinhaltet ?!
1
st: // if there is no MMC, prg. loops here
2
  if (Command(0x41,0,0,0xFF) !=0) goto st;

>und davor jedesmahl das CS auf High - ein 0xff schicken - und wieder CS
>wieder auf Low

Laut code (und eigener zurückliegender Erfahrung) ist es wichtig die 
clock Leitung am Anfang EINMAL high und dann wider low zu ziehen.
Das Timing was im code angegeben ist, muss eingehalten werden..also 80 
Clockzyklen:
1
  PORTB |= (1 << SPICS); // disable MMC
2
  // start MMC in SPI mode
3
  for(i=0; i < 10; i++) SPI(0xFF); // send 10*8=80 clock pulses
4
  PORTB &= ~(1 << SPICS); // enable MMC

Gruß
Gast #1368134
Hallo,

mein Status ist im Moment folgender:

- Karte in Idle setzen geht
- Karte dann initialisieren geht auch

das wars dann schon :-(

Habe dann versucht 512 Bytes auf die Karte zu schreiben:
1
do
2
{
3
   SPI_put_char(0xFF);
4
   SPI_put_char(0x58);
5
   SPI_put_char(0x00);
6
   SPI_put_char(0x00);
7
   SPI_put_char(0x02);
8
   SPI_put_char(0x00);
9
   SPI_put_char(0xFF);
10
   answer=SPI_get_char();
11
}while(answer==0xFF);//CMD write block
12

13
rs232_send_hex(answer);//PC rec. 0x00
14
SPI_put_char(0xff);
15
SPI_put_char(0xff);
16
SPI_put_char(0xfe);//start block
17
for(i=0;i<512;i++)
18
{
19
  SPI_put_char(0xAA);//block
20
}
21
SPI_put_char(0xff);//dummy
22
SPI_put_char(0xff);//dummy
23
do
24
{
25
  answer=SPI_get_char();
26
  rs232_send_hex(answer);
27
}while(answer==0xFF);
28

29
answer&=0x1f;
30
rs232_send_hex(answer);//should be 0x05
31
do
32
{
33
  answer=SPI_get_char();
34
}while(answer!=0xFF);

Statt den zu erwartenden 0x05 kommt meist was anderes konnte kein Muster 
erkennen. Hatte aber schon einmal 0x05!

habe einmal versucht die Bocklänge zu setzen, erhalte als antwort nie 
0x00, meist 0x03 oder 0x01 ...:
1
SPI_Disable();
2
SPI_PutChar(0xFF);
3
SPI_Enable();
4
do
5
{
6
  SPI_put_char(0x50);
7
  SPI_put_char(0x00);
8
  SPI_put_char(0x00);
9
  SPI_put_char(0x00);
10
  SPI_put_char(0x00);
11
  SPI_put_char(0xFF);
12
  do
13
  {
14
    answer=SPI_get_char();
15
  }while(answer==0xFF);
16
}while(answer!=0x00);

Habe auch schon viele codebeispiele(http://www.captain.at, 
http://www.captain.at, uvm) ausprobiert, CMD1 geht weiter komme ich 
nicht.

Ideen?

glg,

Stefan

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.