LCD: Text blinken

OP #919500
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
1
while(1){
2
lcd_clear();
3
lcd_home();
4
lcd_string(stunden);
5
lcd_string(":");
6
lcd_string(minuten);
7
_delay_ms(300);
8
lcd_clear();
9
lcd_home();
10
lcd_string("  ");
11
lcd_string(":");
12
lcd_string(minuten);
13
if debounce...(Tasterabfrage)
14
}
(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
#919504
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.
OP #919527
Lesenswert?

1
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
2
{
3
    if ( ! (*port & (1 << pin)) )
4
        {
5
                /* Pin wurde auf Masse gezogen, 100ms warten   */
6
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
7
        _delay_ms(50);
8
        if ( *port & (1 << pin) )
9
        {
10
                /* Anwender Zeit zum Loslassen des Tasters geben */
11
               _delay_ms(50);
12
               _delay_ms(50);
13
               return 1;
14
        }
15
        }
16
              return 0;
17
}
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
OP #920319
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)
1
  // Set Pin 6 (PD2) as the pin to use for this example
2
PCMSK |= (1<<PIND2);
3

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

7
// turn on interrupts!
8
GIMSK  |= (1<<INT0);
1
SIGNAL (SIG_INT0)
2
        {
3
        led_blink();
4
        }
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
OP #920387
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
OP #920415
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
#920422
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.
1
interrupt()
2
{
3
   zähler +1
4
   wenn zaähler=50 dann
5
   {
6
      wenn merker=0 dann
7
      {
8
         normal darstellen
9
         merker =1
10
      }
11
      anderenfalls
12
      {
13
         blinken darstellen
14
         merker =0
15
      }
16
      zaehler =0
17
   }
18

19
}

MFG
Falk

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren