Forum: Compiler & IDEs Abfrage eines Ausgangs-Pins


von LePo (Gast)


Lesenswert?

Hallo,

ich habe vor kurzem angefangen Mikrocontroller zu programmieren und bin 
jetzt auf ein Problem gestoßen, zu dem ich im Internet leider nichts 
Brauchbares finden konnte.

An Pin A4 ist ein Transistor angeschlossen, der einen ganzen Haufen von 
weiteren LEDs betreibt. Wenn der LED-Haufen an ist, soll nebenbei noch 
eine Status-LED an PinA5 eingeschaltet sein. Wenn ich nun einen Taster 
betätige, der an INT0 angeschlossen ist, soll ein Interrupt ausgelöst 
werden, in dem der Transistor (PA4) ausgeschaltet wird und gleichzeitig 
auch die Status-LED ausgeschaltet wird.
So weit so gut.

Realisiert habe ich das so: (Auszug aus meinem Programm in der 
IR-Routine)

#if (PINA&(1<<PA4))
     PORTA &= ~(1 << PA4);
     #else
     PORTA |= (1 << PA4);
     #endif

     #if (PINA&(1<<PA4))
     PORTA &= ~(1 << PA5);
     #else
     PORTA |= (1 << PA5);
     #endif

Eingeschaltet werden beide Pins aber eben nicht ausgeschaltet. Dazu 
kommt, dass der Compiler hin und wieder den Fehler meldet, dass in der 
Bedingung des If-Konstrukts ein linker Operand fehlt. Warum weiß ich 
auch nicht.

Ich habe auch schon probiert einen Extra-Pin als Eingang zu definieren 
und den dann mit PA4 zu verbinden. Und dann eben den neuen Pin 
abzufragen. Geht leider auch nicht.

Ich weiß jetzt ehrlich gesagt echt nicht mehr weiter.

Viele Grüße
LePo

von Der Weise (Gast)


Lesenswert?

Äh, die #if, #else und #endif werden genau EIN mal beim Kompilieren 
ausgewertet, und dann je nachdem der Code darin eingefügt ins Programm, 
oder eben nicht (Preprozessor).
Du willst einfach nur if (...) { ... } else { ... }
Und:
1
if (PINA&(1<<PA4))
2
     PORTA &= ~(1 << PA4);
3
else
4
     PORTA |= (1 << PA4);
5
6
if (PINA&(1<<PA4))
7
     PORTA &= ~(1 << PA5); ...
Du änderst in den ersten 4 Zeilen den Ausgangs-Zustand von PA4, und 
fragst in dann in Zeile 6 ab, was an diesem Pin anliegt. Dann hat er 
sich aber schon geändert, sodass PA5 genau das umgekehrte Ausgabesignal 
bekommt. Außerdem bin ich mir nicht sicher, wie lange es dauert, bis das 
an PA4 ausgegebene Signal wieder am Input buffer von PA4 angekommen ist 
und in dann der if() -Abfrage korrekt verwendet wird. Es wäre doch viel 
einfacher so:
1
if (PINA&(1<<PA4))
2
     PORTA &= ~(1 << PA4);
3
     PORTA &= ~(1 << PA5);
4
} else {
5
     PORTA |= (1 << PA4);
6
     PORTA |= (1 << PA5);
7
}
Und das lässt sich dann noch abkürzen zu:
1
if (PINA&(1<<PA4))
2
     PORTA &= ~((1 << PA4) | (1 << PA5));
3
     PORTA &= ~(1 << PA5);
4
} else {
5
     PORTA |= (1 << PA4) | (1 << PA5);
6
}

von Der Weise (Gast)


Lesenswert?

Oh, hab nach den if's die { vergessen, es müsste so sein:
1
if (PINA&(1<<PA4)) {

von LePo (Gast)


Lesenswert?

Ja, hattest Recht. Jetzt funktioniert es im Grunde, aber leider sehr 
unzuverlässig. Dass heißt, von 3 eingeleiteten Interrupts funktioniert 
nur einer.
Meistens sieht es so aus, dass PA5 (Status-LED) ausgeschaltet wird, und 
kurz vor Ende der Routine wieder aus irgendeinem Grund angeht, genauso 
PA4. (Oder anders herum) Und nach knapp 3 Versuchen geht es dann auf 
einmal.

Gibt es dazu vielleicht noch einen Tip?

Vielen Dank schonmal im Voraus
LePo

von Uwe (de0508)


Lesenswert?

Mein Tipp : Taster prellen !

von Karl H. (kbuchegg)


Lesenswert?

LePo schrieb:

> Gibt es dazu vielleicht noch einen Tip?

Ja.
Interrupts zum Tastenauswerten sind ungeeignet.
Jetzt hast du auch gesehen warum. Weil Taster prellen

Entprellung

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.