www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik sd_card probleme block lesen


Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe folgenden Versuchsaufbau: atmega 128 über spi an einer SD Card.

initialisieren funktiniert wunderbar, CID Register auslesen usw auch. 
leider kann ich jedoch keine Blöcke vom Speicher lesen. Ich habe die 
Blocksize auf 512 gestellt und will auch einen block  (addresse 0x00-) 
also genau einen Block lesen.

Das kommando wird von der SD erkannt, aber wenn ich dann auf das 
starttoken der Daten warte 0xfe laue ich in meinen Timeout rein und der 
ist wirklich großzügig bemessen, sonst braucht kein befehl so lange.

hier der Codeausschnitt:
char readBlock_SD(char * cmd, char* buffer, int length){

  int timeout = 5000;
  // Send Command
  if(cmd_SD(cmd))
    // Return if an Error occurred
    return -1;

  // Waiting for initial transmission
  while(SPI_RECEIVE() != 0xfe && timeout){
    timeout--;
  }

  // Timeout brake
  if(timeout == 0)
    return -2;

  // Read value
  for( int i = 0; i < length; i++){
    buffer[i] = SPI_RECEIVE();
  }

  // CRC
  SPI_RECEIVE();
  // Close block
  SPI_RECEIVE();

  return 1;


}

wie gesagt bim timeout springt er raus.

ran kann das liegen??

Gruß

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spekulation!

Das Problem steckt nicht im Code oben, sondern in der Kommuniaktion mit 
der Karte. Die Karte schickt in der vorgegebenen Zeit nicht die 
erwarteten Daten.

Ich würde das Anstoßen der Blockübertragung und deren Abwicklung 
debuggen. Dazu würde ich mir ausgeben lassen, was in der Zeile 
while(SPI_RECEIVE() != 0xfe && timeout) von SPI_RECEIVE() zurückgegeben 
wird.

Programmiertechnisch ist die Zeitvorgabe mit dem Runterzählen von 
timeout "hässlich". Es kann passend getunt sein, bei der nächsten 
Compilerversion, Änderungen an der Source oder Änderungen der Taktrate 
passt es schon nicht mehr.

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie würdest du das timeout denn realisieren?

das timeout hab ich weg bekomen, ich hatte beim lesen cs nicht richtig 
gesetzt. nur bekomme ich nun nur schwachsinn gelesen. immer das gleich. 
habe die sd card mit nem hexeditor eingelesen und das was ich bekomme 
steht definitiv nicht an der stelle im MBR den ich da auslese also 
addresse 0x00

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir hier nochmal jemand helfen?? wie gesagt ich empfange immer nur 
(komischerweise 3 zeichen lang?!?!) olgende Hexzahl 0xedf. Wie kann das 
kommen??

Hier nochmal der gesammte code: read_Block_SD wir mit der Adresse 0 
aufgeruen. Das kommando wird quittiert, alles scheint ok, nur die Daten 
stimmen nicht. Liegt das an meinem umwandeln?
/**    PROTECT
 *
 * This function sends a command to the sd card and receives the answer
 * @param cmd the command to send
 * @param arg the argument send to the Card (4 Bytes)
 * @return the answer of the SD Card
 */
static char cmd_SD(char * cmd){
  /**
   * Es müssen wohl 32 byte gesendet werden,28 nutzbytes und der rest command und crd
   */
  unsigned short ret=0;
  int timeoutvar=0;


  // Release CS SD Card (low active)
  PORTB &=~(1<<SDCARD_CS);

  cmd[0] += 0x40; // put on a offset of 0x40


  SPI_SEND(cmd[0]);
  SPI_SEND(cmd[1]);
  SPI_SEND(cmd[2]);
  SPI_SEND(cmd[3]);
  SPI_SEND(cmd[4]);
  SPI_SEND(cmd[5]); // CRC Checksum

  // Wait for response
  timeoutvar=500;
  do{
    ret = SPI_RECEIVE();
    timeoutvar--;
  }while(ret == 0xFF && timeoutvar);


  // set CS SD Card (low active)
  PORTB |=(1<<SDCARD_CS);
  return ret;
}






/**
 * This function reads a block from the SD Card to the Buffer
 *
 * @param * cmd   pointer to a 6 byte array containing the command
 * @param * buffer  pointer to a buffer where the bytes could be storage
 * @param length  length of buffer
 * @return   1   if everything is all right
 *       -1  if cmd error
 *       -2  if timeout while receiving
 */
char readBlock_SD(char * cmd, char* buffer, int length){

  int timeout = 5000;
  // Send Command
  if(cmd_SD(cmd))
    // Return if an Error occurred
    return -1;

  // Release CS SD Card (low active)
  PORTB &=~(1<<SDCARD_CS);

  // Waiting for initial transmission
  while(SPI_RECEIVE() != 0xfe && timeout){
    timeout--;
  }

  // Timeout brake
  if(timeout == 0)
    return -2;
  char str[6];
  str[0]=" ";
  str[1]=" ";
  str[2]=" ";

  // Read value
  for( int i = 0; i < length; i++){
    buffer[i] = SPI_RECEIVE();
    itoa((int)buffer,str,16);
    sendStringRS232(" 0x");
    sendStringRS232(str);
    if(((i+1)%16)==0)
      sendStringRS232("\r\n");
  }

  // CRC
  SPI_RECEIVE();
  // Close block
  SPI_RECEIVE();

  // set CS SD Card (low active)
  PORTB |=(1<<SDCARD_CS);

  return 1;


}


  void SPI_SEND(char cmd){
    SPDR = cmd;
    while(!(SPSR & (1<<SPIF))){} //Wait until Byte is send

  }

  char SPI_RECEIVE(){
  SPDR = 0xff;
  while(!(SPSR & (1<<SPIF))){} //Wait until Byte is send
  return SPDR;
  }




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.