www.mikrocontroller.net

Forum: Compiler & IDEs Problem mit Interrupt


Autor: Alexander B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,

 ich habe die letzten Tage versucht mit meinen Testboard ( AVR-P40-USB), 
die externe Interrupt Geschichte zu verstehen.

Ich habe einen ATMEGA32 auf dem Board.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#define CPU_F 8000000UL


uint8_t flag;  //globale Variable

int port_init (void)
{
DDRB |= (1<<PB0);  //LED PB0 auf Ausgang
DDRB &= ~ (1<<PB1); //Taster PB1 auf Eingang
PORTB = (1<<PB0);    //LED aus

DDRD &= ~ (1<<PD2); //INT0 auf Eingang
PORTD = (1<<PD2);   // interner Pullup Widerstand 

return 0;
}



int interrupt_init (void)
{ 

MCUCR = 0b00000011; //Steigende Flanke erzeugt Interrupt
GICR = 0b01000000; //INT0 aktiviert

return 0;

}


ISR (INT0_vect)
{
flag = 1; // Variable setzen
}







int main (void)
{
  port_init();          // Init 
  interrupt_init();     //Init
 
  

PORTB &=~ (1<<PB0); // LED TEST
_delay_ms (500);    // LED TEST
PORTB = (1<< PB0);  // LED TEST

sei();
 
  while (1)  
   {
  if (flag == 1)          // Variable abfragen
    {
     PORTB &=~ (1<<PB0);  // LED Anschalten
    }
   }


}



Der LED test funktioniort auf dem Board . Jedoch wenn ich den Taster 
drücke passiert nichts.

LED ist active low;
Taster active high  an int0 mit internem pullup widerstand.

Bitte um Hilfe.

Danke im voraus

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Bartler schrieb:
> Taster active high  an int0 mit internem pullup widerstand.

Damit liefert der gedrückte Taster high, der ungedrückte auch. Das 
verwirrt den AVR dann so sehr, daß er gar nichts macht ;-)

Ansonsten heisst die Antwort auf dein Problem "volatile".

Oliver

Autor: Alexander B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#define CPU_F 8000000UL


volatile uint8_t flag;  //globale Variable

int port_init (void)
{
DDRB |= (1<<PB0);  //LED PB0 auf Ausgang
DDRB &= ~ (1<<PB1); //Taster PB1 auf Eingang
PORTB = (1<<PB0);    //LED aus

DDRD &= ~ (1<<PD2); //INT0 auf Eingang
PORTD = (1<<PD2);   // interner Pullup Widerstand 

return 0;
}



int interrupt_init (void)
{ 

MCUCR = 0b00000001; //Steigende Flanke erzeugt Interrupt
GICR = 0b01000000; //INT0 aktiviert

return 0;

}


ISR (INT0_vect)
{
flag = 1; // Variable setzen
}







int main (void)
{
  port_init();          // Init 
  interrupt_init();     //Init
 
  

PORTB &=~ (1<<PB0); // LED TEST
_delay_ms (500);    // LED TEST
PORTB = (1<< PB0);  // LED TEST


cli ();

uint8_t led;

flag = led;

sei();
 
  while (1)  
   {
  if (led == 1)          // Variable abfragen
    {
     PORTB &=~ (1<<PB0);  // LED Anschalten
    }
   }


}


Funktioniert immer noch nicht, stimmt das so mit volatile ?
Oder soll ich einfach mal einen externen Pullup Widerstand verwenden ?

mfg Alex

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Bartler schrieb:

> Oder soll ich einfach mal einen externen Pullup Widerstand verwenden ?

Wenn dein Taster wirklich 'active high' ist,
dann brauchst du einen Pull-DOWN und keinen Pull-UP

Autor: Alexander B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JA meine ich damit, aber ich hatte es neulich schonmal versucht aber es 
hatte nicht geklappt.  Stimmt das so mit dem volatile ? an was könnte es 
sonst noch liegen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Bartler schrieb:
  cli ();
  uint8_t led;
  flag = led;
  sei();
  
   while (1)
   {
     if (led == 1)          // Variable abfragen
     {
       PORTB &=~ (1<<PB0);  // LED Anschalten
     }
   }
}

>
> Funktioniert immer noch nicht,

und wie stellst du dir vor, dass die Variable led innerhalb der while 
Schleife jemals einen anderen Wert bekommen soll?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke ein nicht unerhebliches Problem in deiner Programmierung ist 
die schlecht Code-Formatierung bzw. schlechte Wahl von Variablennamen.

Mit den vielen Leerzeilen ziehst du dir den Code auf dem Bildschirm 
unnötig in die Länge und verlierst dabei den Überblick.

Nichts gegen Aufteilung in Funktionen.
Aber diese beiden init Funktionen erzeugen dir mindestens 25 Zeilen im 
Quelltext, die du auf 5 reduzieren könntest, wenn du die 
Initialisierungen ganz einfach in main machen würdest.
Dein Code würde kürzer und damit leichter zu überblicken. Die 
Komplexität in main() steigt durch die Initialisierungen aber nicht 
wesentlich.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Bartler schrieb:
> JA meine ich damit,

Na dann.
Dann haben wir:

* Ist der Taster nicht gedrückt, hält der Pullup Widerstand den
  Eingang auf +5V, also high

* Ist der Taster gedrückt, 'zieht' der Taster die Leitung auf +5V,
  also ebenfalls high

Für den µC präsentiert sich also der Eingang ständig auf high.
Wie soll der dann erkennen, dass du den Taster gedrückt hast?

Autor: Alexander B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erst mal,

also mit den Variablennamen bin ich nicht so einfallsreich, und das mit 
den vielen leerzeilen.. ich finde es für mich übersichtlicher --> 
Ansichtssache.

Ich hab jetzt den Taster  mit pull-DOWN widerstand eingelötet. 
Funktioniert immer noch nicht.

Das mit der while-Schleife stelle ich mir so vor, dass dort immer die 
variable abgefragt wird, und wenn der interrupt auslöst wird ja der Wert 
der Variable geändert. ich habe jetzt in der Whileschleife direkt "flag" 
genommen für die If-bedingung
  while (1) {
      if (flag == 1)          // Variable abfragen
    {
     PORTB &=~ (1<<PB0);  // LED Anschalten
    }
   }

Aber es funktioniert nicht.  Leider.

Autor: Alexander B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum avtive high und Pulldown Widerstand--> Versorgungsspannung geht auf 
Taster danach geht taster auf den Widerstand danach zu masse. Der Pin 
wird zwischen Widerstand und Taster abgegriffen.  Somit ist bei offenem 
Schalter keine Spannung vorhanden da ohne Strom auch keine Spannung am 
Widerstand abfallen kann.. wird der Taster geschlossen so fließt strom 
durch den Widerstand und dort fällt die gesamt Spannung gezwungenermaßen 
ab, da der Schalter im geschlossenen Zustand keinen Widerstand hat.


Umformatiertet Code ;)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define CPU_F 8000000UL


volatile uint8_t flag;  //globale Variable

int init (void)
{
DDRB |= (1<<PB0);  //LED PB0 auf Ausgang
DDRB &= ~ (1<<PB1); //Taster PB1 auf Eingang
PORTB = (1<<PB0);    //LED aus
DDRD &= ~ (1<<PD2); //INT0 auf Eingang
MCUCR = 0b00000001; //Steigende Flanke erzeugt Interrupt
GICR = 0b01000000; //INT0 aktiviert
return 0;
}


ISR (INT0_vect)
{
flag = 1; // Variable setzen
}


int main (void)
{
init();          // Init 
PORTB &=~ (1<<PB0); // LED TEST
_delay_ms (500);    // LED TEST
PORTB = (1<< PB0);  // LED TEST
sei();
while (1) 

   {
      if (flag == 1)          // Variable abfragen
    {
     PORTB &=~ (1<<PB0);  // LED Anschalten
    }
   }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Bartler schrieb:
> Zum avtive high und Pulldown Widerstand--> Versorgungsspannung geht auf
> Taster danach geht taster auf den Widerstand danach zu masse. Der Pin
> wird zwischen Widerstand und Taster abgegriffen.  Somit ist bei offenem
> Schalter keine Spannung vorhanden da ohne Strom auch keine Spannung am
> Widerstand abfallen kann.. wird der Taster geschlossen so fließt strom
> durch den Widerstand und dort fällt die gesamt Spannung gezwungenermaßen
> ab, da der Schalter im geschlossenen Zustand keinen Widerstand hat.

Alles schön und gut.


> int init (void)
> {
> DDRB |= (1<<PB0);  //LED PB0 auf Ausgang
> DDRB &= ~ (1<<PB1); //Taster PB1 auf Eingang
> PORTB = (1<<PB0);    //LED aus
> DDRD &= ~ (1<<PD2); //INT0 auf Eingang

Wo hängt denn nun dein Taster?
Auf PB1 oder auf PD2

Laut Code und Kommentar hängt dein Taster auf PB1
Die Interrupt Hardware lauscht aber auf PD2

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Bartler schrieb:

> Umformatiertet Code ;)

:-)
Das nennst du umformatiert?

Autor: Alexander B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der taster hängt an pb1 und pd2 aber die Zeile  mit pb1 ist hier 
überflüssig. Kann jemand vllt. Mal einen verbesserten Code von mir aus 
auch kurz Posten? Wäre eine echte Hilfe

Autor: Marco F. (m8_killer)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier ist mein vorschlag, einfach und funzt

gruss

Autor: Marco F. (m8_killer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
p.s.  ist für atmega32 geschrieben

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.