PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Lcd Menü



Razer
11.05.2006, 19:44
Hallo an alle

Ich entwickle derzeit eine umfangereiche Messstation. Dafür brauche ich ein Menü. Ich hab 2 Taster zu Verfügung und einen Drehschalter für die Einstellungen.

Die 2 Taster hab folgende Aufgabe: Taster 1: Return/Next Menue
Taster 2: Back/Previous Menue

Für die Messstation brauche ich ein Einstellungsmenüe, in dem ich alle Konfigurationen vornehemen kann. Ich muss auf jeden Fall zwischen den einzelnen hin und her blättern können. zB ich bin gerade im Menü 3. Dann muss ich auf das Menü 2 und auf das Menü 4 blätern können (über die 2 Taster)

Als Mikrocontroller verwende ich einen Atmega168. Der aht doch auf jedem Pin einen Pinchange Interrupt. Ich hab mir gedacht, die beiden Tastter wirken als Interrupts. Beim Interrupt für Taster 1 (enter) soll eine ISR ausgeführt werden, und eine Menüvariable inkrementiert werden. Beim Interrupt des Tasters 2 soll die Variable dekrementiert werden.

Nun muss ich doch aber immer ein passendes Menü aufrufen. Ich hätte mir gedacht, ich könnte ein Array von Menüs machen zB menue[10]. Dann soll immer das Menü menue[menue_variable]ausgeführt werden.

Nur wie schaut der Syntax zu einem Array von Funktionen aus??

Kann das in C so funktionieren. Beziehungsweise ist das sinnvoll so zu programmieren?

Danke im Voraus

Gruß Robert

johannuhrmann
11.05.2006, 21:25
Hallo Razor,

Taster oder Schalter direkt Interrupts auslösen zu lassen ist keine besonders
gute Idee, da die immer prellen (http://de.wikipedia.org/wiki/Prellen) und Du deshalb bei jedem Tastendruck immer ein
paar Menüpunkte weiterspringen würdest.

Um Deine andere Frage zu beantworten:
Ja, man kann in C Arrays von Funktionszeigern anlegen und es ist vermutlich in
Deinem Fall auch sinnvoll. (soweit ich das jetzt beurteilen kann)

Ohne Gewähr:


/*
callbacks ist ein Array von 10 Funktionszeigern auf Funktionen, die
einen int und einen char als Parameter erwarten und einen int zurückgeben.
*/
int (*callbacks[10])(int, char);

/*
alternativ und oft leichter lesbar kann man den einzelnen Funktionszeiger
als neuen Typ via Typedef definieren und den neuen Typ dann wie jeden
anderen verwenden...
*/
typedef int (*callback_t)(int, char);
callback_t callbacks[10];


Alle Klarheiten beseitigt?

Grüße,

Hans

Razer
12.05.2006, 05:52
Hallo Hans

Kann ich das so machen?



void (*lcd_menu[10] (void)

lcd_menu[0] = uart_menu(); //Zb

(*lcd_menu[0])(); //Funktionausfruf


Dann verknüpfe ich zB bei der menu_init alle Funktionen mit den dazugehörigen Zeigern??

Gruß Robert

johannuhrmann
12.05.2006, 19:15
Hi,

schau mer mal ;)



/* da fehlt doch eine Klammer ;) */
void (*lcd_menu[10] (void)

/* keine Klammer hinter dem Funktionsnamen, sonst wird die Funktion aufgerufen! */
lcd_menu[0] = uart_menu(); //Zb

/* der stimmt */
(*lcd_menu[0])(); //Funktionausfruf


Das Verknüpfen in der init-Methode kannst Du Dir sparen, wenn Du folgendes schreibst:


void (*lcd_menu[10])(void) = { uart_menu, luftdruck_menu, foobar_menu, ... };


Lesestoff:
http://www.newty.de/fpt/index.html und ausserdem
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#.28Tasten-.29Entprellung

Grüße,

Hans

Razer
13.05.2006, 14:57
Hallo Hans

Kann ich auch einen 2 Dimensionales Funktionspiterarray deklarieren??



zB
void (*lcd_menue[5][5]) (void) = {{uart_menue, timer_menue,...},
{i2c_menue, eeprom_menue,..},
{3. Ebene,...},
{4. Ebene,...},
{5. Ebene,...}};

(*lcd_menue[0][1])(); //i3c_menue


Funktioniert das so?

Gruß Robert

Kaiser-F
13.05.2006, 15:51
Servus beinand!

Ich habe meine Menüführung immer so gelöst:

zwei Globale Variablen: MUNUE_NR und DRAW.

MUNUE_NR bestimmt das aktuelle menu.
Meißt muss man ja nur das Display einmal mit dem aktuellen Menü
beschreiben. Das macht die DRAW-Variable. Ändert man das Menü,
setzt man DRAW auf >0 (zB 1 ). Die entsprechende Menüfunktion erkennt das und beschreibt das
LCD und setzt dabei DRAW wieder auf 0:

Die Funktion MENUE() führst du dauernd aus!

Diese bestimmt das momenthan ausgewählte Menü.


uint8_t MENUE_NR=0;
uint8_t DRAW=1;

void MENUE( void ){

switch( MENUE_NR){
case 0 MENUE_HAUPT(); break;
case 1 MENUE_LCD(); break;
case 2 MENUE_CONFIG(); break;
case 3 MENUE_SAMPLE(); break;
case 4 MENUE_TIMER(); break;
}
}




void MENUE_HAUPT( void ){
if(DRAW){
//Zeichne das menü auf den Bildschirm
DRAW=0;
}


// hier kannst du sachen ausführen, die im menue gemacht werden müssen
}

void MENUE_LCD( void ){
if(DRAW){
//Zeichne das menü auf den Bildschirm
DRAW=0;
}


// hier kannst du sachen ausführen, die im menue gemacht werden müssen
}

usw....

johannuhrmann
13.05.2006, 23:21
Hi Robert,

klar kann das so funktionieren. Allerdings musst Du schön langsam aufpassen,
dass Du in einem Jahr noch durchsteigst, wenn Du Dir den Code ansiehst.

Grüße,

Hans

Razer
13.06.2006, 18:24
Hallo an alle

Ich melde mich nun hier wieder einmal. Ein bisschen Zeit nach all dem Stress in der Schule...

Das hab nun verstanden. Ich möchte es aber nun so realisioeren, dass es Verzweigungen gibt.

Wenn ich zum Beisoiel ins Speichermediummenü gehe, dann möchte ich zB UART oder Speicherkarte auswählen. Wenn UART --> Baudrate.

Wie kann ich sole Verzweigungen am besten realisieren??

Danke im Voraus

Gruß Robert

Razer
14.06.2006, 21:58
Weiß denn keiner was dazu?

Kaiser-F
15.06.2006, 08:58
Die verzweigungen kannst du genau nach dem selben Prinzip machen.

Mit der selben Menue-Varible. Du springst halt dann vom haptmenue, welches die nummer 1 hat, ins menue Speicherkarte (Nr.10).

Und von dort hast du dann die Buttons
UART (Nr.20)
SPI (Nr.21)
TWI( Nr.22)
IDE (Nr.23)
LAN(Nr.24)

In den jeweiligen Menüpunkten ist immer ein "ZURÜCK" button, welcher einfach die Menüvariable auf den entrsprechenden wert bringt. Also auf das Menü (Im Zweig) zuvor.


EDIT: Die Möglichkeit mit der Menüvariable ist also fast wie mit hyperlinks zu realisieren. Nur eben einfacher, man braucht nur durch auswahl eines Menübuttons eine einzige Variable zu ändern, um von menü zu menü zu gelangen.

Also bei UART bewirkt "ZURÜCK", dass die Menüvariable den wert 10 füe "Speicherkarte" annimmt

Kaiser-F
15.06.2006, 09:15
Um die Übersicht bei verzweigten Menüs nicht zu verliehren sollte man sich immer sowas zeichnen:

http://www.sir-kaiser.de/upload/menuefuehrung.jpg

Vorteil der Methode:

Man kann ganz leicht nachträglich Menüpunkte hinzufügen!