Hallo liebe Gemeinde, folgendes Problem habe ich: Habe auf meinem Board mit nem Atmega8 einen Taster an INT1 hängen. Dieser ist hardwaremäßig entprellt (analago zu dem Beispiel zur ENTPRELLUNG von mikrocontroller.net). Das Hauptprogramm seht ihr im Anhang. Das Programm legt sich nach der Initiallisierung des Notwendigen schlafen und wird durch den Taster (Int1 dann auf GND) geweckt. Danach wird lediglich der INT1 deaktiviert und das "clientmenu" aufgerufen. In clientmenu(); passiert prinzipiell nichts weiter als dass die Dauer des Tastendrucks (welcher den INT1 auslöste) "gemessen" wird. Und dann in Abhängikeit der Dauer zwischen 3 auszuführenden Funktionen gewählt wird (kleiner 100 = 1s, 100-400 = 1-4s, größer 400 ), Dazu dient folgende Funktion: unsigned int taster_time(void) { unsigned int i = 0; led_on(); //warte solange taste gedrückt ist while( !(TASTERPIN & (1<<TASTER)) ) { _delay_ms(10); i++; } _delay_ms(30); return i; } Ich weiß das man so etwas mit Timer sinvoll lösen können soll aber so war es erstmal einfacher. Das Problem ist nun, dass bei zu schnell aufeinander folgenden Tastendrücken das Programmen sich aufhängt. Ich also die Batterie raus und rein tun muss. Zu schnell bedeutet hier, dass 3 Drücke pro Sekunde meist kein Problem sind aber wenn man es richtig drauf anlegt, hängst es. Die Entprellung sieht auf dem Oszilloskop recht gut aus, auch bei den "Zerstörer"-Tastendrücker. Daher frag ich mich, wo die Ursache dafür liegt? Als kleine Debug-Hilfe schaltet die taster_time(); eine LED ein , das Auschalten der LED (led_off();) habe ich dann immer weiter nach hinten geschoben. Damit wollte ich feststellen wo das Programmen hängen bleibt. Das led_off(); in der Interrupt-Routine hinter clientmenu(); wurde immer ausgeführt. Also auch wenn das Prog hingen blieb, ging die LED aus. Die nächst möglichste stelle sollte dann ja die Stelle sein, wo das Programm nach der Interrupt-Routine weiterläuft. So habe ich das led_off(); dorthin verschoben. nun blieb die LED an, wenn das Programm sich aufhing. Also ergeben sich mir 2 Fragen, warum hängt sich das Programm bei zu schnellen Tastendrücker auf? Und warum schaltet die LED in der ISR aus, direkt danach aber nicht? (Siehe Code im Anhang). Vielen dank für jene die themenbezogen helfen wollen! mfg
Mich irritiert mich das: <code> while( !(TASTERPIN & (1<<TASTER)) ) </code> Um einen Taster an Port A4 abzufragen, würde ich sowas schreiben: <code> while ( !(PINA & (1<<4)) ) </code> Leider ahst Du auch nicht den QUelltext gepostet, wo die beiden Konstanten für den Taster deklariert sind. Den Namen nach vermute ich allerdings, dass Du TASTERPIN und TASTER vertauscht hast und dass sich das Programm deswegen an dieser Stelle aufhängt.
Ja sorry... die defines dazu habe ich versäumt zu posten... Hier: ///////////////////////////////////////////////////// ////// LED Funktionsbekanntgabe + Taster ///////// ///////////////////////////////////////////////////// //LED udn AUSGANG #define LEDDDR DDRB #define LEDPORT PORTB #define LED1 PB1 //TASTERPORT #define TASTERDDR DDRD #define TASTERPORT PORTD #define TASTERPIN PIND #define TASTER PD3 ///////////////////////////////////////////////////// // LED Ports initialisieren ///************/ //plus Taster1 ///////////////////////////////////////////////////// void init_port() { LEDDDR |= ( (1<<LED1) ); // PIND 3 als Ausgang LEDPORT &= ~( (1<<LED1) ); //ausgange auf low TASTERDDR &= ~(1<<TASTER); //Taster als Eingang //TASTERPORT &= ~(1<<TASTER); //TASTER ohne Pullup TASTERPORT |= (1<<TASTER); //TASTER mit Pullup // für Lvl-Interrup, Taster zieht eingang nun auf GND nicht auf 3/5 Volt }
Also, jetzt rein vom Gefühl her: ein zeitliches Delay von zig ms innerhalb einer Interruptroutine macht man einfach nicht. Was passiert denn, wenn die Taste 1 min gedrückt ist, mit den weniger priorisierten Ints oder dem Hauptprogramm, das vielleicht zyklisch einen Port pollt etc.? Bevor ich mir den Riss gebe, warum dieses Konsrukt nicht funktioniert, baue ich es doch besser mit Timer oder setze schnell ein Bit oder eine Semaphore etc in der INT Routine und kehre schnell zurück, Im Hauptprogramm schreibe ich dann eine Stoppuhr, insbesondere bei einem kleinen uc wie dem M8. Nur mal so als Vorschlag...
ah du meinst.. den ISR nur zum aufwachen benutzen und den rest im hauptprogramm erledigen... das ist ein guter Ansatz bzw ein Versuch wert! was passiert wenn er 100 Sekunden fgedrückt wird war mir "relativ" egal. Da das ein - ich sag mal - Lichtschalter ist, der in der regel nur schläft und meist nur was anschalten soll. die beiden optioen länger zu drücken sind für eine art Einstellung gedacht. Im schlimmstenfall hatte ich mir vorgestellt, passiert bei so langem drücken einfach ein Überlauf der Zählervaiable (unsigned int ca 6500 Sekunden). Dass eine solche Dauer oder auch meine sonstigen Taster-Dauer in der ISR grundsätzlich problematisch sind, habe ich garnicht bedacht.
Die Abfrage der Taste ist jedenfalls nicht falsch, jetzt wo ich die Definitionen sehe.
also habe das clientmenu raus aus der isr genommen und unter das sleep gedöns in der main gepackt... ändert leider nichts an den abstürzen :-(
Christian Peskov schrieb: > keine weiteren Ideen?? Wie wäre es mit vollständigem Quellcode? Oder habe ich da was übersehen?
Wie hat du die Fuses programmiert? Slow or fast rising power? Interner Oszillator oder externer Quartz? Welche Versorgungsspannung? Bei slow rising power braucht der Atmega ja 65ms+ um aus dem power down sleep mode aufzuwachen. Bei dir scheint er sich aufzuhängen wenn in dieser Zeit ein zweiter INT1 interrupt reinkommt. Programmier doch spasseshalber mal fast rising power, um zu sehen, ob sich dann am Verhalten was ändert. LG, Sebastian
das klingt ganz schön plausibel für eine mögliche Abhilfe... wen dieses Karnevalgedöns mich in ruhe lässt, werde ich testen, ob die änderung der aufweckzeit besserung bewirkt. danke. an stk500 besitzer: nein du hast nichts übersehen.. aber statt die weiteren 5 includes zu posten habe ich es umschrieben. und es wird (wie du siehst) nur die clientmenu per INT aufgerufen. Und da werden nunmal nur die drei beschriebenen Fälle unteschieden. im innern dieser funktion und der entsprechnenden Includes vermute ich die ursache NICHT. mfg
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.