Forum: Mikrocontroller und Digitale Elektronik Interrupt dauerhaft laufen lassen...


von Christian Buntrock (Gast)


Lesenswert?

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

von Andi K. (Gast)


Lesenswert?

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

von Christian Buntrock (Gast)


Lesenswert?

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?

von Thomas Burkhardt (Gast)


Lesenswert?

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...

von Christian Buntrock (Gast)


Lesenswert?

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... :)

von Thomas Burkhardt (Gast)


Lesenswert?

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.

von Andi K. (Gast)


Lesenswert?

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

von Christian Buntrock (Gast)


Lesenswert?

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 Andi K. (Gast)


Lesenswert?

Von wem oder was wird der Taster gedrückt?
Von einer Nocke?

MfG
Andi

von Christian Buntrock (Gast)


Lesenswert?

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...^^

von Christian Buntrock (Gast)


Lesenswert?

gibts denn keine möglichkeit das regelmäßig abzufragen??

von Thomas Burkhardt (Gast)


Lesenswert?

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?

von Christian Buntrock (Gast)


Lesenswert?

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

von Christian Buntrock (Gast)


Lesenswert?

wie könnte man denn das mit nem timer lösen?
bzw. wo müsste dann die abfrage hin?

von Andi K. (Gast)


Lesenswert?

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

von Christian Buntrock (Gast)


Lesenswert?

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...^^

von Christian Buntrock (Gast)


Lesenswert?

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?

von Hannes L. (hannes)


Lesenswert?

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.

...

von Christian Buntrock (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.