Moin,
bin wieder an meinem MK2-Board am Gange.
Ich habe im Vorfeld ein funktionierendes Programm geschrieben, dass
einen Taster als Schalter verwendet, um eine LED ein- bzw.
auszuschalten. Es soll auch nichts anderes passieren, auch wenn ich die
Taste gedrückt halte. Dazu habe ich die negative Flanke verwendet. Ich
erwähne es deshalb, weil ich Teile davon in meinem neuen Programm
verwende. Nun bin ich mutiger geworden:
Neues Projektchen:
Verwendung von 8 Tastern um 8 LEDs ein-auszuschalten (wie oben). Aber
die 8 Taster sollen nicht 8 Inputbits belegen, sondern nur 4. Ich wollte
es binär lösen.
Taster 1 = Bit 0
Taster 2 = Bit 1
Taster 3 = Bit 0 + Bit 1
etc.
Hier der Code:
Ich bin mir sicher, dass es eleganter und kürzer geht. Aber mir geht es
darum, meine Ausführung zum Funktionieren zu kriegen und zu verstehen,
warum etwas nicht funktioniert. Wenn alles klappt, dann wollte ich mich
ransetzen und Kürzungen etc. einbringen.
Ich bin Schritt für Schritt vorgeangen. Wenn ich die Zeile 43 durch //
rausnehme, dann funktioniert das Ganze. Eben nur mit einem Taster1
(PINB0) und einer LED (PINC0).
Wenn ich aber den Code, so wie er oben ist abrabeiten lasse, dann
funktioniert die Sache mit Taster2 (PINB1) und LED (PINC1) aber der
Taster1 funktioniert nicht mehr.
Wenn ich die Zeile 50 aktiv mache, dann funktioniert kein Taster mehr.
Laut Simulation springt der Controller immer zwischen den Zeilen 42 und
59. Es scheint ihn nicht zu interessieren, dass sich sig0 bzw. sig1
geändert haben.
Ich hoffe, es kann mir jemand helfen. Ich sitze bereits seit gestern
dran und finde einfach den Fehler nicht.
Danke im Voraus.
_______________
Tue deinem Körper etwas Gutes, damit die Seele Lust hat darin zu wohnen
!
Wie sieht denn deine Schaltung aus? Binär kann immer nur einer gedrückt
sein. Außerdem müsste man viele Dioden brauchen. Und die ersten 4bits
eines Ports einlesen geht so: uint8_t key = PORTB & 0x0F. Die letzten 4
mit 0xF0.
Hi
Wenn du dies nur machst, um dir Eingänge zu sparen, ist es vielleicht
eine bessere Lösung, die Taster über eine Matrix einzulesen. Allerdings
brauchst du dafür auch einen Ausgang und einen Inverter oder 2 Ausgänge
zusätzlich. Macht aber Sinn, wenn es mehrere Eingänge braucht, als IO'
vorhanden sind.
Dazu legst du deine Taster Parallel auf die Eingänge, z. B. in 4er
Gruppen. Jede Gruppe steuerst du mit einem Ausgang an. Im Programm weist
du ja, welche Gruppe grad selektiert ist und du brauchst die Eingänge
nun nur noch entsprechend zu behandeln. Andere Alternative ist
tatsächlich sowas wie 8 zu 3 Decoder. gibt es in der 74er IC-Serie
(Oktaldecoder oder so ) Hier kannst du deine Taaster an die 8 Eingänge
schalten und das IC bereitet einen Code aus drei Bits auf.
Such mal nach Oktaldecoder, vielleicht weiß Google da was.
Gruß oldmax
@ sam1994
Hallo,
das ist richtig. Es soll immer nur einer gedrückt werden. Mit Dioden
meinst du sicherlich Halbleiterdiode (und nicht LED). Das stimmt, aber
es soll letztendlich erstmal die Umsetzung und das Verständnis in
C-Programmierung im Vordergrund stehen. Natürlich hat das ein sinnvollen
Hintergedanken. Und zwar die Verwendung von z.B. Tastern auf
Folientasterturen.
Das Schaltbild habe ich hochgeladen.
Du hast geschrieben: "... Ports einlesen geht so: uint8_t key = PORTB &
0x0F"
Hmm, damit lese ich doch den Port aus, richtig? Ich benötige doch den
Pin, um die Änderung festzustellen, oder?
Wie im ersten "Aufsatz" erwähnt, habe ich ein Programm das funktioniert,
wo ich den PIN (wo der Taster angeschlossen ist) abfrage:
[c]
/*----------------------------------------------------------------------
-------
ON - OFF switch with pushbutton
Pushbutton with no change if keep holding pushbutton.
Can be used for selection button (if holding button longer, the output
status
won't change.
------------------------------------------------------------------------
-----*/
// pushbutton on PORTB 1
// LED on PORTC 0
#include <avr/io.h>
#include <util/delay.h>
int main (void)
{
DDRC &= ~(1<<DDC1); // set PORTC1 for input other keep unchanged
DDRC |= (1<<DDC0); // set PORTC0 as OUTPUT for LED
PORTB |= (1<<PORTB1); // set PullUp for INPUT
char status=0;
uint8_t sig, sig_alt;
sig_alt=1;
while(1)
{
sig=PINB & (1<<PB1); // Read signal of PIN1
if (sig==0 && sig_alt!=0) // negative slope of signal? -->
pushbutton pressed
{
_delay_ms(20);
if (status==0)
{
PORTC |= (1<<PC0); // LED ON
status=1;
_delay_ms(100);
}
else
{
PORTC &= ~(1<<PC0); // LED OFF
status=0;
_delay_ms(100);
}
}
sig_alt=sig;
} // end of while(1)
} // end of main
[c/]
Wenn ich in Zeile 33 statt "sig=PINB & (1<<PB1);" "sig=PORTB &
(1<<PB1);" schreibe funktioniert es nicht mehr.
Vielleicht verstehe ich deinen Hinweis nicht.
@sternst
Danke. Ich werde es mir gleich mal anschauen. Aber eine Frage vorab:
Wann soll sig1 = 2 werden? Wo siehst du das? Ich zähle doch nichts hoch
bzw. addiere etwas zueinander. Nach meinem Verständnis haben meine sig
bzw. sig_alt Variablen nur die Zustände 0 oder 1.
@oldmax
Danke, aber ist mir noch zu weit weg. Ich möchte erstmal meinen Mist
hier verstehen.
EdTheB
@sternst
Jetzt weiss ich was du mit der 2 meinst. Ich kriege den Bit-Wert von PB1
raus? Ich dachte, wenn ich den PIN auslese erhalte ich entweder 0 oder 1
und nicht die Wertigkeit des PINs.
Das heißt, wenn z.B. der PIN7 auf High ist und ich den PIN abfrage, dann
erhalte ich die Wertigkeit (hier 128) zurück?
Danke.
Werde erst heute abend oder morgen Zeit haben, diese neue Erknenntnis in
mein Programm einbauen.
EdTheB
Eduard "A" schrieb:> wenn ich den PIN auslese erhalte ich entweder 0 oder 1> und nicht die Wertigkeit des PINs.
So was wie "den PIN auslesen" tust du gar nicht. Du ließt den kompletten
Port (alle acht Pins, also 8 Bits) und dann maskierst du ein einzelnes
Bit aus. Und das Ergebnis ist dann halt entweder 0, oder der Wert, der
sich ergibt, wenn nur diese eine Bit im Byte 1 ist.