Forum: Mikrocontroller und Digitale Elektronik GLCD Display mit einem Menü


von Ingo Uhlemann (Gast)


Lesenswert?

Hallo alle zusammen,

ich habe mir für ein kleine Hobbyprojekt einen AT-Mega128 mit einem 
128x128GLCD Display aufgebaut. Das Display kann ich auch schon 
erfolgreich ansteuern.

Ich möchte auf dem Display ein relativ einfaches menü darstellen welches 
aus zwei ebenen besteht. Dafür habe  ich das Display in 2 Teile geteilt 
96pixel und 32pixel. Der Schönheit halber auch schon mit linien 
versehen.

Jetzt möchte ich im oberen Teil das Hauptmenu anzeigen, die Länge des 
menüs kann ich jetzt noch nicht genau sagen. Wenn ich jetzt mit den 
Tasten oben auswähle dann soll sich im Unteren Teil das Menü ändern.

Also mal als Strucktur dargestellt

Menü1
-----Submenü1
-----Submenü2
-----Submenü3
Menü2
-----Submenü1
...

Jeder untermenüeintrag soll dann bestimmte Pins Setzen oder nicht.
Beispiel:
Auswahl Menü1-->Submenü1
PortD : Pin0 (1), Pin1(0), Pin2(1), Pin3(0)
Auswahl Menü1-->Submenü2
PortD : Pin0 (0), Pin1(1), Pin2(0), Pin3(0)

Jetzt liegt mein Problem darin das ich mich gerade in C einarbeite, habe 
mir dafür auch einige Nützliche Bücher besorgt.

Mir fehlt momentan ein gescheiter Ansatzpunkt wie ich das ganze beginne. 
Wenn mir da jemand ein paar Tipps geben könnte wo ich mir ähnliches auch 
anschauen kann, wäre ich euch echt sehr dankbar.

Das dann nach dem Auswählen noch mehr geschied ist klar und auch jetzt 
nicht unbdingt das Problem (momentan).

Tschau ingo

P.S.: Bitte nicht falsch verstehen, ich möchte es nicht vorgekaut 
bekommen, denn dann kann ich es ja auch nicht lernen ;-)

von Puppetmaster (Gast)


Lesenswert?

Ich würd eine Funktion anlegen die mir das Menü zeichnet wenn es 
aufgerufen wird und mit einer Variablen die Auswahl speichern.

Pseudocode:
1
int Menüpunkt;
2
void Menüzeichnen(void)
3
{
4
//Zeichnet das menü
5
}
6
7
void Auswahl(int i)
8
{
9
Menüzeichnen();/*Stellt das normale menü erst wieder her damit nicht alles markiert ist*/
10
//Zeichnet einen Kastenmarkierung oder was auch immer an Position int i ^^ z.b. mit einer if Abfrage
11
}
12
13
void Normal(void)
14
{
15
//Zeichnet alles nochmal so wie es aussehen soll ohne Menü ausgeklappt
16
}
17
18
while(1)
19
{
20
21
if(ereigniss== menüöffnen)  
22
{
23
Menüzeichnen();
24
Auswahl(0);
25
Menüpunkt=0;
26
}
27
28
if(ereigniss== menü up && Menüpunkt |= 0) Auswahl(--Menüpunkt);
29
else if(ereigniss== menü down && Menüpunkt < Maximum) Auswahl(++Menüpunkt);
30
}
31
32
if(ereigniss== bestätigen gedrückt)
33
{
34
if(Menüpunkt == 0) PortD : Pin0 (1), Pin1(0), Pin2(1), Pin3(0); 
35
else if(Menüpunkt == 1) PortD : Pin0 (0), Pin1(1), Pin2(0), Pin3(0);
36
//usw...
37
Menüpunkt=0;
38
Normal();
39
}

Ich hoffe das ist so verständlich so würde ich das im groben aufbauen ps 
das ist jetzt nicht 100% durchdacht und besonders beim umschalten der 
pins müsste man sich gedanken machen ob das ned etwas mit ner Schleife 
besser ging die überprüft welcher Pin gesetzt werden muss

von Michael H. (mah)


Lesenswert?

Ganz brauchbarer Code für einen Menu-Handler auf Basis eines 
tabellengesteuerten endlichen Automaten ist im AVR Butterfly code zu 
finden (sieh mal auf 
http://www.mikrocontroller.net/articles/AVR_Butterfly , GCC port hier: 
http://www.siwawi.arubi.uni-kl.de/avr_projects/).

Ist ein gutes Beispiel für datengesteuertes Programmieren (im Gegensatz 
zum Ausprogrammieren des Verhaltens in endlosen Würsten von if/then/else 
und case statements) : das Verhalten des Menübaums wird durch Tabellen 
(arrays im Flash) definiert  - man muss nur noch die für den Menüpunkt 
spezifische Funktion hinzufügen. Und über C-Datentypen und Pointer auf 
Funktionen lernst auch gleich was dabei.

lg Michael

von Ingo Uhlemann (Gast)


Lesenswert?

Hallo,

danke für die Tipps. Ich werde jetzt über den Weg mit Array und 
mehrdimensionale Arrays gehen. Praktisch die Inhalte des menüs in einem 
Array im Flash ablegen. Die Koordinaten werde ich dann im EEprom 
abspeichern, damit die Werte auch nach einem neustart noch vorhanden 
sind. Habe mir einen Programmablaufplan aufgestellt damit ich das 
Programm gescheit umsetzen kann.

Wenn ich dann wieder ein Problemchen haben, hoffe ich doch das ich die 
Probleme mit euch Klären kann.

Tschau Ingo

von Ingo Uhlemann (Gast)


Lesenswert?

Hallo,

so bin jetzt dabei das erste Array anzulegen. Sinnvollerweise würde ich 
das Menü im flash ablegen. Dafür habe ich mir das Tutorial mal zur Hilfe 
genommen aber irgendwie verstehe ich die ganze sache nicht.

Als erstes in der Definition das array selbst
1
const char str1[] PROGMEM = "Betriebssysteme";
2
const char str2[] PROGMEM = "Speicherconfig";
3
const char str3[] PROGMEM = "Sound";
4
 
5
const char *strarray1[] PROGMEM = {
6
  str1,
7
  str2,
8
  str3
9
};

Aber irgendwie verstehe ich das Prinzip des lesens aus dem Flash nicht 
richtig, was auch sehr dürftig beschrieben ist.
1
int main(void)
2
{
3
  int i, j, l;
4
  const char *pstrflash;
5
  char work[20], work2[20];
6
  // fuer Simulation: per volatile Optimierung verhindern, 
7
  //                  da c nicht genutzt
8
  volatile char c;
9
  
10
  for ( i = 0; i < (sizeof(strarray1)/sizeof(strarray1[0]) ); i++ ) {
11
 
12
    // setze Pointer auf die Addresse des i-ten Elements des
13
    // "Flash-Arrays" (str1, str2, ...)
14
    pstrflash = (const char*)( pgm_read_word( &(strarray1[i]) ) );
15
    
16
    // kopiere den Inhalt der Zeichenkette von der
17
    // in pstrflash abgelegten Adresse in das work-Array
18
    // analog zu strcpy( work, strarray1[i]) wenn alles im RAM
19
    strcpy_P( work, pstrflash );
20
    // verkuerzt:
21
    strcpy_P( work2, (const char*)( pgm_read_word( &(strarray1[i]) ) ) );
22
    
23
 
24
    // Zeichen-fuer-Zeichen
25
    l = strlen_P( pstrflash );
26
    for ( j=0; j < l; j++ ) {
27
      // analog zu c=strarray[i][j] wenn alles im RAM
28
      c = (char)( pgm_read_byte( pstrflash++ ) );
29
    }
30
  }
31
 
32
  while (1) { ; }
33
}

Sehe ich das richtig das jedes Zeichen einzeln in den Speicher kopiert 
werden muß`?

Oder gibts da noch einen einfacheren weg?

Wieder für Tips Dankbar. Ingo

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.