Datum:
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
Datum:
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.
Datum:
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.
Datum:
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?
Datum:
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)?