Forum: Compiler & IDEs Interupt-Handling


von martin (Gast)


Lesenswert?

Hallo,

ich habe vor einiger Zeit schon mal einen Beitrag gepostet ohne am Ende
mit einer funktionierenden Lösung da zustehen. Ich will bei einem Mega16
einen Interupt ausgelöst bekommen sobald sich an einem von zwei auf high
liegenden PIN's der Zustand von high nach low ändert. Ich habe dafür
SIG_COMPARATOR gewählt. Mein Problem ist das sie ISR immer gleich nach
dem einschalten des µC aktiviert wird, obwohl beide PIN noch in der
Luft hängen. Ich vermute, das ich nicht die richtige Reihenfolge für
die Interupt-Initialisierung eingehalten habe. Meine Bitte:

Kann mir jemand einen Code-Schnipsel scheiben oder Tipp geben, wo ich
so etwas finde.

Noch was, ich habe schon tagelang in Manuel's, google etc. gesucht und
weiß ehrlich gesagt nicht mehr weiter.

Gruß und Danke
Martin

von johnny.m (Gast)


Lesenswert?

Wenn die Pins 'in der Luft hängen', dann kann alles Mögliche passieren
(undefinierter Zustand). Außerdem solltest Du mal genau beschreiben, wie
das alles verschaltet ist und auf welches Ereignis genau der Int
ausgelöst werden soll. Deine Beschreibung oben ist sehr dürftig und ich
habe keine Lust, jetzt nach dem alten Thread zu suchen.

Gruß

Johnny

von Tobi (Gast)


Lesenswert?

Hi Martin,

Ob das so geht ist fraglich, da der Komparator einen recht hohen Offset
hat. Wenn also beide PINS auf HIGH sind, kann man nicht garantieren, was
für einen Zustand der Komparator-Ausgang hat. Das kann dann auch von
Baustein zu Baustein schwanken, oder mit der Temperatur,... Nimm doch
einfach die externen Interrupt-Pins (INT0(PD2) und INT1(PD3)) her! Da
brauchst du zwar 2 Interrupt-Funktionen, das funktioniert aber sauber!
Und: Offene Pins haben immer undefinierte Zustände und können dir so
Interrupts auslösen. (Der µC sieht dann mal HIGH, mal LOW, ... je nach
Lust und Laune)
Prinzipiell geht man auch so vor, dass man bei ausgeschaltetem
Global-Interrupt Flag den gewünschten Interrupt einschaltet, das
zugehörige Interrupt Flag löscht und dann die Global Interrupts wieder
frei gibt. Beim aktiviren von Interrupts kann immmer ein Interrupt
ausgelöst werden, obwohl es offensichtlich keinen Grund dafür gibt!
-->Siehe Datenblatt Mega 16

von Tobi (Gast)


Lesenswert?

Noch ein Tip: aktivire die Pull-Ups, bevor du die Global Interrupts frei
gibst! Davor aber das Interrupt Flag löschen!
Beispiel:

...
#define INT0_ON 2
#define INT1_ON 4
#define INT2_ON 1

//Externe PIN Interrupts konfigurieren, dabei pending Interrupts
löschen (DEL Interrupt FLAG)
#define EXT_INT_ENABLE_DEL_FLAG(State)   { GIFR=((State)&0x07)<<5; \
GICR&=0x1F; GICR|=((State)&0x07)<<5; }

#define INT2_FALL  0
#define INT2_RISE  1

#define INT_PIN0_CONFIG(State)   { MCUCR&=0xFC; MCUCR|=(State)&0x03; }
#define INT_PIN1_CONFIG(State)   { MCUCR&=0xF3; \
MCUCR|=((State)&0x03)<<2; }


int main(void)
  {
  cli(); //Global Interrupts Off (nur zur Anschauung, ist ja hier noch
aus)
  PORTD|=0x0C; //Pull Up für Port D2 und PD3 aktivieren;
  INT_PIN0_CONFIG(INT_FALL); //Interrupt bei fallender Flanke
  INT_PIN1_CONFIG(INT_FALL);
  EXT_INT_ENABLE_DEL_FLAG(INT0_ON|INT1_ON);
  sei(); //Global Interrupts aktivieren
  }

SIGNAL(SIG_INTERRUPT0)
  {
  //Tu was du willst,....
  }

SIGNAL(SIG_INTERRUPT1)
  {
  //Tu was du willst,....
  }

von Martin (Gast)


Lesenswert?

Moin,

dane erstmal für die Tipp's, werde es heute abend ausprobieren und
mich ggf. morgen noch mal melden (bin privat offline ...)

Gruß Martin

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.