Hallo, ich bins wieder ;) Ich habe noch eine kurze Frage... Und zwar möchte das ein Pin dauerhaft überprüft wird. D.h. es soll einen Pin geben, der wenn er gesetzt wird oberste Priorität hat und alles andere erstmal unterbricht... Nun das hört sich ja sehr nach Interrupts an :) Ich habe also INT1 genommen. In der INT1-Funktion setze ich ne LED auf 1 zur Controlle. Mein Problem ist, ich möchte nicht einen delay oder so einbauen, damit man die LEDS sieht. Ich möchte es so machen, dass die LEDS solange an bleiben, bis man den INT1-Pin wieder loslässt. D.h. wie eine art gedrückt halten und wenn man loslässt gehen sie wieder aus... Wie könnte man das machen? Der Pin ist übrigens der selbe wie PORTD Pin 3, aber so richtig wusste ich trotzdem nichts damit anzufangen. :( thx!!! grüße Christian
Anhand der Bezeichnung "PORTD" meinst Du wohl einen AVR, richtig? Wenn dem so ist, stell den INT1 auf Flankenwechsel oder Toggle oder Rais and Falling, wie auch immer das im Datasheet heißen mag. In der ISR (Interrupt Service Routine) fragst Du dann den Pin für INT1, PinD.3, ab ob high- oder low-Pegel und schaltest die LED je nach dem ein oder aus. MfG Andi
Hi. Erstmal danke für den Post. Ich habe es jetzt mal damit versucht (in der Interupt-Routine): PORTC=0x33; //LED'S while(PIND.3==1) { delay_ms(1); } PORTC=0x00; jedoch bleiben die LEDS aus (bzw. gehen so schnell an und wieder aus das ich es nicht sehe...). das liegt an der while-bedingung, oder?
Hi, Grundsatz 1: keine Delays in Interruptroutinen! Nur um klarzustellen, dass wir uns richtig verstehen. Taster gedrückt -> LED an Taster nicht gedrückt -> LED aus Es geht so, wie Andi schon schrieb. Der ext. Interrupt kann so eingestellt werden, dass die ISR bei jeder Flanke aufgerufen wird. Du musst also in der ISR nur den aktuellen Zustand des Pins einlesen und die LED entsprechend setzen. Danach musst du nicht warten, sondern kannst die ISR verlassen. Das Abschalten geschieht schliesslich analog durch den Aufruf des Interrupts. Wenn du allerdings eine Taster einlesen willst, ist Pollen mit Entprellung vermutlich vorzuziehen...
Hmm. Ja ich glaube auch dass das für diesen Fall sinnvoller wäre weil es ja permanent überprüft werden soll. Jetzt frage ich mich nur, wo ich das pollen machen muss... :)
Hi, in der Hauptschleife oder auch nicht schlecht per Timer. Schau dir mal die Codeteile auf http://www.mikrocontroller.net/articles/Entprellung an. Ich gehe davon aus, dass du einen Taster verwendest. Soll nämlich ein schnelles Logiksignal ausgewertet werden, dann ist die regelmäßige, aber vergleichsweise langsame Abtastung insofern schlecht, als dass kurze Impulse einfach übersehen werden.
Am besten in einer Timer-ISR mit mindestens 100Hz. Dort einfach PinD.3 auf 0 oder 1 prüfen. Ist es 0 (Taster gedrückt) LED an, ist es 1, LED aus. Sofern Deine Main-Schleife nicht mit allzu viel beschäftigt ist, kannst es auch dort machen sofern mit dem Taster nichts anderes angestellt werden soll wozu eine Entprelung benötigt werden würde. MfG Andi
hmm. naja was heißt kurz? im ms-bereich? also ich denke der taster ist immer so 20-30 ms gedrückt. danach wird er wieder losgelassen. die dauer kann aber auch variieren. aber unter 10 ms geht das denk ich auf keinen fall. wie lange dauert denn diese dauer, in der geprellt wird?? ist das pollen hier nicht so sinnvoll? was halt letztendlich wichtig ist, ist das die auch immer an ist, wenn der pin berührt wird. egal was ist. das hier soll oberste priorität haben...
Von wem oder was wird der Taster gedrückt? Von einer Nocke? MfG Andi
ne von einem menschen^^ aber das passiert immer recht schnell weil ich noch gewicht dahinter habe und der taster empfindlich ist. aber ich kann ehrlich gesagt auch nicht gut einschätzen wie lang 10ms sind^^ also es kann sein das es auch etwas länger dauert...^^
Hi, wie meinen? Natürlich kannst du regelmäßig abfragen, genau das machen Timer. 20 ms zum Tasterdrücken - da brauchst du schon nen schnellen Zeigefinger... Was ist jetzt nochmal genau das Problem?
hmm. timer. daran habe ich noch gar nicht gedacht. wichtig ist jedoch, dass es immer regelmäßig ausgeführt wird. das problem: ich möchte das wenn ein pin gesetzt wird, das dann ein anderer pin (an dem eine led ist) ebenfalls gesetzt wird. wichtig ist mir halt, dass dieser pin absolute prirität hat. d.h. sobald man diesen pin setzt, muss die LED immer angehen. alles andere hat in dem moment niedrigerere priorität... danke!!! gruß christian
wie könnte man denn das mit nem timer lösen? bzw. wo müsste dann die abfrage hin?
Du stellst den Timer auf 1/1000. Jede Millisekunde wird in dem "Timer-Programm" der PinD.3 abgefragt und je nach Zustand setzt Du auch in dem "Timer-Programm" die LED auf low oder high. Ansonsten wie in dem von mir ersten Beitrag in dem "INT1-Interrupt-Programm" bei Flankenwechsel genauso wie in der Timer-ISR. Wurde alles ab meinem ersten Beitrag bereits erwähnt. MfG Andi
hmm. wie bzw. so schreibt man das timer-programm hin? ich kenne nur das man das timer-register TCNT abfragt. Wäre aber schön wenn es sowas gebe. Das ich unabhängig von allem anderen immer eine Routine regelmäßig durchlaufen lassen kann. 1ms würde denke ich da auch locker reichen...^^
ahh. ich habe mal hier im tutorial geguckt. da steht "Der Zähler zählt nun aufwärts bis 255, um dann wieder bei 0 zu beginnen. Der aktuelle Zählerstand steht in TCNT0. Bei jedem Überlauf von 255 auf 0 wird das Timer Overflow Flag TOV0 im Timer Interrupt Flag TIFR-Register gesetzt und, falls so konfiguriert, ein entsprechender Timer-Overflow-Interrupt ausgelöst und die daran gebundene Interrupt-Routine abgearbeitet." könnte es damit gehen?
Vielleicht solltest du mal anhand des Datenblattes des verwendeten AVRs ermitteln, wie der verwendete Timer aufgebaut ist, also über welche I/O-Register er verfügt, welche Werte in welche Register eingetragen werden müssen um eine bestimmte Funktion zu erreichen. Die Timer der AVRs sind nämlich sehr unterschiedlich ausgestattet, da kann man schlecht global gültige Aussagen machen. Im Prinzip musst du dafür sorgen, dass ein Timer in regelmäßigen Abständen einen Interrupt auslöst. Für diesen Interrupt schreibst du dann eine ISR (Interrupt-Service-Routine), die vom zugehörigen Int-Vektor aufzurufen ist. In dieser ISR werden dann die betreffenden Eingänge abgefragt und ggf. entprellt. ...
juhuu. danke es hat funktioniert =))) habe das jetzt so gemacht: -------------- interrupt [TIM0_OVF] void timer0_ovf_isr(void) { if(PINB.0==0 && PINB.1==1) ... } --------------------- funktioniert prächtig! =) danke nochmal an euch!!
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.