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


von Y. T. (moritzz)


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).
1
 ;*INTERRUPT durch Empfang von Daten am UART*
2
int_rxc:
3
sbi portc, 2       ;Signallampe für empfangen an
4
clr temp1                         
5
in temp1, UDR
6
7
;*erste Datenzwischenspeicherung*
8
OK_Daten_uebernehmen:
9
ST Z+, temp1
10
nop
11
cpi ZH, 0x02
12
breq highb_fertig
13
rjmp weiter_emp
14
highb_fertig:
15
cpi ZL, 0x5F
16
breq finito
17
weiter_emp:
18
reti
19
20
;*SRAM voll --> Schreibe auf SD-Karte*
21
finito:
22
sbi portc, 3
23
LDI ZH, HIGH(0x0060)         ;startadresse von sram auf 0060
24
LDI ZL, LOW(0x0060)
25
26
;*auf sd-karte schreiben*
27
CMD24:
28
rcall Kommando  
29
rcall anfang_befehl
30
31
ldi temp1, 0xFE
32
rcall sende
33
                          ;512 bytes von sram ab 0x0060 bis 0x025F in einen sektor der sd-karte schreiben
34
weiter_emp_:
35
36
LD  temp1, Z+           ;von 0060 anfangen bis:
37
rcall sende             ;daten übergeben
38
39
cpi ZH, 0x02            ;bei sram-adresse start (0x0060) + 511 ist schluss
40
breq highb_fertig_
41
rjmp weiter_emp_
42
highb_fertig_:
43
cpi ZL, 0x5F            ;bei sram-adresse start (0x0060) + 511 ist schluss
44
breq finitop
45
rjmp weiter_emp_
46
47
finitop:
48
49
////////////////////////
50
51
ldi temp1, 0x00
52
rcall sende
53
ldi temp1, 0x00
54
rcall sende
55
56
;die beiden CRC's
57
;und ende
58
59
;*Empfange Antwort der SD-Karte*
60
EMPFANG:
61
62
  ldi  temp1,  0xFF
63
  rcall  sende         ;//Wartet auf ein gültige Antwort von der MMC/SD-Karte
64
  in  temp1,  SPDR 
65
    cpi temp1, 0xFF
66
  breq empfang
67
68
69
  lp9:
70
  ldi  temp1,  0xFF
71
  rcall  sende         ;//Wartet auf ein gültige Antwort von der MMC/SD-Karte
72
  in  temp1,  SPDR 
73
74
  cpi  temp1,  0xFF      ; Antwort sollte 0x01 sein
75
  ; breq geschrieben    
76
77
    cpi temp1,  0x00
78
   breq lp9
79
80
;geschrieben
81
82
;neuer sektor:  Datum2Datum3Datum4Datum5 + 0x0200
83
add Datum5, leer ; lowest byte
84
adc Datum4, zwei ;
85
adc Datum3, leer ;
86
adc Datum2, leer ; höchstes Byte
87
88
cpi uni, 'H'
89
breq Herunterfahren
90
91
;startadresse von sram wider auf 0060
92
LDI ZH, HIGH(0x0060)
93
LDI ZL, LOW(0x0060)
94
95
reti ; und wieder zurück
96
97
;*ENDE DES SCHREIBPROZESSES*

Gruss,
Moritz

von holger (Gast)


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.

von Y. T. (moritzz)


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 !!!

von Gast (Gast)


Lesenswert?

Was sagt dein Debugger?

von Y. T. (moritzz)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

Habs jetzt nicht genau angeschaut, aber ich würde sagen, dein Fehler 
liegt hier:
1
;*erste Datenzwischenspeicherung*
2
OK_Daten_uebernehmen:
3
ST Z+, temp1
4
nop
5
cpi ZH, 0x02
6
breq highb_fertig
7
rjmp weiter_emp
8
highb_fertig:
9
cpi ZL, 0x5F
10
breq finito
11
weiter_emp:
12
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
1
.equ DeinLabel = 0x25F
und dann später im Code
1
;*erste Datenzwischenspeicherung*
2
OK_Daten_uebernehmen:
3
     ST Z+, temp1
4
     nop
5
6
     cpi ZH, High(DeinLabel)
7
;...
8
     cpi ZL, Low(DeinLabel)
9
10
     breq finito
11
weiter_emp:
12
     reti

Für Ports und Pins das gleiche.

Gruß
Sebastian

von Y. T. (moritzz)


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.

von Roland R. (roland) Benutzerseite


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

von Y. T. (moritzz)


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 !!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.