mikrocontroller.net

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


Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include "lcd-routines.h"
#include <util/delay.h>
#include <stdlib.h>


void punkt1 (void);
void punkt2 (void);
void punkt3 (void);
void punkt4 (void);
void punkt5 (void);


void long_delay(uint16_t ms) 
{
    for(; ms>0; ms--) _delay_ms(1);
}


volatile unsigned int gewicht = 7, kont = 0, kont2 = 0;




void menue(void)
{
  unsigned int men_punkt = 1;
  
  while (kont == 0)
  {
    lcd_clear();
    switch(men_punkt)
    {
    case 1:  set_cursor(0,0);
        lcd_string ("   Hauptmenue");
        set_cursor(0,2);
        lcd_string ("<-  menue 1   ->");
        break;
    case 2:  set_cursor(0,0);
        lcd_string ("   Hauptmenue");
        set_cursor(0,2);
        lcd_string ("<-  menue 2   ->");
        break;
    case 3: set_cursor(0,0);
        lcd_string ("   Hauptmenue");
        set_cursor(0,2);
        lcd_string ("<-  menue 3   ->");
        break;
    case 4:  set_cursor(0,0);
        lcd_string ("   Hauptmenue");
        set_cursor(0,2);
        lcd_string ("<-  menue 4   ->");
        break;
    case 5:  set_cursor(0,0);
        lcd_string ("   Hauptmenue");
        set_cursor(0,2);
        lcd_string ("<-  menue 5   ->");
        break;  
    }
    kont2 = 0;
    
    while (kont2 == 0)      //so lange ausführen bis eine Aktion ausgeführt wurde (kontrolloieren über kont2)
    {
      if (PIND & (0<<PIND3))         //rechts
      {
        men_punkt ++;
        kont2 ++;
      }
      else if (PIND & (0<<PIND2))      //links
      {
        men_punkt --;
        kont2 ++;
      }
      else if (PIND & (0<<PIND4))      //OK
      {
        kont ++;
        kont2 ++;
      }
    }
    if (men_punkt == 0)
    {
      men_punkt = 5;
    }
  }
  
  switch (men_punkt)
  {
  case 1:  punkt1();   break;
  case 2: punkt2();  break;
  case 3: punkt3();  break;
  case 4: punkt4();  break;
  case 5: punkt5();  break;
  }
}

void punkt1(void)
{  
  lcd_clear();
  set_cursor(0,0);
  lcd_string("menue 1");
  long_delay(2000);
  menue();
}

void punkt2(void)
{  
  lcd_clear();
  set_cursor(0,0);
  lcd_string("menue 2");
  long_delay(2000);
  menue();
}

void punkt3(void)
{  
  lcd_clear();
  set_cursor(0,0);
  lcd_string("menue 3");
  long_delay(2000);
  menue();
}

void punkt4(void)
{  
  lcd_clear();
  set_cursor(0,0);
  lcd_string("menue 4");
  long_delay(2000);
  menue();
}

void punkt5(void)
{  
  lcd_clear();
  set_cursor(0,0);
  lcd_string("menue 5");
  long_delay(2000);
  menue();
}

int main(void)
{
  DDRD = 0xE0;
  DDRC = 0x30;
  PORTD = 0x1C;
  lcd_init();
  set_cursor(0,0);
  lcd_string ("   Guten Tag");
  set_cursor(0,2);
  lcd_string ("    XXXXXXXXX");
  long_delay(1000);
  menue();
}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da fehlt ne while(1) in main().

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

Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thx,

meine main sieht nun folgendermasen aus:

int main(void)
{
  DDRD = 0xE0;
  DDRC = 0x30;
  PORTD = 0x1C;
  lcd_init();
  set_cursor(0,0);
  lcd_string ("   Guten Tag");
  set_cursor(0,2);
  lcd_string ("    XXXXXXXXX");
  long_delay(1000);
  menue();
  while (1)
  {
  }
  return 1;
}


aber es tut sich immer noch nichts ???

Autor: Andreas Watterott (andreasw) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
while (1)
  {
    menue();
  }

Autor: Klugscheißer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit der while-Schleife war ja auch anders gemeint.

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

Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nun tut sich was aber wies scheint muss ich wirklich noch entprellen ^^

noch ne frage zu dem was holger geschrieben hat:

while (1)
  {
    menue();
  }

wir menue da nicht dauernd aufgerufen?

Autor: Klugscheißer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
stimmt eigentlich ^^

thx

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

Autor: Der Gast -1 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entprellung - Artikel im Wiki

Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht 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???

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.