mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SD-Karten-SEKTOR - Warum am Ende immer 00?


Autor: Y. T. (moritzz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,

ich habe jetzt zufällig an meinem SD-Logger festgestellt, dass, egal 
welche Daten ich logge (GPS, ADC-Daten) das letzte Byte des 512Byte 
großen Sektors auf der SD-Karte immer 00 ist. Kann sowas nur am Code 
liegen?

Der Interrupt-Teil des Codes (Code für GPS-NMEA-Daten aus dem UART) 
lautet wie folgt. Es werden erst 512 Bytes im SRAM zwischengespeichert, 
um sie danach in einen Sektor auf dem Kärtchen zu schreiben. Die 
SRAM-Start Adresse ist 0060 und geht dann hoch auf 025F (also 512 
Speicherplätze).
 ;*INTERRUPT durch Empfang von Daten am UART*
int_rxc:
sbi portc, 2       ;Signallampe für empfangen an
clr temp1                         
in temp1, UDR

;*erste Datenzwischenspeicherung*
OK_Daten_uebernehmen:
ST Z+, temp1
nop
cpi ZH, 0x02
breq highb_fertig
rjmp weiter_emp
highb_fertig:
cpi ZL, 0x5F
breq finito
weiter_emp:
reti

;*SRAM voll --> Schreibe auf SD-Karte*
finito:
sbi portc, 3
LDI ZH, HIGH(0x0060)         ;startadresse von sram auf 0060
LDI ZL, LOW(0x0060)

;*auf sd-karte schreiben*
CMD24:
rcall Kommando  
rcall anfang_befehl

ldi temp1, 0xFE
rcall sende
                          ;512 bytes von sram ab 0x0060 bis 0x025F in einen sektor der sd-karte schreiben
weiter_emp_:

LD  temp1, Z+           ;von 0060 anfangen bis:
rcall sende             ;daten übergeben

cpi ZH, 0x02            ;bei sram-adresse start (0x0060) + 511 ist schluss
breq highb_fertig_
rjmp weiter_emp_
highb_fertig_:
cpi ZL, 0x5F            ;bei sram-adresse start (0x0060) + 511 ist schluss
breq finitop
rjmp weiter_emp_

finitop:

////////////////////////

ldi temp1, 0x00
rcall sende
ldi temp1, 0x00
rcall sende

;die beiden CRC's
;und ende

;*Empfange Antwort der SD-Karte*
EMPFANG:

  ldi  temp1,  0xFF
  rcall  sende         ;//Wartet auf ein gültige Antwort von der MMC/SD-Karte
  in  temp1,  SPDR 
    cpi temp1, 0xFF
  breq empfang


  lp9:
  ldi  temp1,  0xFF
  rcall  sende         ;//Wartet auf ein gültige Antwort von der MMC/SD-Karte
  in  temp1,  SPDR 

  cpi  temp1,  0xFF      ; Antwort sollte 0x01 sein
  ; breq geschrieben    

    cpi temp1,  0x00
   breq lp9

;geschrieben

;neuer sektor:  Datum2Datum3Datum4Datum5 + 0x0200
add Datum5, leer ; lowest byte
adc Datum4, zwei ;
adc Datum3, leer ;
adc Datum2, leer ; höchstes Byte

cpi uni, 'H'
breq Herunterfahren

;startadresse von sram wider auf 0060
LDI ZH, HIGH(0x0060)
LDI ZL, LOW(0x0060)

reti ; und wieder zurück

;*ENDE DES SCHREIBPROZESSES*

Gruss,
Moritz

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ich habe jetzt zufällig an meinem SD-Logger festgestellt, dass, egal
>welche Daten ich logge (GPS, ADC-Daten) das letzte Byte des 512Byte
>großen Sektors auf der SD-Karte immer 00 ist. Kann sowas nur am Code
>liegen?

Ja, dem Sektor ist es völlig wurscht was DU in das letzte
Byte reinschreibst.

Autor: Y. T. (moritzz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wär trotzdem cool, wenn jemand mal über das codefitzelchen rübergucken 
kann, wenn ich nämlich zu wenig bytes schreiben würde, würde die karte 
doch meckern! Doch ich kann definitiv sagen, dass NICHT immer von den 
Daten her das letzte Byte 0 ist - sondern eben irgendein WERT !!!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sagt dein Debugger?

Autor: Y. T. (moritzz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der ist glücklich, sowie die SD-Karte auch. Man kann wunderbar 
stundenlang werte aufzeichnen, nur es geht halt jedes 512.Byte verloren!

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs jetzt nicht genau angeschaut, aber ich würde sagen, dein Fehler 
liegt hier:
;*erste Datenzwischenspeicherung*
OK_Daten_uebernehmen:
ST Z+, temp1
nop
cpi ZH, 0x02
breq highb_fertig
rjmp weiter_emp
highb_fertig:
cpi ZL, 0x5F
breq finito
weiter_emp:
reti
Du musst hier mit 0x260 vergleichen und nicht mit 0x5F, weil du sonst 
nur 511 Byte in deinen Puffer im Sram schreibst. Und was nicht im Puffer 
ist kann natürlich auch nicht auf die Karte geschrieben werden.

Aber mal so allgemein:
wenn du den Code einrückst findet man die Sprungmarken leichter. Und 
wenn du mit .equ arbeitest wird der Code auch leichter nachvollziehbar 
und später auch leichter anpassbar, wenn sich z.B. die Hardware mal 
ändert.
statt 0x25F schreibst du dann am Anfang des Codes
.equ DeinLabel = 0x25F
und dann später im Code
;*erste Datenzwischenspeicherung*
OK_Daten_uebernehmen:
     ST Z+, temp1
     nop

     cpi ZH, High(DeinLabel)
;...
     cpi ZL, Low(DeinLabel)

     breq finito
weiter_emp:
     reti

Für Ports und Pins das gleiche.

Gruß
Sebastian

Autor: Y. T. (moritzz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
cool, danke.
Ich hab das zwar schon ausgerechnet (Da in 0x0060 ja auch schon 
gespeichert wird9, aber einen Versuch ist das auf jeden Fall Wert.
Änder ich mal testweise so.

Codedesign verbesse ich noch.

Autor: Roland Riegel (roland) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Moritz,

Wie Sebastian schon angemerkt hat, verwendest Du einen falschen 
Vergleichswert für den Z-Pointer. Du erhöhst den Pointer zuerst (Z+) und 
vergleichst erst dann, und das 512 mal, also ist der richtige 
Vergleichswert
  0x60 + 512 = 0x60 + 0x200 = 0x260

Durch Deinen zu geringen Vergleichswert werden nur 511 Bytes gepuffert, 
der Sektor enthält im letzten Byte also nur einen Zufallswert.

Gruß,
Roland

Autor: Y. T. (moritzz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, jetzt ist mir klar. Durch LD Z+ wird der ja erhöht, und DANACH 
vergleiche ich..jaaahh logisch

Top, Danke. Mein Skiurlaub inklusive GPS-Skiroutenaufzeichnung ist somit 
gerettet !!

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.