Unregelmaessige Ausfuehrung von Interrupts

OP #2379503
Lesenswert?

Abend,
bei meinem derzeitigen Projekt tritt ein unschoener Effekt auf,
den ich mir gerade auch nach langem Suchen und Testen nicht erklaeren 
kann.

Zunaechst mal worum es geht:
Ein POV-Globus mit 80 Pixeln auf der Breite, der einen Fotodetektor fuer 
den Nullpunkt (an INT1) hat und sich auch automatisch an die Drehzahl 
anpasst. Controller ist ein Mega644.

Funktioniert soweit auch ganz gut, d.h. der Nullpunkt steht absolut 
stabil, am Ende sieht man sehr kleine Schwankungen durch die 
Nachregelung.

Die Nachregelung funktioniert ueber einen Index, der 3x so schnell wie 
die "breite-Pixel" laeuft und im Nullpunkt abgefragt wird:
1
ISR(TIMER1_OVF_vect)
2
{
3
        TCNT1 = refresh_rate;
4
        uint8_t nonvol_spindex = speed_index;
5
        if (nonvol_spindex <= 237){
6
                if(nonvol_spindex%3 == 0){
7
                        show_globe(nonvol_spindex/3);
8
                }
9
                speed_index++;
10
        } else if (nonvol_spindex < 254){
11
                speed_index++;
12
        }
13
}
14

15
ISR(INT1_vect)
16
{
17
        uint8_t index_temp = speed_index;
18
        uint16_t refresh_temp = refresh_rate;
19
        TIMSK1 &= ~(1 << TOIE1);
20
        TIFR1 |= (1 << TOV1);
21

22
        if(index_temp <= 238 && refresh_temp <= 65000){
23
                if (index_temp < 200){
24
                        refresh_temp += 200;
25

26
                } else {
27
                        refresh_temp += 2*(239-index_temp);
28
                }
29
        } else if (index_temp >= 240 && refresh_temp > 200){
30
                if (index_temp > 254){
31
                        refresh_temp -= 200;
32
                } else {
33
                        refresh_temp -= 2*(index_temp-239);
34
                }
35
        }
36
        refresh_rate = refresh_temp;
37
        TCNT1 = refresh_temp;
38
        speed_index = 0;
39
        TIMSK1 |= (1 << TOIE1);
40
}
show_globe(index) schiebt den aktuellen "Laengengrad" auf die 
Ausgaberegister.

Meine Denkweise ist dabei, dass der speed_index idealerweise 239 sein 
sollte (237/3 = 79, letzter Laengengrad), wenn der Detektor ausloest, 
damit danach noch genau wieder ein Zyklus von TIMER1_OVF_vect bis zum 
Index 0 vergeht (+ den Fehler durch Bearbeitungszeit von INT1).

Wie gesagt, funktioniert alles ganz gut, nur leider tritt in 
unregelmaessigen Abstaenden der Effekt auf, das das komplette Bild ca. 1 
Pixel fuer vermutlich eine Umdrehung (ganz genau ist es nicht
zu erkennen) zu frueh angezeigt wird.
Anders gesagt ein kurzes Rueckeln entgegen der Wiedergaberichtung, als
wenn der Nullpunkt kurzzeitig vorher liegen wuerde.

Meine Vermutung ist, dass sich die ISRs in die Quere kommen, das 
Datenblatt finde ich in der Richtung ziemlich duerftig gehalten.

Vielen Dank fuer alle Ideen und Hinweise.
OP #2379614
Lesenswert?

Wenn ich noch weitere timingkritische Teile haette klar, aber mehr muss 
der Controller hier nicht koennen und ich halte mir noch eine gewisse 
Flexibilitaet vor.
Wie auch immer: solange die Abfolge der ISRs (auch im Ueberlappungsfall) 
so ist wie im Datenblatt beschrieben sollte imho kein Problem auftreten, 
auch wenn der Stil vielleicht fragwuerdig ist.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren