Forum: Mikrocontroller und Digitale Elektronik ASM speichern in SRAM


von Axel H. (mf-futzi)


Lesenswert?

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

von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Stichwort: ST X+, r
Beim Monatsanfang musst Du das X-Register neu laden (LDI).

von benson (Gast)


Lesenswert?


von Axel H. (mf-futzi)


Lesenswert?

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

von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

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

von Axel H. (mf-futzi)


Lesenswert?

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

von Herr M. (herrmueller)


Lesenswert?

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

von Steffen H. (avrsteffen)


Lesenswert?

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
14
sts    (Tag_aktuell),r16
15
ret

von Steffen H. (avrsteffen)


Lesenswert?

Ach ja,
Zum Auslesen:
1
read_flm_data:
2
lds    r16,(Tag_anzeige)    ; anzuzeigender Tag [1..31]
3
dec    r16                  ; anzuzeigender 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
ld     rdByte3,Z+
11
ld     rdByte2,Z+
12
ld     rdByte1,Z+
13
ret

von Axel H. (mf-futzi)


Lesenswert?

Hallo Steffen,

vielen Dank, super! Ja, der Speicherplatz gibt ja schon den Tag wieder.

Werde ich dann so machen.



Axel

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.