Hallo, ich wollte zur Übung mit meinem eine Uhr basteln. Die Ausgabe erfolgt auf einem LCD. Die Uhrzeit usw. wird schon angezeigt. jetzt frage ich mich, wie ich es machen kann, dass Strings "Montag", "Dienstag" etc. "Januar", "Februar" etc. in Abhängigkeit des Wertes einer Zählvariablen ausgegeben werden können? Mein erster Ansatz sieht wie folgt aus: ******************************************* wochentag: rjmp text_1 rjmp text_2 rjmp text_3 rjmp text_4 rjmp text_5 rjmp text_6 rjmp text_7 text_1: .db "Montag",0 text_2: .db "Dienstag",0 text_3: .db "Mittwoch",0 text_4: .db "Donnerstag",0 text_5: .db "Freitag",0 text_6: .db "Sonnabend",0 text_7: .db "Sonntag",0 ****************************** um zwischen den einzelnen Strings zu wechseln, würde ich eine Zählvariable, die von 0 bis 6 zählt verwenden und davon abhängig machen, ob nun Montag, Dienstag oder so weiter ausgeben werden soll? Gibt es soetwas wie "einen bedingten Speicherzugriff"? oder wie könnte man da vorgehen?
du willst sicher nicht wirklich auf die Stringtabelle springen, denn dann würde das dort stehende als Code interpretiert. Du solltest das Z-Register mit der Adresse des jeweiligen ersten Zeichens laden und von dort aus mittels lpm die Bytes holen. Aber aus dem Ärmel schüttel ich Assembler inzwischen auch nicht mehr :-(
So einfach kannst du hier nicht indirekt zugreifen, weil die einzelnen Zeichenketten unterschiedliche Längen haben. Ergo: text_1, ... text_7 ebenfalls in eine Tabelle eintragen, und zweifach indirekt zugreifen. D.h. im ersten Zugriff wird text_n, also die Adresse der Zeichenkette gelesen, und damit wird dann auf die eigentliche Zeichenkette zugegriffen. Was die konkrete Syntax angeht: da kennst du den Atmel-Assembler besser als ich ;-)
Johann L. schrieb: > So einfach kannst du hier nicht indirekt zugreifen, weil die einzelnen > Zeichenketten unterschiedliche Längen haben. > > Ergo: text_1, ... text_7 ebenfalls in eine Tabelle eintragen, und > zweifach indirekt zugreifen. D.h. im ersten Zugriff wird text_n, also > die Adresse der Zeichenkette gelesen, und damit wird dann auf die > eigentliche Zeichenkette zugegriffen. > > Was die konkrete Syntax angeht: da kennst du den Atmel-Assembler besser > als ich ;-) Naja das wird sich noch zeigen! Also gut ergo zweifach indirekt zugreifen! dann werde ich mich mal an die Arbeit machen.
Hi >Gibt es soetwas wie "einen bedingten Speicherzugriff"? oder wie könnte >man da vorgehen? Du willst doch nicht zu deinem Text springen?
1 | |
2 | ldi r16,1 ; Tag der Woche in r16 |
3 | |
4 | ldi ZL, low(wochentag<<1) ; Tabellenadresse nach Z |
5 | ldi ZH,High(wochentag<<1) |
6 | |
7 | lsl r16 ; r16 x2 |
8 | clr r17 ; Null |
9 | |
10 | add ZL,r16 |
11 | adc ZH,r17 ; Offset addieren |
12 | lpm r16,Z+ |
13 | lpm r17,Z |
14 | movw ZH:ZL,r17:r16 ; Textadresse nach Z |
15 | |
16 | lsl ZL |
17 | rol ZH |
18 | |
19 | lpm r16,Z+ ; Erster Buchstabe nach r16 |
20 | |
21 | ...... |
22 | |
23 | wochentag: |
24 | .dw text_1 |
25 | .dw text_2 |
26 | .dw text_3 |
27 | .dw text_4 |
28 | .dw text_5 |
29 | .dw text_6 |
30 | .dw text_7 |
31 | |
32 | text_1: .db "Montag",0 |
33 | text_2: .db "Dienstag",0 |
34 | text_3: .db "Mittwoch",0 |
35 | text_4: .db "Donnerstag",0 |
36 | text_5: .db "Freitag",0 |
37 | text_6: .db "Sonnabend",0 |
38 | text_7: .db "Sonntag",0 |
MfG Spess
Hallo Spess, ich habe jetzt mal deinen Tipp versucht umzusetzen. Ich habe in der Hauptschleife (loop) alle Befehle ausser dem Aufruf der Stringausgabe "kommentarisiert". Leider wird nichts auf dem Display ausgegeben (alle Felder am LCD leuchten) Wodran mag das liegen? Ich weiss, dass man natürlich noch an der Nutzung (also wie viel und welche) der Register noch arbeiten kann!
Bei so kurzen Strings kann man aber auch einfach die Null-Bytes abzählen:
1 | ldi r16, 0 ; 0 = Montag |
2 | |
3 | ldi ZL, low(wochentag<<1) ; Tabellenadresse nach Z |
4 | ldi ZH, High(wochentag<<1) |
5 | rjmp _wt2 |
6 | wochentag: |
7 | .db "Montag",0, \ |
8 | "Dienstag",0, \ |
9 | "Mittwoch",0, \ |
10 | "Donnerstag",0, \ |
11 | "Freitag",0, \ |
12 | "Sonnabend",0, \ |
13 | "Sonntag",0 |
14 | _wt1: |
15 | lpm r0, z+ |
16 | and r0, r0 |
17 | brne _wt1 |
18 | _wt2: |
19 | subi r16, 1 |
20 | brcc _wt1 |
21 | |
22 | lpm r16, Z+ ; Erster Buchstabe nach r16 |
Peter
Hi >.def wochentag_nr_h = r26 >.def wochentag_nr_l = r27 Tausche mal die Register. MfG Spess
Spess53 schrieb: >>.def wochentag_nr_h = r26 >>.def wochentag_nr_l = r27 > > Tausche mal die Register. Ok cool jetzt klappt's. Gut wenn schon das Registerpaar r26/r27 verwendet wird, sollte das register mit der höheren nummer (r27) auch dem Highteil zugeordnet werden. Das hätte ich wohl erst in ewig und 3 Tage nicht gefunden. Vielen Dank Peter Dannegger schrieb: > Bei so kurzen Strings kann man aber auch einfach die Null-Bytes > abzählen: > ldi r16, 0 ; 0 = Montag > > ldi ZL, low(wochentag<<1) ; Tabellenadresse nach Z > ldi ZH, High(wochentag<<1) > rjmp _wt2 > wochentag: > .db "Montag",0, \ > "Dienstag",0, \ > "Mittwoch",0, \ > "Donnerstag",0, \ > "Freitag",0, \ > "Sonnabend",0, \ > "Sonntag",0 > _wt1: > lpm r0, z+ > and r0, r0 > brne _wt1 > _wt2: > subi r16, 1 > brcc _wt1 > > lpm r16, Z+ ; Erster Buchstabe nach r16 Werd ich beizeiten auch mal implementieren. Vorerst reicht mir eine funktionierende Lösungen --> später geht's dann ans optimieren
Hi >Gut wenn schon das Registerpaar r26/r27 verwendet wird, sollte >das register mit der höheren nummer (r27) auch dem Highteil zugeordnet >werden. Nur ein Grund dieses def-Gedödel zu meiden. MfG Spess
Also ich habe meine Uhr jetzt soweit realisiert: Wochentage werden angezeigt Monate habe unterschiedliche Anzahl an Tage alle 4 Jahre tritt ein Schaltjahr auf alle 100 Jahre gibt es kein Schaltjahr nach 4 Jahren außer alle 400 Jahre ob das alles Sinn macht sei erstmal dahingestellt. (in 80 oder 400 Jahren wird die Uhr eh keiner mehr nutzen) Aber egal nun zum nächsten Schritt: Ich wollte die Uhr jetzt extern über 2 Taster stellen können. Dazu wollte ich INT0 und INT1 verwenden: Die eine ISR schaltet zwischen den Stellgrößen (Stunden, Minuten, etc.) In der anderen ISR wird die jeweilige Stellgröße inkrementiert. Nun bin ich auf ein Problem gestoßen: Die Eingänge von INT0 und INT1 scheinen zu prellen. Immer wenn ich über einen Taster einen Interrupt auslöse, wird der jeweilige Zahlenwert gleich um 3, 4 oder 5 erhöht? wie kann ich den INT0 z.B. entprellen oder hat das damit doch nichts zu tun?
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten Und Tasten muss man keineswegs über Interrupts auswerten. Ganz im Gegenteil. Wenn du deine Tastenabfrage in die jeweilige Hauptschleife reinmachst, ist das mehr als schnell genug.
Karl heinz Buchegger schrieb: > Und Tasten muss man keineswegs über Interrupts auswerten. Ganz im > Gegenteil. > > Wenn du deine Tastenabfrage in die jeweilige Hauptschleife reinmachst, > ist das mehr als schnell genug. Ja ok ic glaube ich werde mich mal mit der Methode von dem Herrn Dannegger befassen. Irgendwie ist mir das aber noch nicht ganz klar. Deshalb schaue ich mir das morgen nochmal in aller Ruhe an. Mir ist aufgefallen, dass dort die unteren Register verwendet werden! Da mir jetzt auch schon aufgefallen ist, dass man doch recht schnell in "Registernotstand" gerät, wollte ich mal fragen, wie das noch mit den Registern r0 bis r15 war? Es können bei denen doch nicht alle Befehle angwendet werden? ich hab im Datenblatt dazu keine genaue Beschreibung gefunden?
Hi >... wollte ich mal fragen, wie das noch mit den >Registern r0 bis r15 war? >Es können bei denen doch nicht alle Befehle angwendet werden? Richtig: http://www.atmel.com/atmel/acrobat/doc0509.pdf Überall wo dort r16...r31 steht geht es mit den unteren Registern nicht. >Da mir jetzt auch schon aufgefallen ist, dass man doch recht schnell in >"Registernotstand" gerät,... Hast du einen Registerschwund? Ich habe immer 32 Register zur Verfügung. Noch nie einen Notstand gehabt. Aber lass mich raten: du benutzt dieses unselige .def-Gedödel und weist Registern eine bestimmte Funktion zu. Selbst schuld wenn es dann eng wird. Man muss nicht jeden Sch... mitmachen. Und wenn du davon nicht lassen kannst: einige AVRs haben auch noch GPIO-Register und RAM die meisten. MfG Spess
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.