Forum: Mikrocontroller und Digitale Elektronik Interrupt Zeiten - Rechenfehler gesucht..


von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Hi,

da ich gerade mit einem anderen Codeschnipsel nicht weiter komme, wollte 
ich Mal meine "Uhr" auf Genauigkeit überprüfen.
Es handelt sich dabei um einen PIC mit 8Mhz
1
else if (TMR0IE && TMR0IF)
2
    { //Timer0 ist nicht aktiv, wenn die MPU schläft.
3
        //8-bit - Timer --> 8000000/256 = 0,000032s bei 1:1
4
        //Aktueller Prescaler: 1:2 -->0,000064s -->Faktor 15625 ==1s
5
        //TMR0 Überlauf ISR
6
        //3125== 0,2s
7
        clock_64us++;
8
        if (clock_64us >= 3125)
9
        {
10
            clock_64us = 0;
11
            clock_200ms++;
12
            if (clock_200ms >= 5)
13
            {
14
                clock_200ms = 0;
15
                clock_1s++;
16
                LED_AN;
17
                if (clock_1s >= 60)
18
                {
19
                    clock_1s = 0;
20
                    clock_1min++;
21
                }
22
            }else
23
                LED_AUS;
24
        }
25
        TMR0IF = 0;
26
    }

Im Quellcode sind schon einige Berechnungen, doch ich glaube ich habe 
mich orgendwo verhauen, denn die LED sollte ja zwischen 2 AN-Zyklen 
ziemlich genau 1Sek haben. Optisch nehme ich jedoch den 5-fachen Wert 
war.

Hier meine Rechnung im Detail:
8000000Hz = 0,000000125 /Sek

Da es sich beim Timer0 um einen 8bittigen handelt, den ich auf den 
Prescaler 2 eingestellt habe folgere ich:
8000000/256/2 = 15625 Überläufe /Sek

Oder anders "zähle bis 15625" und 1 Sek ist um
Da der Wert so schön durch 5 teilbar ist unterteile ich es noch Mal in
"zähle bis 3125" und 200ms sind um.

info:
1
volatile uint16_t       clock_64us = 0;
2
volatile uint8_t        clock_200ms = 0;
3
volatile uint8_t        clock_1s = 0;
4
volatile uint8_t        clock_1min = 0;

Wo habe ich mir den dicken Fehler eingehandelt?

main() sowie alle anderen Interrupts habe ich zu testzwecken geleert, so 
dass ein Interrupt Verschlucken ausgeschlossen sein sollte. Watchdog 
etc. sind ebenfalls alle aus.

Laut datenblatt läuft der Timer0 mit Fosc. Sollte das ein Fehler sein 
und er läuft tatsächlich nur mit FOSC/4?


Grüße Oekel

von Falk B. (falk)


Lesenswert?

Poste VOLLSTÄNDIGEN Quellcode als Anhang.

von D a v i d K. (oekel) Benutzerseite


Angehängte Dateien:

Lesenswert?

Siehe Anhang.

set_pwm(0, 5, 0, 255); steht stellvertretend für die LED. Wollte jetzt 
nicht auch noch alle anderen Files posten.

Grüße Oekel

Nachtrag:
Die Zeile decode_DMX(); hatte ich natürlich zum Testen auskommentiert. 
(nicht dass jetzt Jemand behauptet diese Routine dauert zu lange usw.)

von Chris B. (dekatz)


Lesenswert?

D a v i d K. schrieb:
> Laut datenblatt läuft der Timer0 mit Fosc. Sollte das ein Fehler sein
>
> und er läuft tatsächlich nur mit FOSC/4?

TIMER0 MODULE, Datenblatt p.157, Block Diagramm 15.1 steht eindeutig 
FOSC/4

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Chris B. schrieb:
> TIMER0 MODULE, Datenblatt p.157, Block Diagramm 15.1 steht eindeutig
> FOSC/4

Danke!

Ich habe wirklich Zeile für Zeile von Kapitel 15.0 (Timer0) gelesen und 
diese Info nicht gesehen.
Dass ausschließlich das Schaubild 15.1 diese Info beinhaltet ist etwas 
blöd, werde den Bildchen in Zukunft mehr Achtung schenken.

Grüße Oekel

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.