Guten Abend zusammen. Ich brauche dringend einen frischen Denkansatz für mein Problem, darum hoffe ich auf Hilfe durch dieses Forum, bzw. seine Nutzer. Folgendes Problem raubt mir seit drei Tagen den letzten Nerv und ich glaube, ich habe mich da etwas verfahren. Jedenfalls finde ich selber keine Lösung. Es geht um eine Temperaturregelung. Eine Temperatur wird eingelesen, mit einem Sollwert verglichen und anhand dessen ein Regelungsvorgang vollzogen. Grundsätlich wird die Regelung nur über zwei Taster bedient: Solltemperatur "Auf" und "Ab". Soll- und Ist-Wert werden über ein LCD-Display ausgegeben. Bei einem Tastendruck auf die Tasten "Auf" oder "Ab" wird ein Interrupt ausgelöst, der den µController aus der Regelschleife holt und den Sollwert inkrementiert bzw. dekrementiert. Danach geht's wieder in die Regelschleife. Als Testplatform nutze ich hier ein STK500 und einen Atmega32. Auf meiner Fehlersuche habe ich das Programm bereits soweit abgespeckt, daß eigentlich nur noch die Interruptfunktion für einen Taster über ist, die primitiver Weise den LED-Block des STK500 Board löschen soll. Aber trotz des reduzierten Codes begreife ich nicht, was ich falsch geschrieben habe. Evtl. liegt hier ein "Man sieht den Wald vor lauter Bäumen nicht"-Effekt vor, weil ich schon zu lange an diesem Fehler arbeite. Jedenfalls möchte ich mich jetzt schonmal bedanken, falls sich jemand die Mühe macht, mit mir zu grübeln und mir zu helfen.
Vielleicht noch die Register GICR und ggf. MCUCR passend setzen?
Chris G. schrieb: > Aber trotz des reduzierten Codes begreife ich nicht, was ich falsch > geschrieben habe. Du musst den INT0 schon auch noch freigeben. Im Moment sind zwar Interrupts gnerell freigegeben, aber die spezifische Freigabe des INT0 ist nicht vorhanden. Aber eigentlich ist das sowieso keine gute Idee, Taster über einen Interrupt Eingang auszuwerten. Die bessere Variante sind die Komfort-Taster Entprellroutinen, die über einen Timer Interrupt die Taster pollen und gleichzeitig entprellen *) sie funktionieren wesentlich besser, egal wie stark die Taster prellen *) durch die Autorepeatfunktion ermöglichen sie auch komfortable Eingaberoutinen, ohne dass sich der Benutzer an den Tasten einen Wolf drückt. *) Sie sind einfach in der Verwendung http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
Problem 1: Du hast nicht geschrieben, wo du jetzt eigentlich ein Problem hast :-) Problem 2: Tastenabfrage im Interrupt ist - zumindest ist das die Meinung hier im Forum - ein großes "No Go!" Entprellung ist hier das Stichwort (such mal im Forum nach "Entprellung in Software" Das was ich alleine an Deinem Codeschnipsel sehe ist folgendes: - Ein Interrupt wird ausgelöst, "keypressed" wird gesetzt - Hauptschleife fragt "keypressed ab uns setzt keypressed auf 0 - Tastenprellen löst weiteren Interrupt aus und setzt keypressed wieder auf 1 ;-) Ein Ansatz wäre zum Beispiel, die Tastatur regelmäßig im Timerinterupt abzufragen, z.B. (Pseudocode) // Beispiel: 4 Tasten an Port D, Bit 0-3 static uint8_t keypressed[3], keydebounce[3]; ISR(...) /* aufruf alle 10ms */ { uint8_t i; for (i=0; i<=3; i++) { if (PIND & 1<<i) { if (keydebounce[i]++ == 10) /* nach 0.1s wird Taste erkannt */ keypressed[i]++; if (keydebounce[i] > 80) keydebounce[i] = 0; } else keydebounce[i] = 0; /* Alternative: oder keydebounce[i] = keypressed[i] = 0 */ } } hiermit wird alle 0.8+0.1 = 0.9 Sekunden ein Tastendruck erkannt (auto-repeat). Du könntest sogar im Hauptprogramm 5 Sekunden schlafen und würdest nun in keypressed[i] entsprechend der Dauer des Tastendrucks eine "5" vorfinden im Hauptprogramm fragst du nun nur keypressed[x] ab: .. if (keypressed(0) { x = x + 1; /* oder x = x + keypressed(0); */ keypressed(0) = 0; } Mit dem "Alternativen" Codeschnippsel würde die Interruptroutine bei Loslassen auch den Taste-gedrückt-Code löschen, falls also das Hauptprogramm noch nicht dazu gekommen wäre keypressed[0] auszuwerten würde es nichts tun. Just my 2 cent PS: Ich kriege - auch mit 3 Glas Rotwein intus - jedes mal Augenkrebs wenn ich "LCD-Display" lese ;-)
Dann nimm noch ein paar und es wird besser. :-) PS: Gute Idee, prost!
Torsten K. schrieb: > if (keypressed(0) > { > x = x + 1; /* oder x = x + keypressed(0); */ > keypressed(0) = 0; > } Es muß latürnich if (keypressed[0]) { x++; /* oder: x = x + keypressed[0]; */ keypressed[0] = 0; } heißen... und statt static eventuell volatile ;-)
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.