OK, I now have a PIC18F2431 with acounter set up on Timer1 and a time base set up on Timer0.
The counter was pretty straight forward but i have a few questions regarding the operation of Timer0
1/. Timer Pre-Load
Timer0 is a 16 bit timer which gives an output as it rolls over from $FFFF to 0.
An 8MHZ clock speed will provide one instruction every 500ns. For a 100Hz time base (10ms period) I would need 20000 instruction cycles (20000 x 500ns = 10ms).
A free running timer wiith no pre-load would roll over every 65536th cycle so to achieve a 20000 cycle roll over I need to pre-load the timer with 65536 - 20000 = 45536.
All good - nice clean theory however, a 45536 pre-load results in ~50Hz time base!
Here is my code:
Code:
#CONFIG
CONFIG OSC = IRCIO
CONFIG FCMEN = ON
CONFIG IESO = OFF
CONFIG PWRTEN = ON
CONFIG BOREN = ON
CONFIG BORV = 42
CONFIG WDTEN = OFF
CONFIG WDPS = 512
CONFIG WINEN = OFF
CONFIG PWMPIN = OFF
CONFIG LPOL = HIGH
CONFIG HPOL = HIGH
CONFIG T1OSCMX = OFF
CONFIG MCLRE = ON
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = ON
CONFIG CP1 = ON
CONFIG CP2 = ON
CONFIG CP3 = ON
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTC = OFF
CONFIG WRTB = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
#ENDCONFIG
' Set up interrupt routine
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, _ISR, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR0_INT ; Enable Timer 0 Interrupts
' Define LCD registers and bits
Define LCD_DREG PORTB
Define LCD_DBIT 4
Define LCD_RSREG PORTA
Define LCD_RSBIT 1
Define LCD_EREG PORTA
Define LCD_EBIT 2
Define LCD_BITS 4
Define LCD_LINES 2
' Set up Internal Oscillator @ 8MHz
DEFINE OSC 8
OSCCON = %01110010 ' Internal oscillator, 8MHz
' Set up Timer0
T0CON = %00001000 ' Timer off
' 16 bit
' Internal clock
' Prescaler not assigned
T0CON.7 = 1 ' Start Timer0
' Set up I/O Ports
ANSEL0 = 0 ' No analogue input, all digital
TRISA = 0 ' ALL PORTA as outputs
PORTA = 0 ' All outputs low
TRISB = 0 ' ALL PORTB as outputs
PORTB = 0 ' All outputs low
TRISC = 0 ' Set PORTC as output
PORTC = 0 ' All outputs low
Pause 100
LCDOUT $FE,1," Baztronics "
Pause 100
TMR0_Reload CON 55750 ' Reload value for ~100Hz interrupt frequency at 8MHz, prescaler 1:1
TMR0_Temp VAR WORD ' Temporary variable use for reloading the timer
LED1 VAR PortC.2
Main:
Pause 100
Goto Main
' This is the interrupt routine for the TMR0 interrupt.
ISR:
T0CON.7 = 0 ' Stop timer
TMR0_Temp.LOWBYTE = TMR0L
TMR0_Temp.HighByte = TMR0H ' Get current "time"
TMR0_Temp.LOWBYTE = TMR0L
' TMR0_Temp.HighByte = TMR0H
TMR0_Temp = TMR0_Temp + TMR0_Reload ' Add reload value to get correct interval
TMR0L = TMR0_Temp.LOWBYTE
TMR0H = TMR0_Temp.HIGHBYTE ' Move result back to timer
TMR0L = TMR0_Temp.LOWBYTE
' TMR0H = TMR0_Temp.HIGHBYTE
T0CON.7 = 1 ' Start timer
Toggle LED1
@ INT_RETURN
I know my internal oscillator is operating at 8MHz because my LCDOUT commands work properly.
Can anyone explain why the time base is not as predicted?
2/. TMR0L and TMR0H
The datasheet states that "TMR0H is not the high byte of the timer/counter in 16bit mode, but is actually a buffered version of the high byte of Timer0" and that it "is not directly readable nor writable."
It goes on to explain that "TMR0H is updated wth the contents of the high byte of TMR0 during a read of TMR0L" The same conditions apply for write operations.
The way I understand this, I must read the TMR0L first, this transfers the buffered data to the high byte of TMR0H and THEN I can read the high byte directly.
Obviously I have mis understood the operation as this does not work.
The only way I can get the timer to provide a stable time base is to read TMR0L twice and TMR0H once OR read TMR0H twice and TMR0L once.
Would someone be able to describe how/why the low and high bytes of TMR0 should be read/written?
Cheers
Barry
VK2XBP
Bookmarks