PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SR- bzw. RS-Flip Flop



Ezalo
27.10.2010, 20:15
Guten Abend,

um meine Weichenantriebe der Modellbahn zu schalten verwende ich Relais. Jedes Relais wird über einen Transistor angesteuert. Das Relais muss anziehen wenn ich einen Taster drücke und solange angezogen bleiben bis ich einen anderen Taster drücke.

Teste dies z.Z. mit 2 Tastern (PA1 und PA2) und einer LED (PA0).

Hier mal der Code an dem ich nicht mehr weiter weiß:


int main(void){
DDRA |= 0b00000001; //PA0 als Ausgang definieren
PORTA &= ~(1<<PA0); //PA0 auf Low schalten (LED aus)
PORTA |= (1<<PA1), (1<<PA2);//PA1 und PA2 auf High setzen
while(1){
if((!(PINA&(1<<PIN1))) && (PINA&(1<<PIN2))){ //Wenn Taster (PA1) betätigt und Taster (PA2) nicht betätigt, dann...
while((PINA&(1<<PIN2)) && (PINA&(1<<PIN1))){ //...weil Taster (PA1 und PA2) nicht betätigt....
PORTA |= (1<<PA0); //... schalte LED ein
}
}
/* else if((!(PINA&(1<<PIN2))) && (PINA&(1<<PIN1))) { //wenn Taster (PA1) nicht betätigt und Taster (PA2) betätigt...
PORTA &= ~(1<<PA0); //... dann LED aus
}*/
}
return 0;
}

Sobald ich die "else if" anweisung nicht auskommentiere geht die LED nach loslassen von Taster (PA1) wieder aus.

Ich weiß solangsam nicht mehr was ich dan dem Code noch ändern soll... :-k

MfG

Ezalo

Slein
27.10.2010, 21:55
Das while mittendrin erschließt sich mir nicht...

Versuchs mal so, evtl. ist es das ja was du willst?

int main(void){
DDRA |= 0b00000001; //PA0 als Ausgang definieren
PORTA &= ~(1<<PA0); //PA0 auf Low schalten (LED aus)
PORTA |= (1<<PA1), (1<<PA2);//PA1 und PA2 auf High setzen
while(1){
if((!(PINA&(1<<PA1))) && (PINA&(1<<PA2))){ //Wenn Taster (PA1) betätigt und Taster (PA2) nicht betätigt, dann...
PORTA |= (1<<PA0); //... schalte LED ein
}
if((!(PINA&(1<<PA2))) && (PINA&(1<<PA1))) { //wenn Taster (PA1) nicht betätigt und Taster (PA2) betätigt...
PORTA &= ~(1<<PA0); //... dann LED aus
}
}
return 0;
}

Ezalo
28.10.2010, 15:46
Dein Vorschlag entspricht aber keinem SR-/ RS-Flip-Flop.
Ein SR-/ RS-Flip-Flop wird durch eine 1 (also Taster PA1) am S Eingang gesetzt, also Q = 1.
Wenn ich jetzt eine 1 (Taster PA2) am Eingang R habe, wird das SR-/ RS-Flip-Flop zurückgesetzt, also Q = 0.
Q = Ausgangsbezeichnung

Slein
28.10.2010, 18:38
Hhhhhmmm,
der code macht die LED an, wenn PA1 gedrückt wird und PA2 nicht.
Die LED geht aus, wenn PA2 gedrückt wird und PA1 gerade nicht.

Es wird in einer Endlosschleife geprüft, ob einer der Fälle zutrifft.
Dann wird entsprechend die LED gesetzt oder ausgemacht.
Trifft keine der Bedingungen zu, wird nichts verändert:
LED ist an, bleibt auch an.
LED ist aus, LED bleibt auch aus.

IMHO das was du beschreibst. :-s

Ich glaube, du versucht mit deinem code ein Verhalten zu beschreiben,
solltest aber eher in Zuständen denken.

PS: meine Variante mal ausprobiert?

nochn PS: wenns nicht geht probier mal dieses:
DDRA = 0b00000001; //PA0 als Ausgang definieren, Rest als Eingang

Ezalo
28.10.2010, 19:04
zum 1. PS: Ja habe ich.
zum 2. PS: Macht kein Unterschied.

Zum Rest:
Wenn ich bei deinem Quellcode PA1 drücke geht die LED an und nach loslassen von PA1 geht sie wieder aus. Halte ich PA2 jetzt gedrückt und drücken dann PA1, bleibt die LED aus. Also dominierend Rücksetzen. Die while Schleife kamm mir in den Sinn, weil das Programm dann in der while Schleife hängen bleibt, zmd solange ich die else Anweisung auskommentiere.

Slein
28.10.2010, 20:10
Habs mal durch den Emulator gejagt.

PORTA |= (1<<PA1), (1<<PA2);//PA1 und PA2 auf High setzen
setzt den Pullup nur für PA1 O:)

Das hier tuts :D
PORTA |= (1<<PA1) & (1<<PA2);//PA1 und PA2 auf High setzen

Ezalo
28.10.2010, 20:38
Hm... bei dir geht der Code also so?



int main(void){
DDRA = 0b00000001; //PA0 als Ausgang definieren
PORTA &= ~(1<<PA0); //PA0 auf Low schalten (LED aus)
PORTA |= (1<<PA1) & (1<<PA2);//PA1 und PA2 auf High setzen
while(1){
if((!(PINA&(1<<PA1))) && (PINA&(1<<PA2))){ //Wenn Taster (PA1) betätigt und Taster (PA2) nicht betätigt, dann...
PORTA |= (1<<PA0); //... schalte LED ein
}
if((!(PINA&(1<<PA2))) && (PINA&(1<<PA1))) { //wenn Taster (PA1) nicht betätigt und Taster (PA2) betätigt...
PORTA &= ~(1<<PA0); //... dann LED aus
}
}
return 0;
}

Bei mir: LED glimmt (also nicht aus ^^)
Bei betätigen von PA1: LED leuchtet
Loslassen von PA1: LED aus
Bei betätigen von PA2: LED aus (also glimmt nicht mehr)
Bei gedrückt halten von PA2 + PA1 betätigen: LED aus

Irgendwie klappt das bei mir nicht :(

BurningWave
28.10.2010, 21:29
Im Prinzip muss dein Programm doch so aufgebaut sein:

-Überprüfen ob, Taste 1 gedrückt ist (und Taste 2 nicht)
----Wenn ja: LED einschalten
-Überprüfen, ob Taste 2 gedrückt ist (und Taste 1 nicht)
----Wenn ja, LED ausschalten
--Von vorne beginnen--

EDIT: Oh ich habe gerade bemerkt, dass du soweit schon warst ;) Wie sind die Tasten denn genau an den µC angeschlossen? Ziehen sie eine Pin auf high oder low?

Slein
28.10.2010, 21:59
Gott, ich bin echt nicht wach heute... sorry 8-[

Die Pullups mann, die Pullups:
PORTA |= (1<<PA1) | (1<<PA2);//PA1 und PA2 auf High setzen

Das Projekt für AVR Studio hab ich angehängt.
(für ATMega16, hast nicht geschrieben, welchen du benutzt)

Ezalo
29.10.2010, 13:31
Danke für die Hilfe ^^

Nun klappt es endlich, hab wohl dann schon angefangen etwas zu umständlich zu denken.

Hab gestern Abend noch das gefunden http://www.info-rlp.de/lernteams/at08/abschnitt_1_mikrocontroller_projekte/led_schalten_mit_speicherfunktion/quelltext_florian_b_.c.txt und hätte das heute mal probiert, nur halt mit 2 Tastern statts einem.

Was mir im Endefekt aber wohl nicht geholfen hätte.