interrupt während delay?

Gast #6224552
Lesenswert?

Hallo,
den Zustand von Tastern frage ich in der hauptschleife immer ab. Wenn 
der Pegel eines Tasters auf high ist, habe ich ein delay von 20 ms. Ist 
der Zustand danach immer noch auf high, ist der taster gedrückt.
Jetzt habe ich aber auch einen timer laufen, der regelmäßig die ISR 
aufruft.
Wenn ich jetzt in einem delay bin, wird die ISR aufgerufen? Bei einem 
ATMega?
Persönliche Seite #6224639
Lesenswert?

TR.0LL schrieb:
> Nein, laut der Arduino-Webseite.

Da steht lediglich, dass die Arduino-Funktion delay() innerhalb einer 
ISR nicht funktionieren wird, da es selber auf ISR angewiesen ist.

Es kommt auf die Implementation an, ob die Funktion unterbrochen werden 
kann.

Herbert schrieb:
> habe ich ein delay

Der TO schreibt aber nichts von Arduino, könnte also jedes beliebiete 
Delay meinen. Also auch _delay_ms(), welches nicht mit Interrupts 
arbeitet.
Gast #6224666
Lesenswert?

Christian H. schrieb:
> Da steht lediglich, dass die Arduino-Funktion delay() innerhalb einer
> ISR nicht funktionieren wird, da es selber auf ISR angewiesen ist.
So ist es.

Christian H. schrieb:
> Der TO schreibt aber nichts von Arduino, könnte also jedes beliebiete
> Delay meinen. Also auch _delay_ms(), welches nicht mit Interrupts
> arbeitet.
Auch dem stimme ich zu.

Was dafür sorgt, dass Interrupts nicht unbedingt ein Arduino delay() 
verlängern. (nur wenn es recht exakt am Ende des delay() passiert)
Und dass sich ISR Zeiten bei den _delay_ms() akkumulieren.
Gast #6224675
Lesenswert?

Ich habe das jetzt auch ohne ein _delay_ms hinbekommen
im button-header
1
#define BUTTON_DEBOUNCETIME 3
2

3
typedef struct
4
{
5
  uint8_t state;
6
  uint8_t active;
7
  uint8_t changed;
8
  volatile uint8_t debounce;
9
}IO;
10

11
IO button[2];

In der while-schleife
1
    /* Taster abfragen */
2
    if((PIND & (1<<PIND4)) && (button[0].state==0) && (!button[0].debounce) ) /* rising edge */
3
    {
4
      button[0].debounce = BUTTON_DEBOUNCETIME;
5
      button[0].state = 1;
6
    }
7
    else if((PIND & (1<<PIND4)) && (button[0].state==1)) /* on */
8
    {
9
      button[0].changed = 1;
10
      button[0].active = 1;
11
    }
12
    else if((!(PIND & (1<<PIND4))) && (button[0].state==1) && (!button[0].debounce) ) /* falling edge */
13
    {
14
      button[0].debounce = BUTTON_DEBOUNCETIME;
15
      button[0].state = 0;
16
    }
17
    else if((!(PIND & (1<<PIND4))) && (button[0].state==0) && (button[0].active==1)) /* off */
18
    {
19
      button[0].changed = 1;
20
      button[0].active = 0;
21
    }

im timer ISR
1
  if(button[0].debounce) button[0].debounce--; /* debounce button */
2
  if(button[1].debounce) button[1].debounce--; /* debounce button */

Jetzt wäre die Frage, wie ich es für weiter buttons hinbekomme, ohne 
alles zu kopieren (also den ablauf in der while-schleife.
Momentan ist ja nur Button1 implementiert. für Button2 und weitere 
müsste ja alles nochmal kopiert werden und nur der pin und button 
angepasst werden
(PIND & (1<<PIND4) -> (PIND & (1<<PIND4)
button[0] -> button[1]

es werden letztendlich 5 buttons. Das bringt ja ewig viel code, wo aber 
letztendlich immer das selbe drinn steht.
#6224879
Lesenswert?

Herbert schrieb:
> aber wie kann ich
> (PIND & (1<<PIND4))
> im struct speichern?

Nur ganz von hinten durch die Brust ins Auge. C kennt keine Bits.
Du kannst Dir Pin-Macros anlegen, die werden dann im Code zu SBIS/SBIC 
expandiert.
Oder Du legst eben alle Tasten auf den selben 8Bit-Port und wertest sie 
per Maskenbyte aus.

Wenn die Tasten unbedingt über alle Ports verstreut sein müssen, kann 
man sie aber auch einmalig am Anfang der Entprellfunktion in einem 
virtuellen Byte zusammen fassen.
#6224901
Lesenswert?

Herbert schrieb:
> In der while-schleife

Herbert schrieb:
> im timer ISR

Was soll diese unglückliche Zweiteilung bewirken?
Du erkaufst Dir damit nur den Nachteil, daß Tastendrücke verloren gehen, 
sobald die Mainloop mal etwas mehr zu tun hat.
Besser ist es, den Timerinterrupt alles machen zu lassen und dem Main 
fertige Ereignisflags zur Verfügung zu stellen. Die können dann 
ausgewertet werden, auch wenn die Taste schon wieder losgelassen wurde.

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