PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Menüführung



steffne
15.07.2009, 23:51
Hallo,

ich bin neu hier und möchte mich kurz vorstellen. Ich bin mit dem Abi fertig und möchte jetz ein Studium in Elektro- und Informationstechnik beginnen. Ich habe als ich 10 Jahre alt war begonnen mit QBasic zu programmieren. Ich hatte damals ein Interface von meinem Vater bekommen und über QBasic verschiedene Dinge gesteuert. (Weichen für die Modelleisenbahn, einen Roboterarm und verschiedene kleine Erfindungen). Dannach habe ich mit Blitz Basic weiter gemacht und als ich 14 war mit C++ angefangen. (Dannach folgten noch zig andere Sprachen) Inzwischen habe ich viel Zeit mit dem Schreiben von Anwendungsprogrammen, meist für Freunde aber auch für eine Firma, verbracht. Nun bin ich zu einem riesigen Metallgehäuse gekommen, was früher einen Endpunkt für den Betriebsfunk beinhaltete und möchte nun ein Computersystem aus AVRs hinein basteln. Das gehäuse funktioniert mit Einschubteilen, ist also sehr praktisch. Es soll einen Haupt(AVR)prozessor, eine Soundkarte, eine Grafikkarte und ein riesiges Interface mit möglichst vielen digitalen und analogen, bidirektionalen Ports geben. Mal sehen, was mir sonst noch so einfällt. Es ist noch viel platz.

Aber bis sahin muss ich erstmal viel Erfahrung auf dem Gebiet des AVR-Assemblers sammeln und deshalb hier schon das erste Problem:


Ich möchte eine Menüführung mit einem ATmega16 machen, die über 4 Tasten gesteuert wird und deren Ausgabe über ein LCD erfolgt.

Da der AVR nebenbei noch viele andere Aufgaben erledigen soll muss das Programm sehr effizient sein und nach jeder Tastenbedienung wieder in die Hauptschleife zurück kehren.

Ich habe mir eine schöne Menüstruktur überlegt und im prinzip bekommen ja die vier Tasten in jedem Menü andere Bedeutungen.

Nun habe ich eine Variante begonnen, bei der das Vorher aufgerufene Menü eine Nummer in den SRAM schreibt und dann beim nächsten mal eine riesige Liste von Comparebefehlen für jede Menünummer und jede Taste für die als nächstes anzuspringende Marke abgearbeitet wird. Ich glaube schlimmer gehts fast nich mehr...

Ich habe noch eine andere Idee, die mir günstiger erscheint. Bisher habe jedoch noch keinen Weg gefunden das umzusetzten.
Ist es möglich die Adressen der vom aktuellen Menü führenden Sprungmarken für jede der tasten in den SRAM zu schreiben? Kann ich also dem Assembler sagen, dass er den Wert von z.B. der Marke "Menue3:" in ein Register laden soll und dann bei der Tatsenbetätigung den Wert zum Anspringen der Programmzeile verwenden?

z.B.:
Ich bin in Menü 2 und sage ihm in dessen Routine er soll in R16 die Adresse für "Menue3:" und in R17 die für "Menue1:" schreiben. Dann schiebe ich die in den SRAM und bei drücken der OK Taste geht es in Menü 3 und bei Cancel wieder in Menü 1.

Im Prinzip sind Sprungmarken ja Konstanten, die sich nur bei Änderungen im Quelltext ändern.
Würde das so funktionieren? Wenn nicht, wie kann man sowas noch umsetzen? Muss man die Werte für die Sprungmarken selbst heraussuchen und bei jeder Programmänderung neu definieren?

Vielen herzlichen Dank im Vorraus
Steffne

Yossarian
16.07.2009, 10:34
Hallo
Ich habe zwar keine Ahnung, ob das mit den AVR geht, aber beim PIC kann man z.B. Sprungtabellen anlegen, deren Wert mit retw in den PC geladen und damit angesprungen werden.
Beim Z80 kann mit z.B. "Push HL" den Wert im Register HL auf den Stack legen und springt dann mit dem ret zu dieser Adresse. Man darf aber nicht vergessen den Stackzeiger wieder auf die richtige Adresse zu setzen, z.B. mit "Pop HL".

Mit freundlichen Grüßen
Benno

Vitis
17.07.2009, 00:23
hmmm ... ist nicht ganz trivial Dein Anliegen,
zumal in ASM, welches nicht meine Liga ist ...
ich habs (in Hochsprache) bei mir so gelöst.
Im Prinzip verwende ich zwei verschiedene Menüs.
Einmal ein Auswahlmenü und ein Einstellungsmenü
Die Menüpunkte sind in Tabellen abgelegt
und jedes Menü hat auch seinen eigenen Index und
klaro den identifier ob Auswahl oder Einstellung.
Quasi so:

1: Hauptmenü
1 (Auswahlmenü)
3;5;7;2;9 (Untermenüpunkte)

3: Einstellungen
1 (Auswahlmenü)
1;7;2;9 (Untermenüpunkte)

7: Parameter 1
2 (Einstellungsmenü)
300 (SRAMadresse)
0;255 (min / max)
1; (Aussprung in Auswahlmenü)

9: Ende
1
0;

steffne
17.07.2009, 18:53
Erst mal vielen Dank für die Antworten auch wenn ich glaube, dass sich das im AVR-Assembler nicht so ohne weiteres realisieren lässt.

Ich habe inzwischen aber noch eine andere Idee, die ich vorerst probehalber im kleinen versuche.
Man kann, wenn ich das richtig verstehe, dem Assembler mit .org genau anweisen, wo ein Programmabschnitt zu stehen hat. Jetzt könnte ich versuchen damit die Menüführung ganz an das Ende des Flash-Speichers zu legen und die als nächstes anzuspringenden Menüadressen als Konstanten angeben. Das Problem ist nur, dass man genau wissen muss wie groß die Menüführung wird und später keine Menüs mehr dazu kommen können weil dann die Startadresse weiter nach vorn rutscht und damit alle Konstanten manuell geändert werden müssen. Das ist bei 58 Menüs nicht unbedingt schnell gemacht.

Am einfachsten wäre wirklich die Möglichkeit eine Sprungmarke, die an sich Konstant ist, als Variable zu Verwenden indem man ihren Wert in ein Register legt.

Ich würde mich sehr über weitere Vorschläge freuen.

Liebe Grüße
Stephan

JonnyP
19.07.2009, 09:50
Vergiss mal feste Adressen. Bei jeder kleinen Änderung verschiebt sich ja alles. Man benutzt einfach einen label unter dem die Tabellen, Texte oder Programmteile liegen. Änderst du dein programm, muss es ja neu assembliert werden und der assembler generiert dann die neuen adressen der labels. Ist doch fast das gleiche wie bei basic, z.b. gosub xyz.

Vitis
19.07.2009, 11:35
in Basic würde man "restore" verwenden um den Zeiger zu setzen ;)

Gosub wäre die Unterroutine um die Menüpunkte aufzuzählen

ich für meinen Teil würde dergleichen sowieso eher in
Hochsprache zu programmieren empfehlen ... ist doch
etwas übersichtlicher ... zauberwort bei der Geschichte
ist State-Machine, ich denk mal dass die Programmausführung
durchs Menü ja nicht unterbrochen werden soll, oder?

steffne
19.07.2009, 14:27
Ich habe die Lösung gefunden und sie ist simpel wie einfach.

Also, für alle die einmal ein strukturiertes Menü auf effiziente Art programmieren wollen:

Man kann die Marken direkt mit ldi laden.

Ich erkläre das ganze mal an einem Beispiel:

Jede Taste hat 16 Bit SRAM fest zugewiesen bekommen.

Taste1--->Vor
Taste2--->Zurück
Taste3--->OK
Taste4--->Cancel

Main:

mach dies
mach das
mach jenes

rjmp Main

Taste1:
[Sprungmarke aus SRAM holen in r16 und r17]
push r16 ;Sprungmarke auf den Stack
push r17
ret ;Marke, die auf dem Stack liegt anspringen
rjmp Main

Taste2:
;Wie Taste 1 nur andere SRAM-Adresse

rjmp Main

Taste3:
;Wie Taste 1 nur andere SRAM-Adresse

rjmp Main

Taste4:
;Wie Taste 1 nur andere SRAM-Adresse

rjmp Main


Menue1:
[Text auf Display schreiben]

;Im folgenden werden die Tasten definiert
ldi r16,LOW(Menue2)
ldi r17,HIGH(Menue2)
[r16 und r17 in den SRAM legen] ;Vor

ldi r16,LOW(Menue1_OK)
ldi r17,HIGH(Menue1_OK)
[r16 und r17 in den SRAM legen] ;OK

ldi r16,LOW(Menue1_Cancel)
ldi r17,HIGH(Menue1_Cancel)
[r16 und r17 in den SRAM legen] ;Cancel

rjmp Main

Menue2:
[Text auf Display Schreiben]

;Im folgenden werden die Tasten definiert
ldi r16,LOW(Menue1)
ldi r17,HIGH(Menue1)
[r16 und r17 in den SRAM legen] ;Zurück

ldi r16,LOW(Menue3)
ldi r17,HIGH(Menue3)
[r16 und r17 in den SRAM legen] ;Vor

ldi r16,LOW(Menue2_OK)
ldi r17,HIGH(Menue2_OK)
[r16 und r17 in den SRAM legen] ;OK

ldi r16,LOW(Menue2_Cancel)
ldi r17,HIGH(Menue2_Cancel)
[r16 und r17 in den SRAM legen] ;Cancel
rjmp Main

Menue3:
[Text auf Display Schreiben]
ldi r16,LOW(Menue2)
ldi r17,HIGH(Menue2)
[r16 und r17 in den SRAM legen] ;Zurück

ldi r16,LOW(Menue3_OK)
ldi r17,HIGH(Menue3_OK)
[r16 und r17 in den SRAM legen] ;OK

ldi r16,LOW(Menue3_Cancel)
ldi r17,HIGH(Menue3_Cancel)
[r16 und r17 in den SRAM legen] ;Cancel
rjmp Main


Menue1_OK:
...
rjmp Main

Menue1_Cancel:
...
rjmp Main

Menue2_OK
...
rjmp Main
.
.
.
.
.

Hier kehrt das Programm immer wieder in das Hauptprogramm zurück. Die Menüs definieren was, welche Taste als nächstes macht indem sie die Sprungmarken zwischenspeichern.
Hat bei mir wunderbar funktioniert auf diese Art.
Habe schon 13 Menüpunkte von 58 auf diese Art fertig gemacht und das Programm ist immernoch ziemlich übersichtlich.

Auf diese Art sind natürlich auch Verschachtelungen mit x Untermenüs möglich.

Ich rate auf jeden Fall mit Zahlen zu arbeiten und das Ganze vorher als Organigramm zu skizzieren.

Liebe Grüße
Steffne