Forum: Mikrocontroller und Digitale Elektronik Menü (hängt)


von Patrick R. (pat711)


Lesenswert?

Guten Abend zusammen,

ich habe mich an ein die programmierung eines Menüs gesetzt, allerdings 
will das nicht so wie ich will.

Hardware: LCD an PORTB
          Taster 1 (links)  an PIND2
          Taster 2 (rechts) an PIND3
          Taster 3 (OK)     an PIND4
          alle Taster gegen Masse
          Quartz 16 MHz

Soll-Funktion:
Das Menü soll folgendermaßen zu bedienen sein:
linkst - Taster blättert eins weiter nach links und der rechts - taster 
eins weiter nach rechts, weir OK gedrückt so wird der aktuelle Menüpunkt 
ausgewählt.

Problem / Ist - Funktion:
Sobald das Programm startet kommt die Begrüßung. Danach wird auf dem LCD 
folgendes angezeigt:
   Hauptmenü
<-  menue 1   ->
also der anfang. Nun sollte über die taster das menü gesteuert werden, 
allerdings tut sich beibedienung der taster nichts.

wenn ich das Programm im AVR - Studio simuliere, so bricht das prgramm 
dort am, wo es in die Funktion "menue" springen soll.

Hier nun der Code:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <util/delay.h>
4
#include <stdlib.h>
5
6
7
void punkt1 (void);
8
void punkt2 (void);
9
void punkt3 (void);
10
void punkt4 (void);
11
void punkt5 (void);
12
13
14
void long_delay(uint16_t ms) 
15
{
16
    for(; ms>0; ms--) _delay_ms(1);
17
}
18
19
20
volatile unsigned int gewicht = 7, kont = 0, kont2 = 0;
21
22
23
24
25
void menue(void)
26
{
27
  unsigned int men_punkt = 1;
28
  
29
  while (kont == 0)
30
  {
31
    lcd_clear();
32
    switch(men_punkt)
33
    {
34
    case 1:  set_cursor(0,0);
35
        lcd_string ("   Hauptmenue");
36
        set_cursor(0,2);
37
        lcd_string ("<-  menue 1   ->");
38
        break;
39
    case 2:  set_cursor(0,0);
40
        lcd_string ("   Hauptmenue");
41
        set_cursor(0,2);
42
        lcd_string ("<-  menue 2   ->");
43
        break;
44
    case 3: set_cursor(0,0);
45
        lcd_string ("   Hauptmenue");
46
        set_cursor(0,2);
47
        lcd_string ("<-  menue 3   ->");
48
        break;
49
    case 4:  set_cursor(0,0);
50
        lcd_string ("   Hauptmenue");
51
        set_cursor(0,2);
52
        lcd_string ("<-  menue 4   ->");
53
        break;
54
    case 5:  set_cursor(0,0);
55
        lcd_string ("   Hauptmenue");
56
        set_cursor(0,2);
57
        lcd_string ("<-  menue 5   ->");
58
        break;  
59
    }
60
    kont2 = 0;
61
    
62
    while (kont2 == 0)      //so lange ausführen bis eine Aktion ausgeführt wurde (kontrolloieren über kont2)
63
    {
64
      if (PIND & (0<<PIND3))         //rechts
65
      {
66
        men_punkt ++;
67
        kont2 ++;
68
      }
69
      else if (PIND & (0<<PIND2))      //links
70
      {
71
        men_punkt --;
72
        kont2 ++;
73
      }
74
      else if (PIND & (0<<PIND4))      //OK
75
      {
76
        kont ++;
77
        kont2 ++;
78
      }
79
    }
80
    if (men_punkt == 0)
81
    {
82
      men_punkt = 5;
83
    }
84
  }
85
  
86
  switch (men_punkt)
87
  {
88
  case 1:  punkt1();   break;
89
  case 2: punkt2();  break;
90
  case 3: punkt3();  break;
91
  case 4: punkt4();  break;
92
  case 5: punkt5();  break;
93
  }
94
}
95
96
void punkt1(void)
97
{  
98
  lcd_clear();
99
  set_cursor(0,0);
100
  lcd_string("menue 1");
101
  long_delay(2000);
102
  menue();
103
}
104
105
void punkt2(void)
106
{  
107
  lcd_clear();
108
  set_cursor(0,0);
109
  lcd_string("menue 2");
110
  long_delay(2000);
111
  menue();
112
}
113
114
void punkt3(void)
115
{  
116
  lcd_clear();
117
  set_cursor(0,0);
118
  lcd_string("menue 3");
119
  long_delay(2000);
120
  menue();
121
}
122
123
void punkt4(void)
124
{  
125
  lcd_clear();
126
  set_cursor(0,0);
127
  lcd_string("menue 4");
128
  long_delay(2000);
129
  menue();
130
}
131
132
void punkt5(void)
133
{  
134
  lcd_clear();
135
  set_cursor(0,0);
136
  lcd_string("menue 5");
137
  long_delay(2000);
138
  menue();
139
}
140
141
int main(void)
142
{
143
  DDRD = 0xE0;
144
  DDRC = 0x30;
145
  PORTD = 0x1C;
146
  lcd_init();
147
  set_cursor(0,0);
148
  lcd_string ("   Guten Tag");
149
  set_cursor(0,2);
150
  lcd_string ("    XXXXXXXXX");
151
  long_delay(1000);
152
  menue();
153
}

von holger (Gast)


Lesenswert?

Da fehlt ne while(1) in main().

Und pfui Deibel menu() wird aus menu() in punktx() aufgerufen.
Stacküberlauf garantiert.

von Patrick R. (pat711)


Lesenswert?

Thx,

meine main sieht nun folgendermasen aus:

1
int main(void)
2
{
3
  DDRD = 0xE0;
4
  DDRC = 0x30;
5
  PORTD = 0x1C;
6
  lcd_init();
7
  set_cursor(0,0);
8
  lcd_string ("   Guten Tag");
9
  set_cursor(0,2);
10
  lcd_string ("    XXXXXXXXX");
11
  long_delay(1000);
12
  menue();
13
  while (1)
14
  {
15
  }
16
  return 1;
17
}


aber es tut sich immer noch nichts ???

von Andreas W. (andreasw) Benutzerseite


Lesenswert?

Ein weiteres Problem ist die Tasterabfrage.
falsch:    PIND & (0<<PIND2)
richtig: !(PIND & (1<<PIND2))

Schau dir auch mal den Artikel zur Entprellung an: Entprellung

von holger (Gast)


Lesenswert?

while (1)
  {
    menue();
  }

von Klugscheißer (Gast)


Lesenswert?

Das mit der while-Schleife war ja auch anders gemeint.

Probier's mal so:
  while (1)
  {
    menue();
  }

von Patrick R. (pat711)


Lesenswert?

nun tut sich was aber wies scheint muss ich wirklich noch entprellen ^^

noch ne frage zu dem was holger geschrieben hat:

1
while (1)
2
  {
3
    menue();
4
  }

wir menue da nicht dauernd aufgerufen?

von Klugscheißer (Gast)


Lesenswert?

>wir menue da nicht dauernd aufgerufen?
Richtig !

Wir sind hier auf einem µC und nicht auf dem PC!
Was soll der Controller machen, wenn er einmal durch das Programm 
gelaufen ist?

Du hast kein Betriebssystem, dass die Funktion nur aufruft wenn sie auch 
was zu tun hat. Also mußt du selbst diese Schleife programmieren. 
Ansonsten passiern die tollsten Dinge.

von Patrick R. (pat711)


Lesenswert?

stimmt eigentlich ^^

thx

hat mir jmd nen tipp was die beste variante zum entprellen ist? 
(softwaremäßig)

von Der Gast -1 (Gast)


Lesenswert?

Entprellung - Artikel im Wiki

von Patrick R. (pat711)


Lesenswert?

holger hatte noch folgendes geschreiben:

>Und pfui Deibel menu() wird aus menu() in punktx() aufgerufen.
>Stacküberlauf garantiert.

wie kann ich das denn am elegantesten verhindern?   über ein return? 
aber dann muss ja mein void weg???

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.