Hallo,
ich habe in ASM einen Durchflussmesser für einen Heizölbrenner
programmiert. Nun möchte ich täglich den Zählerstand der Takte im SRAM
speichern.
Ich habe die Startadresse des Speicherbereichs festgelegt:
dat_tage: .byte 31*4 (31 Tage, byte1=Tag, byte2-4=Zählerstand).
Mit ld und st kann man aus dem SRAM schreiben bzw. lesen, das ist mir
klar. Aber wie kann ich nun die Werte an die richtige Stelle schreiben?
Ich speichere jeden Tag 4 byte. Wie finde ich die Adresse nach den
zuletzt geschriebenen bytes vom Vortag?
Am Monatsende sollen die Werte gelöscht/überschrieben werden, es geht
wieder vone los.
Kann mir jemand eine Tipp geben?
Vielen Dank
Axel
Hallo,
ich hab das jetzt so realisiert:
; Beim Tageswechsel Zählerstand Impulse im SRAM speichern
ldi zl, low(dat_tage) ; Startaddresse
ldi zh, high(dat_tage)
clr temp1
lds temp2, DoM ; Tag laden
push temp2 ; und sichern
dec temp2 ; "Datensatz" 4 byte breit
add temp2, temp2
add temp2, temp2
add zl, temp2 ; zu Startaddresse addieren
adc zh, temp1
pop temp2 ; Tag wieder herstellen
st z+, temp2 ; speichern in SRAM 1. byte
lds temp2, ImpByte3 ; Byte3 der Impulse
st z+, temp2 ; in nächstes Byte
lds temp2, ImpByte2 ; HighByte der Impulse
st z+, temp2 ; in nächstes Byte
lds temp2, ImpByte1 ; LowByte der Impulse
st z, temp2 ; in nächstes Byte
Beim Neustart überschreibe ich in einer Schleife den gesamten
Speicherbereich (31*4 byte)mit 0, damit kein "Müll" drin steht.
Ist das so korrekt?
Axel
Das hast Du etwas komisch gelöst. Man kann das vieeel einfacher machen,
wenn Du eines der Registerpaare (X, Y oder Z) frei hast.
1
Tagwechsel:
2
3
ST Z+, Datenbyte_1
4
ST Z+, Datenbyte_2
5
ST Z+, Datenbyte_3
6
ST Z+, Datenbyte_4
7
8
RET
9
10
11
Monatanfang:
12
13
LDI ZH, HIGH(dat_tage)
14
LDI ZL, LOW(dat_tage)
15
16
RET
Jeden Tag rufst Du einfach "Tagwechsel" auf und am Anfang eines Monats
(und beim ersten Start) davor noch "Monatanfang". Den Speicherbereich
zu leeren ist überflüssig.
Gruß
Jonathan
Hallo Jonathan,
verstehe ich deinen Code richtig, dass beim Neustart z.B. heute
(=12.11.) die Daten um 24 Uhr auf die erste Addresse geschrieben werden?
Bei meiner Lösung werden die Daten auf die 12. Addresse (=12*4)
geschrieben.
Mein Gedanke war, dass ich anhand des aktuellen Tages-1 auf die entspr.
Addresse springe und dann die 4 byte auslesen kann (LCD).
Axel
Hallo Axel,
im Prinzip ist Dein Programm schon richtig. Über 2 Sachen könntest Du
noch nachdenken.
1. Wenn Du nur jeden Tag nur 4 Bytes schreibst, wäre es etwas sicherer
gegen Spannungsstörungen oder -Ausfälle, wenn Du die Daten ins EEprom
schreiben würdest, sonst sind, wenn einmal in 4 Wochen irgendwas
'passiert', alle Daten weg.
2. Wenn Du die Speicherstelle mit dem Tag der Speicherung verbindest,
wie Du es gemacht hast, bräuchtest Du eigentlich den Tag nicht mehr
abspeichern, da er sich aus dem Speicherplatz ergibt.
Ich würde es so machen:
Byte 0 = Tagzahl der letzten Speicherung
Byte 3,4,5 Daten Tag 1 (*3) = 1
Byte 6,7,8 Daten Tag 2 (*3) = 6
Byte 9,10,11 Daten Tag 3 (*3) = 9
Man weiss, wo das Ende ist ( man braucht nix löschen ) und bei
Stromausfall hat man noch alle Daten.
herrmueller
Hallo Axel,
Warum wird denn der Tag nochmal im RAM gespeichert? Du hast doch schom
eine Zählvariable die den Tag enthält.
Mal angenommen du hast den Tag in einer Zählvariablen.
1
;SRAM Variablen
2
Tag_aktuell: .byte1 ; aktueller Tag [1..31]
3
Tag_anzeige: .byte1 ; anzuzeigender Tag [1..31] zum Auslesen
4
5
FLM_DATA: .byte 31*3
Zum Speichern:
1
store_tageswert:
2
lds r16,(Tag_aktuell) ; aktueller Tag [1..31]
3
dec r16 ; aktueller Tag [0..30] zum Rechnen vorbereiten
4
ldi r17,3 ; drei Datenbytes pro Tag
5
ldi ZL,byte1(FLM_DATA) ; Startadresse low Byte der Tagesmesswerte
6
ldi ZL,byte2(FLM_DATA) ; Startadresse high Byte der Tagesmesswerte
7
mul r16,r17
8
add ZL,r0
9
adc ZH,r1
10
st Z+,ImpByte3
11
st Z+,ImpByte2
12
st Z+,ImpByte1
13
subi r16,-2 ; wenn die tageswertspeicherung genau 24Uhr passiert