|
DAN132
Dios Timer Primer
Timer0
By Michael
Simpson
The
Dios has 4 hardware timers. In this application note I will cover in
detail how to use and program the Timer0
You
access timers via registers. The registers can be access directly from
Dios. The main register used with Timer0 is T0CON.
Lets
take a look at some of the configuration of T0CON
Timer or Counter
Timer0 can
operate as a timer or as a counter. To set Timer0 as a counter set bit 5 of
T0CON to 1. IE T0CON.bit(5)=1
If set as a
counter input is applied to IO port 17. This port is also used to program
the Dios. For this reason it is not recommended to use Timer0 as a
counter. Timer1 would probably make a better counter. To set Timer0 as a
timer set bit 5 of T0CON to 0. IE T0CON.bit(5)=0
In timer mode
the timer will increment its register counters (TMR0L and TMR0H) on every
instruction cycle of the Dios or every .1us when the prescaler is not
used.
Prescaler
The prescaler allows us to divide the
internal counts by various devisers to give us a larger range of
operation. For instance by using a prescaler of 1:2 the counter registers
will only increment every .2us. To enable the prescale set bit 3 of T0CON
to 0. IE T0CON.bit(3)=0
Once the prescal has been enabled you set
the actual prescal with the following bits:
Bits 2,1,0 = Ratio
111 = 1:256
110 = 1:128
101 = 1:64
100 = 1:32
011 = 1:16
010 = 1:8
001 = 1:4
000 = 1:2
IE to se to a ration of 1:128 Use:
T0CON.bit(2)=1 : T0CON.bin(1)=1 : T0CON.bit(0)=0
Edge Selection bit
If you are using Timer0 as a counter you
can set the counter to increment on the rising of falling edge of IO port
17. To setup to count on the low to high transition set bit 4 to 0. IE
T0CON.bit(4)=0
To setup to count on the high to low
transition set bit 4 to 1. IE T0CON.bit(4)=1
8 or 16 bit mode
The timer can operate in 8 or 16 bit
mode. If operating in 8 bit mode the timer will increment the TMR0L
register only. When in 16 bit mode both the TMR0L and TMR0H register is
incremented.
Reading and writing the
counter registers
Because of the nature of the hardware
timer you must read and write the TMR0L and TMR0H bits in a particular
order.
When reading read TMR0L first then
TMR0H. The act of reading TMR0L loads TMR0H with a correct value. This
is done so that you can read the values while the timer is operating.
When writing write to TMR0H first then
TMR0L. The act of writing to TMR0L sends the buffered data to the timer.
Again this is done so that you can write to the timer on the fly.
Counter Overflow
When the 8 or 16 bit counter overflows
(wraps) a special bit is set. This bit can be polled or used to set an
interrupt.
Timer0’s overflow bit is located on bit 2
of the INTCON register.
You can check this bit with and if
statement as in:
if INTCON.bit(2) = 1 then
print “its set”
endif
Its up to you to reset this bit to 0. As
a good habit you should also set this bit to 0 before staring the timer.
Presetting the TMR0H and
TMR0L registers
If you set these to registers to 0 they
will have to count all the way to 65535 before an overflow occurs. By
setting the value ahead just a bit will allow us to fine tune exactly when
the timer will overflow.
For example use a prescale of 256 The
Dios will increment the counters once every 25.6 microseconds. So by
presetting the TMR0H to 103 and TMR0L to 150 we can get an overflow every
second.
Timer Enable/Disable
You turn the timer on by setting bit 7 of
T0CON to 1. Turn it off by setting the bit to 0. IE T0CON.bit(7)=1
Bit summary
Bit 0 –
2 Timer prescale
Bit
3 Timer prescale assignment. 0=use prescal, 1=no prescale
Bit
4 Timer edge source (used only when counting)
Bit
5 Timer Source. 0=Internal, 1=Transitions on IO port 17
Bit
6 Timer mode. 0=16 bit mode, 1=8 bit mode
Bit
7 Timer On/Off. 0=Off, 1=On
Examples
Program
1 (download
it here)
In this first example we are going to set
the timer up as a 1 second counter. We will poll the overflow bit and
print a messages every time it over flows. This allows us to do a few
things in the background.
func main()
dim seconds
seconds = 0
'------------------
'Initial setup
'------------------
INTCON.bit(2)=0 'clear timer0
overflow flag
T0CON.bit(7)=0 'Make sure its off
TMR0H=103 '1 second (you must always
write high byte first
TMR0L=150
T0CON.bit(6)=0 '16 bit mode
T0CON.bit(5)=0 'Internal clock
T0CON.bit(3)=0 'Assign prescale
T0CON.bit(2)=1 'Prescale Each Tic =
25.6us
T0CON.bit(1)=1 'Prescale
T0CON.bit(0)=1 'Prescale
T0CON.bit(7)=1 'Start Timer
loop:
if INTCON.bit(2) = 1 then
INTCON.bit(2) = 0 'Remember to
reset
'We must also reset the counters
cause they just wraped to 0
TMR0H=103 '1 second (you must
always write high byte first
TMR0L=150
seconds = seconds + 1
print seconds," Seconds"
endif
goto loop
endfunc
Notice what goes on inside the loop.
You must always reset the overflow flag and and reset the counters if
preset.
Program
2 (download
it here)
In this second example the onirq command
is used to point the timer IRQ to our test function.
func main()
global seconds
seconds = 0
pause 1000
print "Start Program"
'------------------
'Initial setup
'------------------
INTCON.bit(2)=0 'clear timer0
overflow flag
T0CON.bit(7)=0 'Make sure its off
TMR0H=103 '1 second (you must always
write high byte first
TMR0L=150
T0CON.bit(6)=0 '16 bit mode
T0CON.bit(5)=0 'Internal clock
T0CON.bit(3)=0 'Assign prescale
T0CON.bit(2)=1 'Prescale Each Tic =
25.6us
T0CON.bit(1)=1 'Prescale
T0CON.bit(0)=1 'Prescale
T0CON.bit(7)=1 'Start Timer
INTCON.bit(5)=1 'Turn on Timer0 IRQ
INTCON.bit(7)=1 'Enable Global IRQ's
onirq TMR0,letscount
loop:
pause 100
print ".";
goto loop
endfunc
irqfunc letscount()
TMR0H=103 '1 second (you must always
write high byte first
TMR0L=150
seconds = seconds + 1
print seconds," Seconds"
exitirq TMR0
endirq
I welcome other
observations or remarks. Just contact me at
msimpson@kronosrobotics.com
Parts
list
Dios 40 Pin Chip
Dios Carrier #4
7.5V AC Adapter
9 Pin Cable
Breadboard and
Wire Kit
Breadboard
Regulator
|