Hi
Wenn ich den Externen Interrupt auslöse, wird "Funktion ()" in einer
Endlosschleife ausgeführt. Wie kann ich das Verhindern?
Hier mein kurzer Code:
int main (void){
//Initzialisierung der Interrupts
MCUCR = (1<<ISC01) | (1<<ISC00);
GICR = (1<<INT0);
sei();
}
ISR(INT0_vect) //externer Interrupt auf Pin INT0
{
Funktion ();
}
Vielen Dank!
Hi
Der Prozessor macht 100% einen Rücksprung aus der Funktion.
Hab das ganze schon mit nem LCD und Textausgabe getestet.
Habe folgendes gemacht um es zu Testen:
ISR(INT0_vect) //externer Interrupt auf Pin INT0
{
...LCD Ausgabe "start"
Funktion ();
...LCD Ausgabe "ende"
while(1)
{;
}
}
Mit der Eingebauten Endlosschleife wird die Funktion nur einmal
ausgeführt - ist aber nicht sinn und Zweck meines Programms.
mfg
Das weiss ich bei deinem µC bzw. Compiler nicht. Bei PIC's/Assembler
muss man die Flags löschen, bzw. sie werden bei bestimmten Aktionen
gelöscht. Z.B. wird das USART RXIF durch lesen des RX-Registers gelöscht
(wenn ich's richtig in Erinnerung habe).
Ja, zum Beispiel bei ARM geschieht das nicht automatisch. Und solange
man da das Flag/Bit der Quelle, welche den Interrupt ausgelöst hat,
nicht zurücksetzt, wird sofort nach Rücksprung aus der Interrupt-Routine
wieder ein Interrupt ausgelöst.
Das hängt davon ab, was es für ein Interrupt ist.
Wenn es ein Level getriggerter Interrupt ist, wird der solange wie
der Pin LOW ist immer wieder aufgerufen. Vermute, daß es das ist was
passiert.
Ein flankengetriggerter INT wird nur jeweils einmal ausgelöst und
ausgeführt.
Gruß, Marcus
hmmm. Ich (PICer) habe mir mal ein Datasheet vom Atmega32 runtergeladen.
Da steht zumindest, das das I-Flag automatisch gelöscht wird, wenn die
ISR aufgerufen wird:
----------------------------------------------
• Bit 6 – INTF0: External Interrupt Flag 0
When an edge or logic change on the INT0 pin triggers an interrupt
request, INTF0 becomes set
(one). If the I-bit in SREG and the INT0 bit in GICR are set (one), the
MCU will jump to the corre-
sponding 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.
----------------------------------------------
Da ich aber die AVRs nicht kenne, kann ich die nicht sehr weiterhelfen.
Allerdings denke ich, dass soetwas:
Send_SMS("464646467","TESTALARM",0,0);
:
char Send_SMS (char* zielnummer,char* nachricht, char i,char j)
{
:
return (1);
}
eher schlechter Stil ist. Wenn Send_SMS ein char zurückgibt, dann sollte
der Aufruf den auch übernehmen.
char res;
res = Send_SMS("464646467","TESTALARM",0,0);
Kann es da nicht evtl. einen Stack-Überlauf geben, wenn Send_SMS einen
Wert zurückgibt, der nicht übernommen wird?
tastendrücker wrote:
> hmmm. Ich (PICer) habe mir mal ein Datasheet vom Atmega32 runtergeladen.> Da steht zumindest, das das I-Flag automatisch gelöscht wird, wenn die> ISR aufgerufen wird:
Ist beim AVR genauso.
> eher schlechter Stil ist. Wenn Send_SMS ein char zurückgibt, dann sollte> der Aufruf den auch übernehmen.
Muss aber nicht, wenn er nicht benötigt wird.
> Kann es da nicht evtl. einen Stack-Überlauf geben, wenn Send_SMS einen> Wert zurückgibt, der nicht übernommen wird?
Nein. In C ist es problemlos möglich, einen Rückgabewert zu ignorieren.
Das bringt auch keinerlei Nachteile oder Nebeneffekte mit sich. Es gibt
eine ganze Reihe Funktionen (auch Standard-Bibliotheksfunktionen), die
einen Wert zurückgeben, der aber nur in Sonderfällen wirklich sinnvoll
verwendet werden kann und deshalb in den meisten Fällen verworfen wird.
Die besten Beispiele dafür stehen in der stdio.h. Oder verwendest Du
etwa immer den Rückgabewert von printf & Co.? Schließlich gibt
printf einen int zurück...
tastendrücker wrote:
> Kann es da nicht evtl. einen Stack-Überlauf geben, wenn Send_SMS einen> Wert zurückgibt, der nicht übernommen wird?
Nein.
Es ist völlig in Ordnung (im technischen Sinne), wenn man einen
Rückgabewert nicht verwendet.
schurli wrote:
> Ausgelöst wird er duch einen prellenden Schalter. Das ist meiner Meinung> nach aber kein Grund für die Endlosschleife.
Nun, zumindest wird dadurch der Interrupt schon mal 2 mal direkt
hintereinander ausgeführt. Lösche am besten am Ende des Interrupt das
Anforderungsbit nochmal "per Hand".
Hi
Heißt das ich muss das INTF0 Bit am Intrruptende rücksetzen?
Irgendwo muss es ja auch wieder gesetzt werden, damit der Interrupt
wieder funktioniert?
---------------------------------------------------------
• Bit 6 – INTF0: External Interrupt Flag 0
When an edge or logic change on the INT0 pin triggers an interrupt
request, INTF0 becomes set
(one). If the I-bit in SREG and the INT0 bit in GICR are set (one), the
MCU will jump to the corre-
sponding 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.
---------------------------------------------------------
schurli wrote:
> Heißt das ich muss das INTF0 Bit am Intrruptende rücksetzen?> Irgendwo muss es ja auch wieder gesetzt werden, damit der Interrupt> wieder funktioniert?
Nicht, damit er wieder "funktioniert", sondern damit er nicht sofort
nochmal aufgerufen wird. Schließlich ist es zu dem Zeitpunkt schon
wieder gesetzt, und genau deswegen wird nach Verlassen des Interrupt
Handlers dieser erneut aufgerufen.
Das was Du da machst mit stangenweise printf & Co. in der ISR geht
auch nur gut, solange das der einzige Interrupt in Deinem Programm
ist...
Johannes M. wrote:
>> Das was Du da machst mit stangenweise printf & Co. in der ISR geht> auch nur gut, solange das der einzige Interrupt in Deinem Programm> ist...
Auf deutsch gesagt, es macht keinen Sinn, hier überhaupt einen Interrupt
zu verwenden.
Jürgen
schurli wrote:
> GIFR = (0<<INTF0);>> am Ende de Interrupts ändert nichts> Bitte helft mir.
Schau bitte ins Datenblatt bzw. ins AVR-GCC-Tutorial. Da steht, wie
man ein Interrupt Flag löscht. So jedenfalls nicht...
schurli wrote:
> GIFR &= 0xDF;> Brachte die Lösung!
???
1
GIFR=1<<INTF0;
hätte es getan, ist lesbar und macht wirklich genau das was es soll...
Das mit dem & funktioniert eigentlich nur zufällig wegen Nebeneffekten
von Read-Modify-Write-Operationen.