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
Stichwort: ST X+, r Beim Monatsanfang musst Du das X-Register neu laden (LDI).
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 |
14 | sts (Tag_aktuell),r16 |
15 | ret |
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 |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.