Kronos Robotics and Electronics
Site Map
 
Home Zeus Projects App Notes Downloads Dios Athena Forums
 

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

 

Copyright © 2001 - 2007 Kronos Robotics