pic 18f25k20 - timer0 reload

Gast #2654678
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
Gast #2654753
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.
Gast #2657386
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?

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