pic 18f25k20 - timer0 reload

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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.