Forum: Mikrocontroller und Digitale Elektronik pic 18f25k20 - timer0 reload


von hannes (Gast)


Lesenswert?

hallo.

ich hab ein problem mit dem timer0 interrupt - der reload scheint nicht 
richtig zu funktionieren.

folgende voraussetzungen:
externer quarz mit 8MHz, config auf "HSPLL" - die pll ist somit 
aktiviert.
die interne frequenz beträgt somit 8MHz.
compiler = microchip mcc18

der timer0 wird folgendermaßen initialisiert:
   T0CONbits.T08BIT = 0;            // timer is used in 16bit mode
   T0CONbits.T0CS = 0;              // clock source is internal cpu 
frequency
   T0CONbits.T0SE = 0;              // low to high edge
   T0CONbits.PSA = 1;               // don't use the prescaler
   T0CONbits.T0PS2 = 0;             // prescaler value = 2 (not used)
   T0CONbits.T0PS1 = 0;
   T0CONbits.T0PS0 = 0;
   TMR0H = 0xFD;                    // set the interrupt period
   TMR0L = 0xC0;
   INTCONbits.TMR0IF = 0;           // clear the timer 0 Interrupt
   INTCONbits.TMR0IE = 1;           // enable timer0 interrupt
   T0CONbits.TMR0ON = 1;            // enable timer 0


in der ISR wird der timer0 folgendermaßen behandelt:

   if( INTCONbits.TMR0IF && INTCONbits.TMR0IE )
   {
      TMR0H = T0VALUE_H;
      TMR0L = T0VALUE_L;
      INTCONbits.TMR0IF = 0;
   }

d.h. das H byte wird vor dem L byte gesetzt. dann wird das IF flag 
zurückgesetzt.

das problem ist jetzt: der timer läuft etwas langsamer als gewollt.
soll = interrupt alle 104us
ist = interrupt alle 134us

bei der simulation in MPLAB ist mir aufgefallen, dass TMR0H nicht 
beschrieben wird (überprüft durch nachheriges auslesen von TMR0L und 
TMR0H).

danke für eure hilfe!
hannes

von Dario B. (abcd)


Lesenswert?

dann hast du also ein 32mhz quarz angeschlossen?

von Chris (Gast)


Lesenswert?

Du machst eine

hannes schrieb:
> das problem ist jetzt: der timer läuft etwas langsamer als gewollt.
> soll = interrupt alle 104us
> ist = interrupt alle 134us


Differenz = 30 uS oder 120 Befehle.

Grundsätlich ist es falsch, die Zeit neu einzustellen.

Also du willst 104uS , was einem Wert von 824 entspricht.
Wenn man die zwei clk zur Syncronisation des Timers beachtet,
ist das dann ein Wert von 822 .

Anstelle von
timer0 = -822 ;
solltest du folgendes machen
timer0 -= 822;
oder auch
tmr0_low -= LOW(822)
tmr0_high -= HIGH(822)

Damit verstellst du den Timer nur um die gewünschte Zeiteinheit und die
Zeit für den Interrupt bzw ein high priority interrupt macht keinen
kummulativen Fehler.

von Chris (Gast)


Lesenswert?

Nachtrag, wenn du was reinschreibst, und dasselbe rausliest, in den 
nächsten
zwei Befehlen, dann liest du automatisch den alten Wert, da es eine 2clk
Synchronisation gibt.

von hannes (Gast)


Lesenswert?

mit dem neusetzen des timers hast du natürlich recht - dadurch ist es 
möglich ein paar clock-zyklen zu verlieren - aber doch nicht 120???

bzgl. 2clk synchronisation: auch ein erneutes auselesen (>2 zyklen 
später) gibt mir für das high byte 0x00 zurück...

irgendwie muss ich einen systematischen fehler haben - stimmt etwa 
irgendetwas nicht an meiner timer0 init? eventuell an der reihenfolge?

von hannes (Gast)


Lesenswert?

Nachtrag:
Kann es eventuell mit dem watchdog zusammenhängen? Den hab ich nämlich 
aktiviert (bei der Simulation in MPLAB ist er aber automatisch 
deaktiviert)?

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.