mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD: Text blinken


Autor: Tobias Kaminsky (finswimmer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

der User soll wenn der Countdown eingestellt wird, sehen, ob er gerade 
bei der Stunde oder Minute ist.
Dazu dachte ich, ich lasse das LCD die jeweiligen 2 Stellen blinkend 
anzeigen.

Wenn ich es aber im einfachsten Falle mache
while(1){
lcd_clear();
lcd_home();
lcd_string(stunden);
lcd_string(":");
lcd_string(minuten);
_delay_ms(300);
lcd_clear();
lcd_home();
lcd_string("  ");
lcd_string(":");
lcd_string(minuten);
if debounce...(Tasterabfrage)
}
(Nicht getestet, aber Funktionsweise sollte klar werden)
Dann hänge ich in einer Endlosschleife fest, bei der auf 
Tasterereignisse nur alle 600ms reagiert wird.

Das ist also nicht ganz das, was ich haben will.

Ich habe mich gestern auch schon in Interrupts eingelesen.

Laut http://www.windmeadow.com/node/19
[quote]
The interrupts can detect four different types of pin changes:
1. pin goes low
2. any logical change in pin
3. falling edge (pin goes from high to low)
4. rising edge (ping goes from low to high)
[/quote]
bringt mir das nicht viel für einen Taster, oder?

Wäre für einen Denkanstoß sehr dankbar!

Vielen Dank
Tobi

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest dich als nächstes in "Timer" einarbeiten.

Soviel Delay macht man nicht.

Das Schema ist hier so.

Man hat einen Timer-Interrupt, welchen man zu bestimmten Zeiten 
irgendwelche Bits setzen lässt.

In deiner Main-Loop fragst du dann einfach nur dieses eine Bit ab,
Und wenn es gesetzt ist, führst du deinen Blink-Befehl aus und setzt das 
Bit zurück.

Allerdings hängt er dann wieder in deiner Tastaturabfrage fest.
Hier müsstest du die Tastenabfrage auch aufbohren, dass sie dir nicht 
das ganze System lahm legt.
Also z.B. die Abfrage ständig im Hintergrund ausführen und nur ein Bit 
setzen, wenn eine gültige Eingabe (also mit ENTER oder so in etwa) 
empfangen wurde.

Der Interrupt für den Taster geht zum Spielen jetzt erstmal.
Allerdings, wenn du eine stabile Funktionsweise haben willst, solltest 
du dich mal mit "Entprellen von Tastern" auseinandersetzen.
In deinem jetzigen Fall (nur mit Interrupt), kann es passieren, dass 
dein Taster 10 statt nur einem Impuls abgibt.

Autor: Sören H. (dersoe)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... wobei ich ja mal gehört habe, dass man Taster auch hardwareseitig 
entprellen kann ;-) Für den allerersten Anfang sollte wohl ein 
Kondensator reichen (so 1...100nF).
Ansonsten wirst du sicherlich hier noch fündig:
Beitrag "Taster Hardwaremäßig entprellen"
Gruß,
Sören

Autor: Tobias Kaminsky (finswimmer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
        {
                /* Pin wurde auf Masse gezogen, 100ms warten   */
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
        _delay_ms(50);
        if ( *port & (1 << pin) )
        {
                /* Anwender Zeit zum Loslassen des Tasters geben */
               _delay_ms(50);
               _delay_ms(50);
               return 1;
        }
        }
              return 0;
}
Klappt auch sehr gut, wie ich finde.

Mir gehts nochmal um die Funktionsweise vom Timer.
Dieser zählt von 0 bis 255 hoch. Wenn dieser dann wieder auf 0 springt, 
löst er einen Interrupt aus, mit dem man arbeiten kann.

Wie aber wird wo definiert, dass man nach dem Interrupt schaut?
Oder aktiviert der Interrupt selbst seine eigene Routine?

Kann ich dann nicht den Taster auf einen Interrupt legen? Sodass ich 
immer, wenn der Taster gedrückt wird, die dazugehörige Routine 
abgearbeitet wird?
Das hätte den Vorteil, dass nirgendswo "hängende" Endlosschleifen 
arbeiten.


Danke

Tobi

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Vorteil, "dass nirgendwo hängende Endlosschleifen sind" sollte man 
sich sowieso von vorn herein angewöhnen.

Schau mal hier im Menü links unter AVR. Da sind ziemlich viele 
Anleitungen zu solchen Themen. Also einfach mal nach "Interrupts" 
suchen.

Autor: Tobias Kaminsky (finswimmer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So. Ich habe nun, laut http://www.windmeadow.com/node/19, einen 
Interrupt an PD2 angeschlossen.
ISC01=0
ISC00=1
ist "Any logical change on INT0 generates an interrupt request".

Das steht in main(void)
  // Set Pin 6 (PD2) as the pin to use for this example
PCMSK |= (1<<PIND2);

// interrupt on INT0 pin falling edge (sensor triggered)
MCUCR = (0<<ISC01) | (1<<ISC00);

// turn on interrupts!
GIMSK  |= (1<<INT0);
SIGNAL (SIG_INT0)
        {
        led_blink();
        }
steht außerhalb der Schleife.

Nun sollte doch bei einem Tastendruck die Spannung an PD2 kurzfristig 
von Low auf High gehen, somit ist das ein Kriterium für den Interrupt 
und die led sollte blinken?

Leider tut sich da nix...

Habe ich das System "Interrupt" noch nicht begriffen?

Danke
Tobi

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die meisten LCDs können den Cursor alleine blinken lassen. Ist zwar nur 
ein Zeichen, reicht aber meist.

MFG
Falk

Autor: Tobias Kaminsky (finswimmer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:
> Die meisten LCDs können den Cursor alleine blinken lassen. Ist zwar nur
> ein Zeichen, reicht aber meist.
>
> MFG
> Falk

Nee, das ist nicht das, was ich haben möchte, da der Cursor dann meist 
an der falschen Stelle blinkt.
Wenn denn dann soll es richtig gut aussehen :)

Tobi

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nee, das ist nicht das, was ich haben möchte, da der Cursor dann meist
>an der falschen Stelle blinkt.

Das ist dann aber dein Fehler ;)

Autor: Tobias Kaminsky (finswimmer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger wrote:
>>Nee, das ist nicht das, was ich haben möchte, da der Cursor dann meist
>>an der falschen Stelle blinkt.
>
> Das ist dann aber dein Fehler ;)

Klar, das kann ich auch umbauen. Aber dann habe ich immer noch das 
Problem, dass ich die Stunden einstelle, welche 2 Ziffern habe, aber nur 
bei 1Ziffer der Cursor blinkt.

Wie dem auch sei. Ich kenne diese Funktion, möchte aber auch etwas 
lernen und das Ganze ausgliedern und dann per Interrupts lösen.

Daher noch einmal die Frage, ob und wie ich diesen Taster mit Interrupts 
steuern kann?

Danke
Tobi

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Tobias Kaminsky (finswimmer)

>Daher noch einmal die Frage, ob und wie ich diesen Taster mit Interrupts
>steuern kann?

Den Taster kaum, aber das LCD. ;-)

Du must einen Timer Interrupt nutzen, z.B. auf 10ms eingestellt. 
Im Interrupt zählst du eine Variable hoch. Wenn sie z.B. 50 erreicht hat 
(1/2 s), dann musst du anhand einer weiteren Variable prüfen, ob du 
jetzt die Zahl darstellen willst (und welche) oder gerade "geblinkt 
wird", sprich du musst Leerzeichen, Vollzeichen oder invertiert 
darstellen. Wenn du das gemacht hast, musst du deine Zählvariable 
zurücksetzten und auch die Darstellungsvaribable ändern. Ungefähr so.

interrupt()
{
   zähler +1
   wenn zaähler=50 dann
   {
      wenn merker=0 dann
      {
         normal darstellen
         merker =1
      }
      anderenfalls
      {
         blinken darstellen
         merker =0
      }
      zaehler =0
   }

}

MFG
Falk

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.