Forum: Mikrocontroller und Digitale Elektronik Unregelmaessige Ausfuehrung von Interrupts


von Andreas F. (fornax)


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.
von Michael (Gast)


Lesenswert?

Der Aufruf von show_globe hat auch nichts in der ISR zu suchen. Setze 
dort nur ein Flag und mach den Bildaufbau in der Hauptschleife.
von Andreas F. (fornax)


Lesenswert?

Naja, in der Hauptschleife werde ich das Timing kaum praezise genug 
hinbekommen ohne den Flag in jeder Funktion staendig abzufragen (25Hz; 
80 Pixel; <= 5% Abweichung => T<25us), deshalb habe ich die inline da 
rein gepackt.
von Julian R. (tuefftler)


Lesenswert?

Wenn es so zeitkritisch ist, dann solltest du auf ASM umsteigen, oder 
zumindest Teile in ASM schreiben.

julian
von Andreas F. (fornax)


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.
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.