Prozessor "merkt" sich INT0 ?!

Pirx

Mitglied
15. Aug. 2009
305
14
18
Möckern
Sprachen
  1. Assembler
Hallo zusammen,

beim Programmieren eines ATMEGA8 habe ich gerade einen Effekt festgestellt, für den ich auch im Datenblatt keine Erklärung gefunden habe.

Die Programmierung :
INT0 ist konfiguriert, auf die fallende Flanke zu reagieren. In dessen ISR passiert folgendes :
01. INT0 ausschalten, indem GICR auf 0 gesetzt wird
02. Timer1 in Gang setzen, indem dessen Prescaler aktiviert wird (TCCR1B auf 3)
03. eine LED an PORTC einschalten (nur zur Funktionskontrolle)

Timer1 ist auf Overflow eingestellt und dessen ISR sieht wie folgt aus :
11. Timer ausschalten, indem dessen Prescaler deaktiviert wird (TCCR1B auf 0)
12. INT0 wieder einschalten (GICR setzen)
13. die LED an PORTC ausschalten

In Betrieb sieht das dann so aus, dass mit einer fallenden Flanke an INT0 die LED leuchtet und nach ca. 0,5s wieder verlischt. So soll das auch sein. :cool:

Aber : Gibt es während die LED leuchtet eine fallende Flanke (oder auch mehrere), dann wird der INT0 nach dessen Reaktivierung (in der Timer1 ISR) sofort ein zweites Mal ausgeführt. :eek:

Ich ging davon aus, dass bei abgeschaltetem INT0 auftretende Flanken ignoriert werden. Aber das ist offenbar nicht der Fall. Eine Flanke scheint er sich zu "merken". Und das ist auch kein ATMEGA8-Phänomen - der ATTiny24 verhält sich ebenso.

Hat jemand eine Ahnung, wie der Effekt zustande kommt ?

Danke.
 
Hallo,

General Interrupt Flag Register – GIFR
• Bit 6 – INTF0: External Interrupt Flag 0
When an event on the INT0 pin triggers an interrupt request, INTF0 becomes set (one). If the Ibit in SREG and the INT0 bit in GICR are set (one), the MCU will jump to the corresponding Interrupt Vector. The flag is cleared when the interrupt routine is executed. Alternatively, the flag can be cleared by writing a logical one to it. This flag is always cleared when INT0 is configured as a level interrupt.
Also wird das Flag beim Sprung in die ISR gelöscht und damit wieder scharf
geschaltet für einen neuen INT0.

Aus dem Instruction-Set ...
RETI – Return from Interrupt
Description:
Returns from interrupt. The return address is loaded from the STACK and the Global Interrupt Flag is set.
Also werden durch den Rücksprung aus der ISR die interrupts automatisch
wieder global aktiviert.

Zusammenfassung:
Durch die Ausführung der ISR für den INT0 wird der INT0 wieder neu scharf
geschaltet und durch den Rücksprung aus der ISR für INT0 wird wieder
global akttiviert und damit sind auch wieder INT0 möglich.

Ich hoffe mal, ich habe deine Frage jetzt soweit richtig verstanden und die
richtige Richtung eingeschlagen. Aber so wie es für mich aussieht müßtest
du für die Funktion die du möchtest, den INT0 in deiner ISR für INT0 nach
dem Ausschalten sicherheitshalber noch löschen (durch schreiben einer 1
ins INTF0).

Gruß
Dino
 
Das von dir beschriebene verhalten ist absolut in Ordnung. Genau so steht es z.B. im Mega8 Datenblatt auf Seite 15:

There are basically two types of interrupts. The first type is triggered by an ev
Interrupt Flag. For these interrupts, the Program Counter is vectored to the actu
tor in order to execute the interrupt handling routine, and hardware clears th
Interrupt Flag. Interrupt Flags can also be cleared by writing a logic one to the f
to be cleared. If an interrupt condition occurs while the corresponding interr
cleared, the Interrupt Flag will be set and remembered until the interrupt is enab
cleared by software. Similarly, if one or more interrupt conditions occur while th
enable bit is cleared, the corresponding Interrupt Flag(s) will be set and reme
global interrupt enable bit is set, and will then be executed by order of priority.


Es gibt keine Möglichkeit zu verhindern, dass das entsprechende Flag gesetzt wird. Lediglich die Ausführung des Interrupts kannst du durch
Enable INT0 (oder INT1) bzw. durch entsprechendes Setzen des Registers GICR verhindern.
Allerdings kannst du das Flag wieder löschen, bevor du die ISR verlässt. Das Flag wird im Register GIFR gespeichert. Wenn du dort als letzten Befehl vor dem Return z.B.
GIFR=64 (für INT0)
schreibst, wird der zwischenzeitlich aufgetretene Interrupt gelöscht.

HBA

Oops, da war einer schneller.
 
Moin Dino und HBA,

Ich hoffe mal, ich habe deine Frage jetzt soweit richtig verstanden und die
richtige Richtung eingeschlagen.

Ja Dino, genau das war die Frage.

Da mir das keine Ruhe ließ, habe ich in der Zwischenzeit einige Runden im Debugger gedreht (auch eine Möglichkeit, seine Abende zu verbringen :D ). Das Interruptflag arbeitet, sobald MCUCR eingestellt ist (auch ohne eine Interruptroutine hinten dran). Das könnte durchaus anderweitig mal nützlich sein.

Den Weg mit dem Löschen des Interruptflags am Ende der Timerinterruptroutine bin ich dann auch gegangen und jetzt funktioniert's perfekt.

Datenblatt auf Seite 15:

If an interrupt condition occurs while the corresponding interr
cleared, the Interrupt Flag will be set and remembered until the interrupt is enab
cleared by software. Similarly, if one or more interrupt conditions occur while th
enable bit is cleared, the corresponding Interrupt Flag(s) will be set and reme
global interrupt enable bit is set, and will then be executed by order of priority.

Ah, da vorn ist das zu finden. Ich habe natürlich nur weiter hinten in der Abteilung Interrupt gesucht. Das Handbuch ist aber auch ein dicker Wälzer ... ;)

Danke euch beiden.

Gruß
Pirx
 
Moin Pirx,

Ah, da vorn ist das zu finden. Ich habe natürlich nur weiter hinten in der Abteilung Interrupt gesucht. Das Handbuch ist aber auch ein dicker Wälzer ... ;)
vorne sind die allgemeinen Sachen für Interrupts und weiter hinten sind die
einzelnen Interrupt-Sachen für die einzelnen Hardwareteile erklärt.

Als Tip: Bei Problemen IMMER im großen Datenblatt nachsehen. Die Summary
kann man für nen kurzen Überblick verwenden aber sonst für nichts. Auch wenn
man sich beim großen Datenblatt durch 300-400 Seiten durcharbeiten muß :D

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)