Hey Guys, ich hab ein Problem mit der ISR while(marker) { CODE PINX ((PINX & (Taster))==0) marker = 0; Goto(1); } ISR {marker = 1;} Nun möchte ich das ich mit dem selben Taster mit dem ich den Interrupt betätige wieder raus kommen aus der while Schleife. Wie ist dies möglich ?
Ist das so etwas wie virtueller Code? Welcher Comtroller - Compiler etc. wird verwendet ? Besser ist es ein richtiges um komplettes Programm mit der Fragestellung zu posten.
AVR 328 Atmel Studio
1 | while(menuMark) |
2 | {
|
3 | lcd_clear(); |
4 | WeckerMenu(); |
5 | if (WeckerH == 24) WeckerH = 0; |
6 | if (WeckerM == 60) WeckerM = 0; |
7 | zeit(150); |
8 | if ((PINC & (1<<ChooseVariable))==0) vari++; |
9 | zeit(150); |
10 | if (vari==0) |
11 | {
|
12 | if ((PINC & (1<<ZeitverstellenPLUS))==0) WeckerH++; |
13 | if ((PINC & (1<<ZeitverstellenMINUS))==0) WeckerH--; |
14 | }
|
15 | else
|
16 | zeit(150); |
17 | {
|
18 | if ((PINC & (1<<ZeitverstellenPLUS))==0) WeckerM++; |
19 | if ((PINC & (1<<ZeitverstellenMINUS))==0) WeckerM--; |
20 | }
|
21 | zeit(150); |
22 | if (vari==2) vari=0; |
23 | zeit(150); |
24 | if ((PINC & (1<<Menu_Taster))==0) {menuMarker = 0; goto(1);} |
25 | }
|
26 | |
27 | ISR(PCINT1_vect) // Interrupt Service Routine |
28 | {
|
29 | menuMark = 1; |
30 | }
|
Rest funktioniert des Progamms
ich denke es wird zeit das Programm komplett zu sehen, in einer ISR zu warten ist eine ganz schlechte Idee. Auch das
1 | goto(1); |
finde ich sehr bedenktlich, hast du eine Funktion mit dem namen goto?
was heißt goto eigentlich gotocase(1)... Warte routinen sind zum einlesen der Taster das nicht mit einem Tastendruck 30 mal nach oben gezählt wird. Rest des Programmes ist relativ irrelevant weil dies nichts mit dem Problem zu tun hat
Geht ledglich um eine Möglichkeit den Interrupt mit dem selben Taster wieder auszuschalten
Hallo, Bei mir meckert der gcc an den Stellen, wo wir die Funktiondeklaraion und Variablen nicht kennen. Was soll da genau passieren, in deinen Augen ?
Üblicherweise merkst du dir dazu in einem Flag, ob du gerade drin oder draußen bist. Bei dem gezeigten Code ist allerdings "üblicherweise" eventuell nicht der passende Ansatz. Die Meinung deines Compilers zu goto(1) würd mich allerdings schon interessieren. Oliver
Ernst schrieb: > while(menuMark) ^^ > if ((PINC & (1<<Menu_Taster))==0) {menuMarker = 0; goto(1);} ^^ Ist das auch so programmiert oder ist das hier nur ein Schreibfehler? Gruß Dietrich
int Phase_; int vari = 0; int menuMark = 0; int clockMark = 0; #define Menu_Taster PC0 #define ZeitverstellenPLUS PC1 #define ZeitverstellenMINUS PC2 #define ChooseVariable PC3 #define TurnClockoff PC4 #define Menu_Uhr PB5 Er sollte eigentlich aus dem Menü raus gehen, aber anstatt geht er nur raus wenn der Taster gedrückt wird, sprich die ISR setzt die variable dauerhaft 1 per Tastendruck und die 0 aus dem case wird ignoriert.
Dietrich L. schrieb: > Ernst schrieb: > >> while(menuMark) > ^^ > >> if ((PINC & (1<<Menu_Taster))==0) {menuMarker = 0; goto(1);} > ^^ > Ist das auch so programmiert oder ist das hier nur ein Schreibfehler? > > Gruß Dietrich Hab mehrfach rum probiert deshalb war der Code bisschen anderes und menuMarker wurde manuell eingefügt aber im Ursprung war es gleich
Peter II schrieb: > Ernst schrieb: >> die 0 aus dem case wird ignoriert. > > welchem case? Ich code steht kein case. Ist alles im switch programmiert. Im case war damit gemeint in dem oberen Programmteil.. Wie gesagt der rest ist irrelevant...
Dietrich L. schrieb: > Wie ist "menuMark" deklariert? Dazu fehlt noch Deine Antwort. > Hinweis: Du brachst "volatile". Gruß Dietrich
Dietrich L. schrieb: > Dietrich L. schrieb: >> Wie ist "menuMark" deklariert? > > Dazu fehlt noch Deine Antwort. > >> Hinweis: Du brachst "volatile". > > Gruß Dietrich Zum zweiten Mal int menuMark = 0; Wofür genau volatile?
Ernst schrieb: > Ist alles im switch programmiert. > Im case war damit gemeint in dem oberen Programmteil.. So wird das nichts. Du musst den kompletten und aktuellen Code zeigen, der den Fehler hat. > Wie gesagt der rest ist irrelevant... Bei Fehlersuche darf man nie davon ausgehen, man muss an allem zweifeln. Ernst schrieb: > Zum zweiten Mal Das habe ich übersehen :-( > int menuMark = 0; > > Wofür genau volatile? Damit die Variable innerhalb und außerhalb der ISR gültig ist. Gruß Dietrich
Ernst schrieb: > Wofür genau volatile? Hier noch mehr dazu: https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Datenaustausch_mit_Interrupt-Routinen
Ernst schrieb: > Hier der komplette Code in der C Datei > > http://www.file-upload.net/download-11315566/Clock.c.html Man das lieber als Dateianhang hier im Forum. Das ist für die Leser einfacher und sicherer.
Naja wie auch immer die Frage ist ja, wie ich den Taster für beides benutzen beenden und starten des Interrupts während der while Schleife
Ernst schrieb: > Naja wie auch immer die Frage ist ja, wie ich den Taster für beides > benutzen beenden und starten des Interrupts während der while Schleife Taster löst Interrupt aus. Interrupt toggelt einen Flag - nicht mehr und nicht weniger. In main() wird der Flag geprüft und das ist auch alles. Flag als volatile deklarieren.
Hallo Betreuer, bitte erklärt Ernst wie er mit ISR(PCINT1_vect) - level interrupt umgehen muss. Ich will mich nun nicht weiter einmischen.
So wird das nichts. Statt den Taster an einen Interrupt-Pin zu hängen, verwendest Du besser einen Timer-Interrupt, der alle paar ms ALLE Taster abfragt, das Entprellen übernimmt und die Tastendrücke entweder in einer volatile Variable oder besser noch in einem Fifo an main() weitergibt.
1 | char myKey = getKey(); // read key from fifo |
2 | |
3 | switch(myKey) |
4 | {
|
5 | case keyEnterMenuPressed: |
6 | menuMarker = 1; |
7 | ... / do your stuff to enter menu |
8 | break; |
9 | |
10 | case keyEnterMenuReleased: |
11 | menuMarker = 0; |
12 | ... // do your stuff to exit menu |
13 | break; |
14 | |
15 | case keyChooseVariablePressed: |
16 | if (menuMarker == 1) |
17 | {
|
18 | ....
|
19 | }
|
20 | break; |
21 | |
22 | case keyzeitVerstellenPressed: |
23 | if (menuMarker == 1) |
24 | {
|
25 | ....
|
26 | }
|
27 | break; |
28 | }
|
Mit einer Timer-ISR kannst Du bei Bedarf nicht nur keyPressed sondern auch keyReleased Signale auswerten und an main() weiterleiten. Vorteile: * Du wertest Deine Tasten an EINER Stelle aus und nicht verstreut im Programm. Das erleichtert das Testen (was ist das?). * Alle Tasten werden entprellt. * Wenn main() mal ein paar ms beschäftigt ist (Graphik-Ausgabe, etc.), kann trotzdem kein tastendruck verlorengehen. * ... Wie man Tasten im Timer-ISR entprellt, findest Du hier an mehreren Stellen. Gruß, Stefan
Dann nimm es so:
1 | case keyEnterMenuPressed: |
2 | if (menuMarker == 0) |
3 | {
|
4 | menuMarker = 1; |
5 | ... / do your stuff to enter menu |
6 | }
|
7 | else
|
8 | {
|
9 | menuMarker = 0; |
10 | ... // do your stuff to exit menu |
11 | }
|
12 | break; |
Was ich oben zeigen wollte: * Entprellen ist essentiell. * Klare Verteilung: ISR konvertiert Pin-Signale zu Tastenkommandos und main()steuert mit den Tastenkommandos das Menu, etc. * Je nach Aufwand in der Timer-ISR lassen sich unterschiedliche Tastenkommandos generieren: pressed, released, longPressed... main() kann diese auswerten, muss das aber nicht.
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.