Forum: Mikrocontroller und Digitale Elektronik Makro überspringen


von Elbegucker (Gast)


Lesenswert?

Hallo zusammen

Gibt es eine Möglichkeit ein Makro zu überspringen?

In meinem Quelltext wollte ich sowas nutzen:

  sbrc   key_now,   5
  text_to_lcd     Einstellungen_sehen
  sbrc   key_now,   6
  text_to_lcd     Einstellungen_aendern

Soll soviel heißen wie: Wenn Taster 5 gedrückt, dann "Einstellungen 
sehen" auf LCD. Wenn Taster 6, dann "Einstellungen aendern".

Nur funktioniert das ja nicht, weil das Makro mehrzeilig ist und somit 
ja nur der erste Befehl vom Makro übersprungen wird.

.macro text_to_lcd
  ldi ZL,Low(@0*2)
  ldi ZH,High(@0*2)
    rcall lcd_flash_string
.endmacro

von Carsten (Gast)


Lesenswert?

rjmp Sprungmarke       ;mitirgendeinerbedingung

   Makro

Sprungmarke:           ;?

von Elbegucker (Gast)


Lesenswert?

verstehe ich nicht ganz

von Peter R. (gelb)


Lesenswert?

Carsten meint zu recht, dass die sb.. - Befehle zum überspringen eines 
einzelnen Befehls auf mehrbefehlige Makros nicht anwendbar sind und 
daher mit 'richtigen' Verzweigungen und Sprungmarken über die Makros 
hinweg gearbeitet werden muss.
Makros sind eben nur eine Schreibhilfe, der Assemblercode wird dadurch 
nicht anders, nur das Assemblierte wird manchmal länger als man 
glaubt...

Grüße, Peter

von fubu1000 (Gast)


Lesenswert?

cpi key_now, 0x20
breq text_to_lcd
cpi key_now, 0x40
breq text_to_lcd

von Schwurbl (Gast)


Lesenswert?

Aua.

von Peter D. (peda)


Lesenswert?

fubu1000 wrote:
> cpi key_now, 0x20
> breq text_to_lcd
> cpi key_now, 0x40
> breq text_to_lcd

Ne, das macht was völlig anderes, denn dann sind ja alle anderen Bits 
des Ports auch einbezogen, nicht nur das richtige Tastenbit.

Wenn, dann so:
1
  sbrc   key_now,   5
2
  rcall text_to_lcd_label     Einstellungen_sehen
3
  sbrc   key_now,   6
4
  rcall text_to_lcd_label     Einstellungen_aendern
5
...
6
7
text_to_lcd_label:
8
  text_to_lcd     Einstellungen_sehen


Peter

von Kachel - Heinz (Gast)


Lesenswert?

> rcall text_to_lcd_label     Einstellungen_sehen

Kann man mit RCALL ein Makro mit Parameter aufrufen? Das wäre mir neu. 
Oder bin ich jetzt nur einem Missverständnis aufgesessen?

Statt

  sbrc   key_now,   5
  text_to_lcd     Einstellungen_sehen
  sbrc   key_now,   6
  text_to_lcd     Einstellungen_aendern

ginge z.B.:

  sbrs   key_now,   5
  rjmp label1
  text_to_lcd     Einstellungen_sehen
label1:
  sbrs   key_now,   6
  rjmp label2
  text_to_lcd     Einstellungen_aendern
label2:

Ich würde allerdings eine Routine zur Ausgabe indizierter Texte 
benutzen. Dann gibt es nur noch einen Aufruf der Routine, der Text wird 
dann anhand der Menüpunktnummer ausgewählt.

KH

von Peter D. (peda)


Lesenswert?

Kachel - Heinz wrote:
> Kann man mit RCALL ein Makro mit Parameter aufrufen?

Nein.
Ich hatte das für einen Kommentar gehalten.

> ginge z.B.:
>
>   sbrs   key_now,   5
>   rjmp label1
>   text_to_lcd     Einstellungen_sehen
> label1:

Ja, das ist die übliche Methode.
Man kann den Skip-Befehl logisch umdrehen und mit RJMP erweitern.


Peter

von Elbegucker (Gast)


Lesenswert?

Das was hier geschrieben wurde hilft mir schonmal.

Zum Thema:
>Ich würde allerdings eine Routine zur Ausgabe indizierter Texte
>benutzen. Dann gibt es nur noch einen Aufruf der Routine, der Text wird
>dann anhand der Menüpunktnummer ausgewählt.

Nunja es sind auch erst meine ersten Gehversuche. Eigentlich möchte ich 
ein Menü realisieren. Ich denke, dass man wohl mit einer State-Machine 
arbeiten muß, nur habe ich da noch nicht den Ansatz gefunden.

von Kachel - Heinz (Gast)


Lesenswert?

> Ich hatte das für einen Kommentar gehalten.

Ok, das hatte ich auch vermutet. ;-)

---

> Nunja es sind auch erst meine ersten Gehversuche.

Ist ok.

> Eigentlich möchte ich ein Menü realisieren.

Das kommt dann ein paar Schritte später, wenn Du nicht mehr anhand der 
Befehlssatzliste über die Wahl des richtigen Befehles nachdenken musst.
;-)

> Ich denke, dass man wohl mit einer State-Machine
> arbeiten muß,

Das ist schonmal richtig. Ich nutze dazu meist eine Menüpunkt-Nummer, 
die als Index auf die Menütextausgabe, auf den zu bearbeitenden 
Parameter und auf die Verzweigung zum richtigen Handler genutzt wird. 2 
Tasten zappen die Menüpunktnummer, 2 weitere den Wert (oder die 
Menügruppen) bzw. lösen Aktionen aus.

> nur habe ich da noch nicht den Ansatz gefunden.

Kommt noch, mach' erstmal den Kopf von Einsteigerhürden frei.

KH

von Kachel - Heinz (Gast)


Lesenswert?

Achja, an welcher Stelle schaust Du zur Elbe? - Vielleicht bin ich ja in 
Deiner Nähe, habe die Elbe auch öfters mal im Keller. :-(

KH

von Elbegucker (Gast)


Lesenswert?

Also ich habe jetzt meine ersten Versuche mit dem Menü gestartet.
Der Anfang der Menüführung funktioniert zumindest schonmal. Nur nimmt 
der Quelltext doch schon ziemlich überhand.

Ich beschreibe mal meinen Vorgang. Vielleicht könnt ihr mir eine 
Rückmeldung geben, ob das generell richtig ist oder ob das noch 
schneller und eleganter geht.

Zunächst einmal wird ein Unterprogramm ausgeführt, dass die Taster 
überprüft.
Wurde eine Taster gedrückt, wird auf den aktuelle State-Zustand 
überprüft und dann dorthin gesprungen.
In dem State wird/werden der/die entsprechende/n Taster abgefragt. Ist 
der Taster gedrückt worden, so wird dementsprechend der LCD-Text 
ausgegeben und der State- Zustand wird geändert.
Ist das so richtig? Oder gibt es bessere Lösungen?.
Vielleicht liegt der Grund des vielen Quelltextes auch einfach daran, 
dass ich sozusagen mehrere Untermenüs habe?


@Kachel - Heinz
>Achja, an welcher Stelle schaust Du zur Elbe? - Vielleicht bin ich ja in
>Deiner Nähe, habe die Elbe auch öfters mal im Keller. :-(
--> Dann wohl eher nicht. Schätze mal du lebst weiter im Süden.
Ich sitz hier im obersten Norden und habe hier "das Tor zur Welt".
Cu Elbegucker

von Kachel - Heinz (Gast)


Lesenswert?

Elbe:
Ich bin da rund 45 m höher...

Menü:
Es gibt verschiedene Möglichkeiten, meine ist nirgendwo abgeguckt 
(zumindest nicht bewusst) und muss auch nicht optimal sein.

Ich nutze meist 4 Tasten, links, rechts, hoch, runter.

Links und rechts zählt die Menüpunktnummer hoch und runter. unterhalb 
und oberhalb jeder Menüpunktgruppe gibt es einen Dummy-Menüpunkt, in dem 
die Menüpunktnummer auf das andere Ende der Gruppe gesetzt wird, also 
ein Ring geschlossen wird. Jede Gruppe enthält den Hauptpunkt und die 
Unterpunkte.

Hoch und runter haben je nach Menüpunkt unterschiedliche Funktion.
Im Hauptpunkt wird damit die Gruppe verlassen, also die Menüpunktnummer 
auf den Hauptpunkt der nächsten Gruppe gesetzt.
In einem Unterpunkt wird damit der Parameter geändert (Up/Down), falls 
es sich um eine Parametereinstellung handelt, oder es wird eine Aktion 
gestartet (Save, Send Data, Start Play, Go Power-Down, ...).

Die Verzweigung in den Menüpunkt-Handler erfolgt bei größeren Menüs 
vorteilhaft über Z-Pointer und IJMP (Z-Pointer auf Sprungliste, 
zweifache Menüpunktnummer draufaddieren, ijmp). Dabei kann ein Handler 
schon mal für mehrere Menüpunkte verwendet werden, wenn dasselbe (mit 
unterschiedlichen Parametern) zu tun ist.
Der Rücksprung erfolgt zu einer Routine, die die Tasten-Merker 
(Bulletproof-Entprellung nach Peter Dannegger) löscht und den Menütext 
anhand der Menüpunktnummer (als Index) ausgibt. Von da aus geht es dann 
zur Mainloop, wo nach dem Prüfen aller Jobflags und ggf. Aufrufen von 
Jobs in den Sleep (Idle) gefallen wird und bis zum nächsten Interrupt 
(meist Timer) gepennt wird.

Dient das Menü hauptsächlich zum Einstellen von Parametern, so lassen 
sich die Parameter recht vorteilhaft in einem Datenfeld mit der 
Menüpunktnummer als Index ablegen. Dauerhaft im EEP abgelegte Parameter 
können auch die Menüpunktnummer als EEP-Adresse nutzen. Im Flash kann es 
eine Tabelle mit den für jeden Parameter erlaubten Minimal- und 
Maximal-Wert geben, die bei Bedarf auch noch die Schrittweite der 
Änderung enthalten kann. Das ermöglicht es, mit einem Menüpunkt-Handler 
alle Parameteräderungen behandeln zu können.

Ich hoffe, diese Gedanken helfen Dir weiter.

KH

von Elbegucker (Gast)


Lesenswert?

Hi
habe mal wieder eine Wissenslücke.
Zur Zeit gebe ich Text auf meinem LCD ja so aus:


...
text_to_lcd     Einstellungen_anzeigen
...
text_to_lcd     Einstellungen_aendern


Wie kann ich Text unabhängig vom Tabellenname ausgeben?
Also in etwa so:

ldi temp,1
text_to_lcd, temp

Wenn temp=1, dann Einstellungen_anzeigen.

Hoffe es ist klar was ich meine.
Oder geht das über eine weitere Tabelle, die dann auf die anderen 
Tabellen verweist?

@Kachel - Heinz:
Mal sehen, ob es mir hilft. Kann ich dir noch nicht genau sagen.

von Kachel - Heinz (Gast)


Angehängte Dateien:

Lesenswert?

Am Ende der Menübehandlung steht:
1
menu3c:                 ;Änderung sichern
2
 sts paraakt,yl             ;L-Byte und
3
 sts paraakt+1,yh           ;H-Byte vom geänderten Parameter ins SRAM 
4
menuend:
5
 printt menutab,mp          ;Menütext ausgeben
6
menuend1:
7
 clr tfl                    ;Tastenflags löschen
8
 ret                        ;fertig
Damit wird der evtl. geänderte Parameter an die fixen Adressen ins SRAM 
geschrieben, damit die Ausgabe des Parameters durch die 
Indiziert-Print-Routine auf ein Steuerzeichen (Platzhalter) hin in den 
Text eingebettet werden kann. Dann wird mit dem Macro "printt" die 
Routine zum indizierten Ausgeben aus der Liste aufgerufen, menütab ist 
dabei die Liste, mp ist die Menüpunktnummer. Diese sind mittels .db im 
Flash abgelegt:
1
menutab:
2
.dw mt0,mt1,mt2,mt3,mt4,mt5,mt6
3
4
mt0:    .db 4,0
5
mt1:    .db 4,"Max. Temperatur",13,5,39,"C",0,0
6
mt2:    .db 4,"Hysterese",13,5,39,"C",0,0
7
mt3:    .db 4,"Ausschalt-Zeit",13,6," mmm:ss",0,0
8
mt4:    .db 4,"Alarmton-Start",13,5,0
9
mt5:    .db 4,"Alarmton-Sweep",13,5,0
10
mt6:    .db 4," (c) 03/2007 by",13,"################",0
wobei printt (bzw. printf, das von printt aufgerufen wird) die 
Steuerzeichen 5, 6 und 7 als Platzhalter für Einbettung von Zahlen in 
den Text interpretiert (siehe Anhang) und lcd_data folgende 
Steuerzeichen unterstützt:
;  lcd_data     ;Übergibt das Byte (ASCII-Zeichen) im Register "tmp"
                ;zur Textausgabe. Dabei sind folgende Steuerzeichen
                ;möglich:
                ;1:  Blinken ausschalten
                ;2:  akt. Ausgabe-Position als Blinkanfang setzen
                ;3:  akt. Ausgabe-Position als Blinkende setzen
                ;4:  Bildschirm löschen (mit Leerzeichen überschreiben)
                ;8:  Cursor home (ohne Löschen)
                ;13: CR, Zeilenwechsel, Rest der Zeile wird gelöscht

und 0 das Textende kennzeichnet.

Der Anhang enthält die Macros und Routinen zum Formatieren von Text, 
wobei diese ggf. weitere Routinen der Zahl-zu-ASCII-Formatierung 
aufrufen und die einzelnen ASCII-Zeichen (über lcd_data) an den 
LCD-Treiber übergeben.

Die Namensgebung der Macros und Routinen erfolgte zu einer Zeit, in der 
mir ähnlich lautende Namen aus C-Bibliotheken noch nicht begegnet waren. 
Aus heutiger Sicht hätte ich sie vermutlich anders benannt.

KH

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.