Forum: Compiler & IDEs ISR zum Auslesen eines Drehencoders macht Probleme


von Michael D. (etzen_michi)


Angehängte Dateien:

Lesenswert?

Nabend.

Ich habe nun seit einer Woche das Problem das ich mit meine ISR nicht 
zurecht komme.

Die ISR wird regelmäßig durch einen TimerOverflow aufgerufen und fragt 
den Status des an PINC 1 und 2 hängenden Drehencoders ab.

1. Wenn ich die "if" Schleife wechlasse wo geprüft wird ob sich was 
geändert hat:

Irgendwie habe ich das Problem das wenn PINC1 High ist er dauerhaft am 
zähen ist.
Sobald PINC1 Low ist steht er ruhig.

Hat man einen Übergang von 10 nach 00 zählt er -1 (Bit 3-5 in Polling).
Hat man einen Übergang von 00 nach 10 zählt er nichts.

2. Wenn ich die "if" Schleife drin habe:

Hat man beim Übergang von 00 auf 01, von 01 auf 00, 00 auf 10 sowie von 
01 auf 11 keinen Zählvorgang.



Die ISR läuft so ab das er den aktuellen Zustand einließt, diesen mit 
den letzten vergleicht (Bit 1+2 in Polling) und dann einen SwitchCase 
durchführt wonach er überprüft ob hoch, runter gezählt wurde oder ggf. 
ein Schritt übersprungen wurde.
1
ISR(TIMER0_OVF_vect) {
2
3
//#####################################################################################################################
4
5
     // Debug
6
7
//     if(i>=1) { while(1) { }; }
8
//     i++;
9
10
//#####################################################################################################################
11
12
     int volatile temp=PINC;  // Aktuelle Pin Zustände einlesen
13
14
//#####################################################################################################################
15
16
     // Nachschauen ob Taster betätigt, wenn ja hochzählen zur Entprellung 
17
     // und wenn länger gedrückt CountMenue erhöhen (Bestätigung des Ausgewählten Menues)
18
     /*if(temp&0x01) {
19
          if(Polling&0x80) {
20
               Polling&=0x3F;
21
               CountMenue++;
22
               } else {
23
               Polling+=0x40;
24
          }
25
          } else {
26
          Polling&=0x3F;
27
     }
28
*/
29
//#####################################################################################################################
30
31
     // Nachschauen ob Drehencoder gedreht wurde und Reagieren
32
     if((Polling&0x06)!=(temp&0x06)) {
33
          switch(Polling&0x06) {
34
35
               // Stellung 00 kann zu 10 oder 01 gehen
36
               case 0x00:
37
                    switch(temp&0x06) {
38
39
                         case 0x04:
40
                              Polling-=0x08;
41
                              Polling&=0xF9;
42
                              Polling|=(temp&0x06);
43
                              break;
44
45
                         case 0x02:
46
                              Polling+=0x08;
47
                              Polling&=0xF9;
48
                              Polling|=(temp&0x06);
49
                              break;
50
51
                         case 0x00:
52
                              break;
53
54
                         // Wird im Fehlerfall erreicht (Ungültige Sprünge)
55
                         default:
56
                              Polling&=0xF9;
57
                              Polling|=(temp&0x06);
58
                              break;
59
60
                    }
61
62
               // Stellung 01 kann zu 00 oder 11 gehen
63
               case 0x02:
64
                    switch(temp&0x06) {
65
66
                         case 0x00:
67
                              Polling-=0x08;
68
                              Polling&=0xF9;
69
                              Polling|=(temp&0x06);
70
                              break;
71
72
                         case 0x06:
73
                              Polling+=0x08;
74
                              Polling&=0xF9;
75
                              Polling|=(temp&0x06);
76
                              break;
77
78
                         case 0x02:
79
                              break;
80
81
                         // Wird im Fehlerfall erreicht (Ungültige Sprünge)
82
                         default:
83
                              Polling&=0xF9;
84
                              Polling|=(temp&0x06);
85
                              break;
86
87
                    }
88
89
               // Stellung 11 kann zu 01 oder 10 gehen
90
               case 0x06:
91
                    switch(temp&0x06) {
92
93
                         case 0x02:
94
                              Polling-=0x08;
95
                              Polling&=0xF9;
96
                              Polling|=(temp&0x06);
97
                              break;
98
99
                         case 0x04:
100
                              Polling+=0x08;
101
                              Polling&=0xF9;
102
                              Polling|=(temp&0x06);
103
                              break;
104
105
                         case 0x06:
106
                              break;
107
108
                         // Wird im Fehlerfall erreicht (Ungültige Sprünge)
109
                         default:
110
                              Polling&=0xF9;
111
                              Polling|=(temp&0x06);
112
                              break;
113
114
                    }
115
116
               // Stellung 10 kann zu 11 oder 00 gehen
117
               case 0x04:
118
                    switch(temp&0x06) {
119
120
                         case 0x06:
121
                              Polling-=0x08;
122
                              Polling&=0xF9;
123
                              Polling|=(temp&0x06);
124
                              break;
125
126
                         case 0x00:
127
                              Polling+=0x08;
128
                              Polling&=0xF9;
129
                              Polling|=(temp&0x06);
130
                              break;
131
132
                         case 0x04:
133
                              break;
134
135
                         // Wird im Fehlerfall erreicht (Ungültige Sprünge)
136
                         default:
137
                              Polling&=0xF9;
138
                              Polling|=(temp&0x06);
139
                              break;
140
141
                    }
142
          
143
               // Nie erreichbar
144
               default:
145
                    Polling&=0xF9;
146
                    Polling|=(temp&0x06);
147
                    break;
148
149
          }
150
     }
151
152
//#####################################################################################################################
153
       
154
}

Gesamtes Hauptprogramm im Anhang

Irgendwie bin ich inzwischen ein wenig überfordert.

Ich möchte keine fertige Libary nutzen (währe ja langweilig).
Nachdem dieses Problem gelöst ist nehme ich gerne jegliche weitere 
Kritik entgegen welche mir helfen kann.


Vielen Dank

von Peter D. (peda)


Lesenswert?

Michael D. schrieb:
> Ich möchte keine fertige Libary nutzen (währe ja langweilig).

Bloß nicht, die könnte ja funktionieren.
Ich kenne sogar eine.
Der Reiz, sich dann durch einen nicht funktionierenden Code 
durchzuwuseln ist allerdings so zwischen null bis garnicht.


Peter

von Michael D. (etzen_michi)


Lesenswert?

Habe grad mal in der oben stehenden ISR im Punkt welcher nie erreicht 
werden sollte/könnte einen kleinen DebugText reingeschrieben, und genau 
dieser wird bei jedem Step angezeigt??

Ich lese die Eingänge ins Register temp.

Dann mache ich "temp&=0x06".

als nächstes kommt ein SwitchCase welcher 0x00, 0x02,0x04 und 0x06 
abfragt.
Aber irgenwie wird der Text aus default angezeigt, was ich mir irgendwie 
nicht erklären kann.

Weiß jemand warum?
Habe bereits mehrere Optimierungen ausprobiert.

Edit: In temp steht in dieser Situation 0x04.

von Konrad S. (maybee)


Lesenswert?

Peter Danneggers Anmerkung kann ich nur zustimmen.

Das volatile für die temp-Variable ist Unsinn, führt aber zu keinem 
Problem.

> if((Polling&0x06)!=(temp&0x06)) {
>           switch(Polling&0x06) {
>
>                // Stellung 00 kann zu 10 oder 01 gehen
>                case 0x00:
>                     switch(temp&0x06) {

Was spricht denn dagegen, dass (temp&0x06) den Wert 0x06 hat?

von Stefan E. (sternst)


Lesenswert?

Michael D. schrieb:
> Aber irgenwie wird der Text aus default angezeigt, was ich mir irgendwie
> nicht erklären kann.

Weil alle Cases "durchfallen". Die Breaks beziehen sich ja auf die 
inneren Switches.

von Michael D. (etzen_michi)


Lesenswert?

Habe den Fehler gefunden.

Ich habe eine SwitchCase wo ich die 4 möglichen Werte durchgehe 
(temp&0x06) kann in einer 8bit Variablen ja nur 4 Werte haben.

In den einzelnen Werten habe ich dann die einzelnen Möglichkeiten 
durchgekaut.

Diese habe ich jeweils mit einem break; beendet, und bin dann in den 
nächsten Case gegangen ohne den vorherigen zu schließen.

temp habe ich im laufe des Debug`s volatile gemacht um einfach alles 
ausschließen zu können.

Vielen Dank für eure Hilfe, vorallem Stefan

Bezgl. des "Was spricht dagegen das temp&0x06 den Wert 0x06 hat" ging es 
darum das er die 0x06 in einem Case hätte abarbeiten müssen ohne später 
nochmal das default ab zu arbeiten, was an meinen fehlenden breaks lag.

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
Noch kein Account? Hier anmelden.