Für die Einarbeitung in der Programmierung des AVR uC mit C habe ich mir die AVR GCC Tutorials angeschaut und auch einfache Programme nachgebildet. Nun wollte ich ein Programm schreiben der die elektrische Wechselschaltung nachbildet und stoße da auf erhebliche Schwierigkeiten. Im Grunde will ich folgendem Verhalten nachbilden: Taste gedrückt ---> LED An (und bleibt an) bis die Taste wieder gedrückt wird zum ausschalten. Bisher stehe vor dem Problem dass der folgende Code nur dazu führt dass die LED getoggelt wird (LED nur AN während Taste gedrückt wird): if(PINB & (1 << PINB0)){ PORTA |= (1 << PINB0); } else { PORTA &= ~(1 << PINB0); } Das Rausnehmen des else Abschnittes bringt leider keine Abhilfe. Beigefügt ist der Code dazu. Ich freue mich, wenn ich Hinweise erhalten kann wie ich dies lösen. Vielen Dank, Jenny
Hi Lies dir mal den Artikel durch: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten Außerdem solltest du beachten, das beim STK500 eine gedrückte Taste eine Null liefert und eine Led bei einer Null am Pin leuchtet. MfG Spess
Hi
1 | bool t=false; |
2 | if(taster) |
3 | {
|
4 | false= !false; |
5 | }
|
6 | if(t) |
7 | {
|
8 | ledon(); |
9 | }
|
10 | else
|
11 | {
|
12 | ledoff(); |
13 | }
|
natürlich must du die funktionen noch einsetzen, aber rein voon der Theoride... hoffe konnte helfen
N. G. schrieb: > false= !false; Du meinst wohl: t = !t; > aber rein voon der Theoride... Das reicht aber noch nicht. Man muss nach Toogeln von "t" noch warten, bis der Taster wieder losgelassen wird, bevor "t" wieder getoggelt werden darf. Und entprellen fehlt natürlich auch noch ;-( Gruß Dietrich
Danke für die Hilfe. Das Programm habe ich nun wie folgt auf der Basis des Codes zur Entrellung von Peter Dannegger geändert, weil ich gar keine Kenntnis von Assembler habe und daher lieber auf C programmieren würde: int main(void) { bool t=false; DDRB = 0x00; //PortB als Eingang PORTB = 0x01; //Pull-up Aktiv an PIN B0 DDRA = 0xff; //PortA als Ausgang for(;;){ if(debounce(PINB, PB0)) { t=true; } if(t){ PORTA |= (1<<PA0); } else { PORTA &= ~(1<<PA0); } _delay_ms(1000); } } Leider führt dies dazu, dass die LED nur noch dauernd AN ist und keine Reaktion auf Tastendrücke an PB0 zeigt. Was habe ich dabei falsch gemacht. Euere Unterstützung finde ich großartig und gerade für eine Neulinge gibt das eine zusätztliche Motivation.
Kann mir bitte jemand einen Hinweis geben? Der Code habe ich nochmals geändert aber leider ohne Erfolg. Die LED geht bei einem Tastendruck für einige Sekunden AN, erlischt aber danach. Ich wollte es aber so dass es bei einem Tastendruck AN bleibt solange bis der Taster wieder betätigt wird. ---------- int main(void) { bool t=false; DDRB = 0x00; //PortB als Eingang PORTB = 0x01; //Pull-up Aktiv an PIN B0 DDRA = 0x01; //PortA als Ausgang for(;;){ if(PINB & (1 << PINB0)){ t=true; } else { t=false; } if(t){ debounce(PINB, PB0); PORTA |= (1<<PA0); } else { PORTA &= ~(1<<PA0); } _delay_ms(1000); } } Danke, Jenny
Du musst noch eine Variable einfügen, ob die LED zuletzt ein oder aus geschaltet wurde, detektieren, ob die Taste losgelassen wurde und zwei seperate Abfragen benutzen....
Das mit der 2.ten Variable verstehe ich noch nicht ganz. Ich dachte die Variable t im Programm würde es sein. Kannst Du es mir bitte genauer erklären?
Deine Tastenabfrage ist zur Zeit doppelt - das bringt dich aber nicht weiter. Es müssten 2 separate if-Abfragen verwendet werden: 1. Ein: Taste UND !Letzte_Taste UND !Taste_betaetigt 2. Aus: Taste UND Letzte_Taste UND ! Taste_betaetigt
Der Code habe ich nun wie folgt geändert: int main(void) { bool t=false; DDRB = 0x00; //PortB als Eingang PORTB = 0x01; //Pull-up Aktiv an PIN B0 DDRA = 0x01; //PortA als Ausgang for(;;){ /* Ein */ if(PINB & (1 << PINB0)){ if(t==false & ~(1 << PINB0)){ debounce(PINB, PB0); PORTA |= (1<<PA0); } t=true; } if(PINB & (1 << PINB0)){ if(t==true & ~(1 << PINB0)){ debounce(PINB, PB0); PORTA &= ~(1<<PA0); } t=false; } } } Die 2 If-Abfragen sind verschachtelt. Leider ist die LED mit dem Code auch nur dauernd AN.
1. Die Abfragen dürfen nicht verschachtelt sein. 2. Du fragst bei "ein" ab, dass die letzte Aktion "aus" war. 3. Du setzt eine Variable, dass eine Aktion erfolgte. 4. Du speicherst, die Aktion (1=ein, 0=aus). 4. Diese fragst du ebenfalls unter 2 auf FALSE ab. 5. Erst wenn die Entprellroutine "Taste nicht betätigt" liefert, setzt du diese zurück.
Noch ein Update des Codes: int main(void) { bool t=false; bool f; DDRB = 0x00; //PortB als Eingang PORTB = 0x01; //Pull-up Aktiv an PIN B0 DDRA = 0x01; //PortA als Ausgang for(;;){ /* 2. Ein t-->"aus" */ if(PINB & (1 << PINB0) & ~t & ~f){ // 2. Schritt f=true; // 3.+4. Schritt if(~debounce(PINB, PB0)){ // 5. Schritt PORTA |= (1<<PA0); } else{ PORTA &= ~(1<<PA0); } } else { f=false; // 3.+4. Schritt } } } Ich habe mich an dem Hinweis von Otto gerichtet aber offensichtlich noch ein Fehler drin, weil es immer noch nicht klappt. Danke für Hinweise, Jenny
Jenny K schrieb: > keine > Reaktion auf Tastendrücke an PB0 zeigt. Weil Du mit > _delay_ms(1000); die ganze Entprellung zunichte machst. Riesige Delays sind Schweinereien, die in keinem Programm was verloren haben. Es wird zwar oft kolportiert, daß sie Anfängern das Programmieren erleichtern sollen, aber das genaue Gegenteil ist der Fall. Die weiteren Versuche werden ja immer abstruser. Debounce liefert genau einmal True bei jedem Drücken. Einfach:
1 | for(;;){ |
2 | if(debounce(PINB, PB0)) |
3 | PORTA ^= (1<<PA0); |
4 | }
|
Habe nun versucht das Programm soweit zu erweitern, dass die LED an PA2 angeht, wenn sowohl PB0 als auch PB1 nacheinander betätigt wurden. Dazu verwende ich zwei Variablen t und f in denen ich den logischen Zustand zwischenspeichere. Leider funktioniert dies nicht. Was mache ich dabei falsch oder worauf muss ich generell bei der Zwischenspeicherung in einer temporären Variable achten? int main(void) { bool t=false; bool f=false; DDRB = 0x00; //PortB als Eingang PORTB = 0xff; //Pull-up Aktiv an PIN B0 DDRA = 0xff; //PortA als Ausgang PINA &= 0x00; for(;;){ if(debounce(PINB, PB0)){ t=true; PORTA ^= (t <<PA0);//Toggle entsprechend PA0 läuft wie erwartet } else{ t=false; } if(debounce(PINB, PB1)){ f=true; PORTA ^= (f <<PA1); //läuft wie erwartet } else{ f=false; } if(t&f){ //Bedingung wird nicht über die LED an PA2 nachgebildet PORTA |= (1 <<PA2); } else { PORTA &= ~(1 <<PA2); } } } Danke für die Unterstützung. Jenny
Jenny K schrieb: > if(t&f){ //Bedingung wird nicht über die LED an PA2 nachgebildet Willst du wirklich t und f verknüpfen oder abfragen t&&f ?
1 | if(debounce(PINB, PB0)){ |
2 | t=true; |
3 | }
|
4 | if(debounce(PINB, PB1)){ |
5 | if(t){ |
6 | t=false; |
7 | PORTA ^= (1 <<PA2); |
8 | }
|
9 | }
|
Nochmal, debounce() liefert jedes Ereignis genau einmal. Die ganzen else sind daher Unsinn, sie würden ständig durchlaufen.
Heißt es dann dass die debounce() Funktion nicht für Mehrtastenabfragen verwendet werden kann?
Jenny K schrieb: > Heißt es dann dass die debounce() Funktion nicht für Mehrtastenabfragen > verwendet werden kann? Was ist eine 'Mehrtastenabfrage'? Wenn du das meinst, was ich denke das du meinst, dann sieh dir halt mal das letzte Beispiel von PeDa GENAU an. Was denkst du, warum da einmal PB0 und das andere mal PB1 als Argument zum debounce steht? Du musst schon die Dinge GENAU studieren, die du fertig vorgesetzt bekommst!
der Hintergrund ist das ich für ein Praktikum eine Art Zustandautomaten programmieren soll der abhängig von der gerade gedrückten Tasten bestimmte Ausgänge (LED, Relais) an/aus machen soll. Da die Aufgabe für mich komplex erscheint, habe ich überlegt erst mit einfachen/grundsätzlichen Fragestellungen (Zustandszuweisung in Hardware, boolsche Verknüpfung in HW,...) anzufangen. Mit Mehrtastenabfrage meine ich: Taster 1 wird betätigt --> debounce() wird aufgerufen und der ON (betätigt) Zustand in einer boolschen Variable x (TRUE) gespeichert. Falls der Taster 2 danach auch betätigt wird wird die debounce() Funktion erneut aufgerufen und eine Variable y (TRUE) speichert ebenfalls den Zustand.Erst abhängig von der Abfrage, ob x und y beide TRUE sind wird der entsprechende Ausgang PIN aktiviert/deaktiviert. In der C-Programmierung wie wir es in der Vorlesung machen geht das ganze etwas einfacher. Die prinzipielle Funktion in C wobei die Taster und LED als boolsche Variablen deklariert sind läuft auch. Ich finde eure Unterstützung wirklich klasse und Danke dafür. Jenny
Jenny K schrieb: > Mit Mehrtastenabfrage meine ich: > > Taster 1 wird betätigt --> debounce() wird aufgerufen und der ON > (betätigt) Zustand in einer boolschen Variable x (TRUE) gespeichert. > Falls der Taster 2 danach auch betätigt wird wird die debounce() > Funktion erneut aufgerufen und eine Variable y (TRUE) speichert Du missverstehst das irgendwie. Grundsätzlich muss dein Programm in einer Art Dauerschleife laufen. Innerhalb dieser Dauerschleife wird debounce FÜR EINEN BESTIMMTEN PIN aufgerufen. Dieser debounce Aufruf teilt dir mit, ob die Taste in der Zeit seit dem letzten Aufruf für diese Taste niedergedrückt wurde oder nicht. Allerdings überwacht debounce die Taste nicht ständig. Die Grundannahme ist, dass bei zb 1000 Aufrufen von debounce in 1 Sekunde keinen Menschen finden wird, der es schafft eine Taste kurz genug zu drücken, dass dies bei diesen 1000 Aufrufen pro Sekunde unentdeckt bleibt. debounce vergleicht einfach den jetzigen Tastenzustand mit dem Tastenzustand vom letzten Aufruf und wenn der unterschiedlich ist, dann meldet es einen Tastendruck. Unterscheiden sich die beiden nicht, dann meldet es keinen Tastendruck. Aber debounce wartet nicht darauf, dass der Benutzer eine Taste drückt.
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.