du musst in der interruptroutine die motoren auch abstellen... =)
Hallo Leute!
Ich möchte mich nun mal an das Programmieren mit Interrupts heranwagen und hab dazu mittlerweile einiges gelesen. Nun zum konkreten Beispiel. Ich hab mir eine Funktion void fahren(int strecke) programmiert, die Asuro geradeaus fahren lässt. Sie funktioniert auch sehr gut, also das eigentliche Problem liegt nicht im Fahren an sich. Das Problem ist, dass ich keine Kontrolle über Asuro habe, so lange er fährt, da er ja solange in der Funktion fahren steckt. Das heißt ich kann Asuro nicht auf einen Schalter reagieren lassen, während er fährt. Die Lösung: Interrupts!
Aber irgendwie krieg ichs nicht hin. Ich zeig euch mal wie ichs probiert hab:
Dieses Programm soll Asuro 2000mm geradeaus fahren lassen und soll ihn anhalten lassen, wenn ein Schalter betätigt wird.Code:#include asuro.h #include fahren.h SIGNAL(SIG_INTERRUPT1) { StatusLED(RED); while(1); } int main(void) { Init(); StartSwitch(); fahren(2000); //lässt Asuro 2000mm geradeaus fahren StopSwitch(); while(1); return 0; }
Aber leider funktioniert es nicht. Asuro fährt seine 2000mm, egal ob ein Taster gedrückt wird oder nicht. Wo ist der Fehler?
Gruß farratt
PS: Ich nutze die originale "asuro.h", bin mehr so der Selbermach-typ...
du musst in der interruptroutine die motoren auch abstellen... =)
Stimmt zwar, aber die StatusLED wird nicht rot, also muss irgendwo noch ein fehler sein.
Wir können mal einen einfacheren Code betrachten:
Nachdem die Init() ausgeführt wurde, ist die StatusLED krühn.Code:#include "asuro.h" int main(void) { Init(); StartSwitch(); while(1); return 0; } SIGNAL(SIG_INTERRUPT1) { StatusLED(RED); StopSwitch(); while(1); //Diese Endlosschleife kann man weglassen, oder? }
Der Code sollte die StatusLED auf rot schalten, falls ein Schalter gedrückt wird, tut er aber nich. Sie bleibt grün.
Wo is der Fehler?
Einen Hardware-Fehler kann ich ausschließen, weil die Taster im Polling-Betrieb einwandfrei funktionieren.
diese endlosschleife bewirkt, dass die interruptroutine niemals verlassen wird. tödlich!!
ansonsten verwende mal nicht startswitch sondern nutze die register um niterupts zu aktivieren. entferne startswitch und stopswitch, und schreibe stattdessen sei(); hinter init();.
welche version des GCC compilers benutzt du?
Hi,
da ich leider die ASURO lib nicht kenne, kann ich nur allg. Betrachtungen anstellen. Aber vielleicht hilft das ja schon...
Die Interrupts muessen auch aktiviert sein, sind sie das auch standardmaessig? Du hast zumindest keinen expliziten Code dafuer ...
Eine Endlosschleife in einer ISR halte ich fuer keine gute Idee. Eine ISR sollte kurz sein, was man von einer Endlosschleife nicht gerade behaupten kann.
Innerhalb einer einfachen ISR wird meisst zunaechst der IRQ disabled um nested IRQs zu vermeiden. Am Ende der ISR wird er dann wieder altiviert.
HTH
Kay
irqs sind automatisch deaktiviert beim start der routine. es fehlt jedoch ein return am ende!!!
probier mal folgenden code:
[code]#include "asuro.h"
int main(void)
{
Init();
StatusLED(GREEN);
while(1);
return 0;
}
SIGNAL(SIG_INTERRUPT1)
{
StatusLED(RED);
return;
}
Ich bin mir nicht sicher, sind ISR nicht void Funktionen ...?
Dann braucht man nicht unbedingt ein return, mit verlassen des Blocks kehrt er automatisch zurueck. "return value" braucht man nur zwingend bei nicht void-Funktionen, oder?
Aber es ist zumindest besser zu lesen und macht die Absicht des Entwicklers deutlicher (nicht nur "aus Versehen" zurueck) ...
ohne return werden jedoch die interrupts nicht wieder aktiviert...
Lesezeichen