PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Enable INT0 nach Disable



Henry
24.10.2009, 17:58
Hallo,

ich bin gerade dabei ein Projekt zu entwickeln, mit dem ich die Zeit zwischen INT0 undINT1 messen möchte.
Das ist soweit auch kein Problem.

Da ich aber nach dem Eingang eines Signals an INT0 den INT0-Interrupt mit

Disable INT0
deaktivieren möchte um das eingehen weiterer Signale zu verhindern, bis eine neue Messung stattfinden soll.
Das Selbe mit INT1.

Wenn ich dann im Programm wieder die beiden Interrupts mit

Enable INT0
Enable INT1
einschalten möchte, schlägt das fehl.
Der Programmteil wo ich dies durchführen will wird auch durchlaufen, das habe ich mir mittels LED sichtbar gemacht.
Nur wird nicht wieder auf INT0 und INT1 reagiert.

Was kann ich da falsch gemacht haben? Oder kann man die Interrupts nicht so einfach wärend des Programmablaufs ein- und ausschalten?

Danke schon einmal für die Hilfe

mat-sche
24.10.2009, 18:22
Hallo Henry,

doch Du kannst während des Programmes den Int wieder zuschalten, hatte auch mal solch ein Problem.
Poste doch mal den gesamte code!

Gruß

Henry
24.10.2009, 18:38
Hallo,

der Code sieht so aus (eigentlich nichts besonderes drin)

$regfile = "m8def.dat"

$crystal = 8000000

$projecttime = 10

Config Int0 = FALLING
Config Int1 = FALLING

Config Timer1 = Timer , Prescale = 8

Config LCD = 20 * 4
Config LCDPIN = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5

Config PORTD.2 = Input 'Auf Eingang setzen
Config PORTB.3 = Output 'LCD Beleuchtung einschalten

Const Timervorgabe = 64535 '16Bit = 65535


Dim Millisekunden As Long
Dim ZeitMs as Long
Dim Sekunden as Single
Dim Messstrecke_M as Byte
Dim metersec as Single
Dim KMH as Single
Dim MPH as Single
Dim KMHstr as String * 6
Dim MPHstr as String * 6
Dim KMHa as Single
Dim MPHa as Single
Dim Messung as Byte 'Merkerbyte für erfolgte Messung


PortD.2 = 1 'PullUp Einschelten
Portd.3 = 1 'PullUp einschalten

PortB.3 = 1 'Port B3 einschalten (Hintergrundbeleuchtung

Millisekunden = 0
KMH = 0
Messstrecke_M = 3 'Messstrecke in Meter einstellen

On Int0 Irq0
On Int1 Irq1

Enable INT0
Enable INT1

On Timer1 Timer1_irq
Enable Timer1

Enable Interrupts

'LCD initialisieren
Initlcd
Cls
Cursor off

'Startbild anzeigen
Locate 1 , 1
LCD " "
Locate 2 , 1
LCD " "
Locate 4 , 1
LCD ""

Wait 5
Cls

Locate 1 , 1
LCD " "

Do

If Messung = 1 then
Sekunden = Millisekunden / 1000
Metersec = Messstrecke_M / sekunden
KMH = 3.6 * Metersec
MPH = KMH * 0.62


Messung = 2
end IF


If KMH > 999.9 then
KMHstr = "ERR"
MPHstr = "ERR"
Knotenstr = "ERR"
Else
KMHstr = Fusing(KMH , "#.#")
MPHstr = Fusing(MPH , "#.#")

End IF


If Messung = 2 then
' Anzeige auf Display

Locate 2 , 1
LCD "KMH : "
Locate 2 , 7
LCD KMHstr
Locate 3 , 1
LCD "MPH : "
Locate 3 , 7
LCD MPHstr
Locate 4 , 1
LCD " : "
Locate 4 , 7
LCD

Messung = 3

End IF


If Messung = 3 then

Enable Int0
Enable INT1

Portb.3 = 0
waitms 100
Portb.3 = 1

Messung = 0
end IF


Loop

End

'Startimpuls
Irq0:
Millisekunden = 0
Disable INT0
Return

'Stopimpuls
Irq1:
ZeitMs = Millisekunden
Messung = 1
Disable INT1
Return

'Pro Sekunde ein Aufruf
Timer1_irq:
Timer1 = Timervorgabe
Incr MILLISEKUNDEN
Return

linux_80
25.10.2009, 00:02
Hallo,

Du solltest vor dem aktivieren der IRQs die entsprechenden Flags erst löschen. Denn der AVR merkt sich auch die IRQs, die bei deaktiviertem IRQ-Flag auftreten, um diese gleich mach einem aktivieren auszuführen.

zB. mit
GIFR.INTF1 = 1

Henry
25.10.2009, 00:19
Hallo,

danke für die Antwort zu so später Stunde.
Das hat mein Problem gelöst, allerdings muss ich die beiden Flags auf 0 setzen.
Damit bin ich dann einen großen Schritt weiter

linux_80
25.10.2009, 02:07
Um die Flags zu löschen muss man sie auf 1 setzen, weil "0 setzen" heisst löschen :D

siehe AVR DBs

Henry
25.10.2009, 13:48
Hallo,

laut Datenblatt heißt es

• Bit 7 – INTF1: External Interrupt Flag 1
When an event on the INT1 pin triggers an interrupt request, INTF1 becomes set (one).
Wenn ich das richtig interpretiere wird das Bit INTF1 = 1 wenn ein Ereignis eingetreten ist.
Also muss ich daraus eine 0 machen ;-)

Oder habe ich Dich jetzt falsch interpretiert?

for_ro
25.10.2009, 14:04
Hallo,

laut Datenblatt heißt es

• Bit 7 – INTF1: External Interrupt Flag 1
When an event on the INT1 pin triggers an interrupt request, INTF1 becomes set (one).
Wenn ich das richtig interpretiere wird das Bit INTF1 = 1 wenn ein Ereignis eingetreten ist.
Also muss ich daraus eine 0 machen ;-)

Oder habe ich Dich jetzt falsch interpretiert?

Lies mal den Abschnitt zu Ende, dann siehst du, was linux_80 meinte:

• Bit 7 – INTF1: External Interrupt Flag 1
When an event on the INT1 pin triggers an interrupt request, INTF1 becomes set (one). If the I-
bit in SREG and the INT1 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 INT1 is configured
as a level interrupt.

Henry
25.10.2009, 14:16
Stimmt,

da steht es so.
Allerdings habe ich es gestern abend probiert und mit einer 1 in beiden FLAGs ist das Problem nicht behoben gewesen. Als ich es dann mit der 0 probiert habe, klappte es sofort.
Das leuchtet mir dann irgendwie nicht ein.

Es sei denn, durch die beiden Enablebefehle (die ich erst danach ausführe) werden die FLAGs wieder auf 1 gesetzt.