Hallo leute, ich bräuchte mal eure Hilfe zu folgendem Problem, ich komme da gedanklich gerade nicht weiter: Ich habe in meinem uC ein Programm mit zwei Funktionen, zwischen diesen möchte ich gerne mit einem Taster umschalten. Das Umschallten an sich stellt kein Problem dar, eine kleine debounce-routine für den Taster habe ich in einem Timer-Interrupt realisiert, der alle 13,6ms aufgerufen wird: ISR(TIM0_OVF_vect) { // Wenn Taster nach 13ms weiterhin gedrückt, dann Flag für gedrückten // Taster setzen ("Taster ist gedrückt if(!(PINB & (1<<PINB2)) && (taster_flag == 1)) { taster_gedr = 1; } else { taster_gedr = 0; taster_flag = 0; } // Wenn Taster gedrückt, dann flag setzen if(!(PINB & (1<<PINB2))) { taster_flag = 1; } } In der Main-Schleife möchte ich nun mit dem Flag "taster_gedr" zwischen den Programmen umschalten. Das Problem stellt sich insofern dar, die beiden Programme während der gedrückten Taste gegeneinander abzuriegeln, d.h. bei meiner Lösung schalten sich die Programme ständig um solange die Taste gedrückt ist. Es ist also ein Glücksspiel, wie bei einer nicht Entprellten Taste, das andere Programm zu erwischen. Hier mal der Teil zum Umschalten im Hauptprogramm: if((taster_gedr == 1) && (prognr == 1)) { prognr = 2; taster_gedr = 0; } else if((taster_gedr ==1) && (prognr == 2)) { prognr = 1; taster_gedr = 0; } Die Lösung ist ziemlich trivial, das weiss ich selber, nur komme ich grad nicht auf eine solche. Es würde eigentlich reichen, eine Flag im Hauptprogramm zu setzen, die es ausschließen würde, dass in der ISR die taster_gedr Flag wieder auf 1 gesetzt wird, solange der Taster gedrückt ist. Wäre über Hilfe sehr dankbar! Falls der komplette Code nötig ist, bitte bescheid geben!
Lars M. schrieb: > d.h. bei meiner Lösung schalten sich die Programme ständig um solange > die Taste gedrückt ist. Du brauchst eine Flankenerkennung: merke dir in der Hauptschleife den Zustand des Tasters. Wenn der eingelesene Zustand (so einen Taster musst du übrigens nicht in einem Interrupt einlesen, das ist sogar eine ganz schlecht Idee) ungleich dem "alten" Zustand ist, dann hattest du eine Betätigungsflanke. Un dauf die hin schaltest du deine "Programmvariable" um:
1 | int altetaste = 0; |
2 | int programm = 0; |
3 | |
4 | {
|
5 | // hauptschleife ...
|
6 | if (taste!=altetaste) { // Flanke erkannt? |
7 | if (taste) { // steigende Flanke? |
8 | programm++; // unterstes Bit toggeln |
9 | }
|
10 | altetaste=taste; // für nächsten Zyklus merken |
11 | }
|
12 | |
13 | |
14 | if (programm&0x01) { // Programmnummer ungerade? |
15 | // "Programm 1"
|
16 | }
|
17 | else { // Programmnummer gerade |
18 | // "Programm 2"
|
19 | }
|
20 | }
|
:
Bearbeitet durch Moderator
Danke für deinenn Tipp, ich habe es jetzt so gelöst (5min. vor der Kaffemaschine haben geholfen ;-))
1 | if(!(PINB & (1<<PINB2)) && (taster_gedr == 1) && (sperr == 0)) |
2 | {
|
3 | PORTB ^= (1<<PB3); |
4 | taster_gedr = 0; |
5 | tast_timeout++; |
6 | sperr = 1; |
7 | }
|
8 | else if((PINB & (1<<PINB2)) && (sperr == 1)) |
9 | {
|
10 | sperr = 0; |
11 | }
|
Das ist jetzt testweise um eine LED ein und auszuschalten, aber sollte auch für andere Programme funktionieren. Eine frage zum Entprellen: Warum nicht in einem Timer-Interrupt? Bei der Methode vom Peter Dannegger ist die Entprellung doch auch in eine ISR ausgelagert, die Pin-Status Abfrage an sich ist in den Funktionen im Hauptprogramm. (Habe das prozedere mit dem Register-Auslesen ct0,ct1,i jetzt auch zu 90% verstanden). Leigt es an den Registerzugriffen? Diese kann man ja zuerst in temporäre Variablen innerhalb der ISR kopieren und dann wieder zurückschreiben. Habe gelesen, das soll weniger Zeitintensiv sein. Oder liegt es an etwas anderem? Noch eine Frage: Wie hast du den Quellcode farblich so hinbekommen? welche Klammern und befehle muss ich dafür setzen? Edit: Ok habs gefunden :)
:
Bearbeitet durch User
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.