Attiny45 Interrupt in c

Gast #4928618
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
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
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
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
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 #4928676
Oops, die LED sollte auch dann sofort leuchten. Ich glaube, die Grippe 
vernebelt mich komplett.
Setze mal Matthias diffizielen Hinweis um, und nenne eine If-Bedingung 
nicht Schleife.
Gast #4928680
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

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.