Attiny45 Interrupt in c

Gast #4928618
Lesenswert?
• ▲
▼
Hi,
ich kämpfe gerade mit dem folgenden Code in c für den Attiny45.
Beim Betätigen eines Pull-up-Tasters soll die Led für zwei Sekunden 
leuchten.
Sie leuchtet auch, sowohl beim Drücken als auch bei stark verzögertem 
Loslassen (durch fehlendes Debouncing), aber sie lässt sich zwischen 
Drücken und leuchten gut 1/2 Sekunde Zeit...
Könnt ihr mir meinen Fehler zeigen?
1
#define F_CPU 8000000UL
2

3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6

7

8

9

10
int warten = 1;
11

12

13
int main(void)
14
{
15
  DDRB = (1 << PORTB1) | (0 << PORTB2);
16
  MCUCR = (1 << ISC01) | (1 << ISC00);
17
  GIMSK = (1 << INT0);
18
  
19
    while (1) 
20
    {
21
    sei();
22
    if (warten == 0)
23
    {
24
      cli();
25
      _delay_ms(2000);
26
      PORTB &= ~(1 << PORTB1);
27
    }
28
    }
29
}
30

31
ISR(INT0_vect)
32
{
33
  PORTB |= (1 << PORTB1);
34
  warten = 0;
35
}
Gast #4928657
Lesenswert?
• ▲
▼
Hallo
ich glaube du musst deine Variable als volatile kennzeichnen.
Ansonsten fällt die Werteänderung der "Optimierung" zum Opfer
und dein Hauptprogramm bekommt von der Änderung nichts mit.
1
volatile int warten = 1;
Gast #4928658
Lesenswert?
• ▲
▼
Hm, ich weiß nicht genau was du meinst. Während des _delay_ms sind ja 
alle Interrupts ausgeschaltet, da tut sich also nichts. Wenn ich 
gedrückt halte bis die 2s vorbei sind, bleibt die LED aus, da nur eine 
steigende Flanke erkannt wird.
Gast #4928660
Lesenswert?
• ▲
▼
Habe mal im Code ein paar Kommentare in den Code gemacht. Schau es dir 
mal an und überleg dir mal wie du die Variable wann setzt.
basti schrieb:
> int warten = 1; //1. hier wird auf 1 initialisiert, diese variable wird im 
interrupt verändert. Dann muss noch ein volatile davor
>
> int main(void)
> {
>   // initialisieren
>     while (1)
>     {
>     sei(); // interrupts einschalten
>     if (warten == 0)
>     {
>       cli(); // interrupts aus..
>       _delay_ms(2000);//2sek warten .. ok
>       PORTB &= ~(1 << PORTB1); // pin low.. ok
>     }
>     }
> }
>
> ISR(INT0_vect)
> {
>   PORTB |= (1 << PORTB1); // pin high.. ok
>   warten = 0; // auf null setzen.. wann wird diese wieder 1??
> }

Viele Grüße
Mattias
Gast #4928668
Lesenswert?
• ▲
▼
Danke Mattias, die Kommentare habe ich vergessen.
Ich habe bereits die Variable in "volatile int" geändert, das hat noch 
nicht geholfen. "warten" muss natürlich am Ende der if-Schleife auf 0 
gesetzt werden, das probiere ich mal.
Gast #4928680
Lesenswert?
• ▲
▼
Das volatile sagt dem Compiler, dass die CPU die Variable jedes mal vom 
RAM lesen muss bevor er was damit anstellt. Und nicht einen 'alten' Wert 
aus dem Register zum Vergleich nutzt.

Viele Grüße
Mattias

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.