PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : INTERRUPT() statt SIGNAL()



kater
31.08.2005, 10:16
Hai, folgendes nerfiges Problem:
SIG_INTERRUPT0 ist an einem Taster angeschlossen. Wenn es ausloest. soll der Bot eine ausweich Funktion ausfuehren. Das funktionier auch alles fast perfekt. Das Problem ist, er fuehrt die Funktion ausweichen() 2, manchmal auch 4 mal hintereinander aus. Hm erstmal Quelltext:



// Ausfuehren wenn Interrupt 0 ausloest
INTERRUPT(SIG_INTERRUPT0)
{
// Interrupt INT0 ausschalten
GICR &=~ (1 << INT0);
// Mehrmals ausgeloesten Interrupt loeschen
GIFR = (1 << INTF0);
ausweichen();
// Interrupt INT0 einschalten
GICR = (1<<INT0);
}


Ich muss hier INTERRUPT statt SIGNAL nehmen weil ich die Interrupts brauche um die Geschwindigkeit zu regeln. Nun zum Code. Wenn der INT ausloest wird erstmal INT0 ausgeschaltet damit der INT nicht mehrmals ausloesen kann. Dann wird der INT0 zurueckgesetzt falls er doch ein 2. mal ausgeloest hat. Danach solle der Bot einmal ein stueck zurueck fahren und stehenbleiben. Und erst dann wird INT0 wieder eingeschlaltet.

Ich habe keine Idee mehr warum er mehrmals zurueck faehrt. Kann mir da jemand ein Tipp geben?

cavegn
31.08.2005, 10:37
hi

wie lange dauert denn das rückwärts-fahren?
und was passiert, wenn du
GIFR = (1 << INTF0);
erst nach
ausweichen();
machst?

cu

chris

kater
31.08.2005, 13:11
Einmal ausweichen dauert ca. 3sek. Es veraendert sich nichts wenn ich GIFR = (1 << INTF0); vor ausweichen() habe oder danach. Auch nicht wenn ich es davor und danach ausfuehre.
An ausweichen() kann es auch nicht liegen. Wenn ich sie testhalber vom Programm aus aufrufe und nicht ueber ein INT, funktioniert es.

Felix G
31.08.2005, 13:44
also das Setzen der Flags kommt mir ein bischen spanisch vor...
denn ich zumindest lösche Flags mit &=~ und setze sie mit |=

bei deinem Code überschreibst du dir doch z.B. mit der letzten Zeile das gesamte Register anstatt nur ein Bit zu setzen.
Ich weiss nicht ob das hier eine Rolle spielt, aber schön ist es nicht.

kater
31.08.2005, 14:15
Hehe, es funktioniert :D
Hab ich doch tatsaechlich diesen einen kleinen Senkrechten Strich uebersehen ;)
Wie meinst du das ich ueberschreibe das gesammte Register mit der letzen Zeile? Es ist doch egal ob ich GICR |= (1 << INT0); oder
GICR |= (1 << 6); schreibe. So funktioniert es jedenfalls:


INTERRUPT(SIG_INTERRUPT0)
{

// Interrupt INT0 ausschalten
GICR &=~ (1 << INT0);
// Mehrmals ausgeloesten Interrupt loeschen
//GIFR |= (1 << INTF0);

ausweichen();

GIFR |= (1 << INTF0);
// Interrupt INT0 einschalten
GICR |= (1 << INT0);

}

Felix G
01.09.2005, 05:36
klar, das ist egal...
aber wenn man den Strich vergisst wird eben alles überschrieben.