mikrocontroller.net

Forum: Compiler & IDEs Interruptproblem Atmega32


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forum

Möchte mit einem Taster einen Interrupt auslösen (INT0).
Wenn ich den internen PullUp aktiviere und den Taster aug GND hänge 
funktioniert alles wunderbar. Einziges Problem ist, dass ich den Taster 
drücke und erst beim auslassen der Interrupt auslöst. Ist auch klar, da 
ich auf steigende Flanke programmiert habe.

Wenn ich allerdings beim Drücken des Tasters den Interrupt auslösen 
möchte und den Taster auf +5V hänge, wird bereits bei der 
Programmübertragung der Interrupt aktiviert (LEDs der Interruptroutine 
leuchten auf).
Da der Eingangspin von INT0 immer einen definierten Wert braucht habe 
ich einen externen PullDown dazwischengeschaltet. Somit liegt permanent 
GND am Eingangspin, nur beim drücken des Tasters kurzfristig +5V.

Meine Frage:
Warum funktioniert alles wenn ich den internen PullUp verwende und GND 
taste, aber bei einem externen (PullDown) und +5V nicht?


#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>

volatile unsigned char x = 1;     // volatile immer für Variablen, die im  
volatile unsigned char NeueZahl = 0;  // Hauptprogramm und in der
                                      //Interruptroutine verwendet werden

ISR(INT0_vect){

  unsigned char g = 224;  // PORTC erkennt nur Zahlen kleiner als 128,
  PORTC = ~g;             // deshalb Variable eingeführt
  _delay_ms(1000);

  x++;
  NeueZahl = 1;  // True der If-Bedingung
}



int main(void){
 
   DDRC = 0xFF;
   PORTC = ~0x60;
   _delay_ms(1000);
 
   //PORTD = 0xFF;  // PullUp aktivieren!!  oder externen PullUp aktivieren

   // Interrupts aktivieren
   SREG |= (1<<7);    // Global Interrupt Enable     sei(); als Alternative
   GICR |= (1<<INT0);   // External Interrupt 0 Enable
   MCUCR |= (1<<ISC01)|(1<<ISC00);   // Int0 auf steigende Flanke
 
 
   while(1){
 
      PORTC = ~7;
      _delay_ms(500);

      if(NeueZahl){
   
         PORTC = ~x;
         _delay_ms(1000);
         NeueZahl = 0; // If-Bedingung wieder auf 0 setzten,
                       // damit nächster Interrupt diese wieder 
                       // aufrufen kann
      }
   }
}


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

Bewertung
0 lesenswert
nicht lesenswert
Ich denke die Frage sollte eher lauten:
Wie wirkt sich eigentlich ein bestimmter Pegel an diesem Pin aus, 
solange der externe Interrupt nicht konfiguriert ist?

In deinem internen Pullup Szenario, aktivierst du den Pullup bevor du 
den Interrupt freischaltest und konfigurierst (da solltest du übrigens 
noch einmal über die Reihenfolge nachdenken: normal ist wohl, dass 
zuerst eine Einheit konfiguriert ehe man sie dann zur Arbeit 
freischaltet und nicht umgekehrt). Wird der Interrupt freigegeben, dann 
hat er noch die Default-Einstellung von: Interrupt an aktive Low. Das 
hast du aber durch den Pullup nicht mehr am Pin. Dort ist schon high. 
Und erst dann schaltest du auf Edge Detection um.

In deinem Szenario mit externem Widerstand ist aber der Ablauf der 
Ereignisse so:
der Widerstand zieht den Pin auf Low.
Du aktivierst die Interrupts mit sei (was schon mal eine schwachsinnige 
Idee ist. Zuerst werden alle Sourcen konfiguriert und erst dann werden 
die Interrupts freigegeben)
Dann aktivierst du den externen Interrupt. Seine Defaulteinstellung ist: 
Interrupt an aktive Low. Den Fall hast du, der Pin IST low.
Und erst dann konfigurierst du den Interrupt auf Edge Detection.


Wie gesagt: Es ist ein Frage der Reihenfolge, in der Dinge konfiguriert 
und aktiviert werden.

> Einziges Problem ist, dass ich den Taster
> drücke und erst beim auslassen der Interrupt auslöst. Ist auch
> klar, da ich auf steigende Flanke programmiert habe.

Wo ist das Problem?
Konfiguriere den Interrupt auf fallende Flanke und er löst beim Drücken 
der Taste aus.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Du aktivierst die Interrupts mit sei (was schon mal eine schwachsinnige
> Idee ist. Zuerst werden alle Sourcen konfiguriert und erst dann werden
> die Interrupts freigegeben)

Wie würdest du das Programm verändern, damit es mit dem ext. Pulldown 
funktioniert? Bitte den Code in die richtige Reihenfolge setzen, da ich 
nicht weiß wie ich den Code verändern soll.

Danke für deine Bemühungen

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Wo ist das Problem?
> Konfiguriere den Interrupt auf fallende Flanke und er löst beim Drücken
> der Taste aus.

Das habe ich auch gemacht, muss aber den GND schalten.
Ich möchte aber +5V schalten.

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

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:
> Karl heinz Buchegger schrieb:
>> Du aktivierst die Interrupts mit sei (was schon mal eine schwachsinnige
>> Idee ist. Zuerst werden alle Sourcen konfiguriert und erst dann werden
>> die Interrupts freigegeben)
>
> Wie würdest du das Programm verändern, damit es mit dem ext. Pulldown
> funktioniert? Bitte den Code in die richtige Reihenfolge setzen, da ich
> nicht weiß wie ich den Code verändern soll.

Ach komm.
Selber nachdenken. Nur so lernst du.

Wenn das Ziel ist:
  Wasserrohr mit neuem Wasserhahn ist an die Hauptversogung
  angeschlossen und der neu installierte Wasserhahn ist geschlossen,
  welches ist dann die richtige Reihenfolge

  * zuerst Rohr anschliessen
    dann Wasserhahn an Rohr schrauben
    dann Wasserhahn zudrehen

  * zuerst Hahn zudrehen
    dann Rohr anschliessen
    dann Hahn an Rohr schrauben

  * zuerst Hahn schliessen
    dann Hahn an Rohr schrauben
    dann Rohr anschliessen

  * zuerst ...

In alle Fällen landest du beim selben End-Ergebnis. Aber nur in einem 
der Fälle findest du keine überflutete Wohnung vor.

Ich denke ich habe in der ersten Antwort genug Hinweise gegeben, wie die 
zeitliche Entwicklung in deinem Programm ist und wie es zum Effekt 
kommt.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger

Danke für die Tipps. War nur ein simpler Fehler.
Einfach das SREG nach der Konfiguration einschalten , wie du beschrieben 
hast.
 
GICR |= (1<<INT0);   
MCUCR |= (1<<ISC01)|(1<<ISC00); 
SREG |= (1<<7);   


Danke nochmal

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

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:
> Danke für die Tipps. War nur ein simpler Fehler.
> Einfach das SREG nach der Konfiguration einschalten , wie du beschrieben
> hast.
>
> GICR |= (1<<INT0);
> MCUCR |= (1<<ISC01)|(1<<ISC00);

umdrehen.
Zuerst konfigurieren
dann einschalten

> SREG |= (1<<7);

Dafür gibst sei()


Gewöhn dir die Reihenfolge an:
Zuerst werden die Dinge auf Arbeitsbedingungen eingestellt,
dann wird scharf geschaltet. Eventuell löscht man auch vor dem 
Scharfschalten noch einmal mögliche Interrupt-Flags, die sich 
zwischendurch angesammelt haben könnten, während die Konfiguration noch 
nicht vollständig war (und die daher auch Fehlalarme sein können, weil 
der µC auf ein "falsches Interruptereignis reagiert hat).

Nur James Bond springt mit dem Fallschirm in der Hand aus dem Flugzeug. 
Alle anderen stellen zuerst die Konfiguration her (schnallen sich den 
Fallschirm um) ehe sie auf scharf gehen (aus dem Flugzeug springen).

Autor: Thomas Burkhart (escamoteur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Macht man bei Kondomen ja auch so ;-)

Sorry, konnte grad nciht wiederstehen ;-)

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.