One of the most important tasks a microcontroller can do is...
...measure time.
The microcontroller can easily do this as it operates using a fixed
frequency clock oscillator.
The clock oscillator sets the speed of the microcontroller operation - this can
either be an external crystal (up to 20MHz) or for modern PIC devices it can be
an internal RC oscillator (from 4MHz to 8MHz).
Note: Using the internal oscillator saves
having to wire up external hardware but the clock is less accurate.
Since each instruction executes in a set period of time (for the PIC micro this
is 4 cycles of the clock) you can time events by working out how many
instructions have executed.
Note: for jump instructions an extra cycle is
needed.
By creating a routine containing an assembler code loop and knowing the
clock speed you can create exact delay times since you know the time taken for
each instruction to execute (from the datasheet).
If you repeatedly executed this routine and kept a count of the number of times
it's called then you can measure time in multiples of the execution time of the
routine.
There's two problems to this method.
1.The microcontroller is not doing
useful work while it is executing the delay routine.
2.Measuring the delay time of the code
is not always easy (especially for complex loops).
The advantage of the timer peripherals is that they make it a trivial task
to measure time. They are hardware modules that operate separately from the
CPU part of the microcontroller.
This also means that they are capable of very high speed operation (you can
make a 50MHz frequency counter using a timer (even for the obsolete 16F84
device).
In the modern microcontrollers there are three timers; Timer0 Timer1 and Timer2 and each has different
operations and capabilities.
You can use the timers to count periods of the internal clock or you can count
periods of an external clock (for a signal connected to the correct pin of the
microcontroller) i.e. a timer input- for Timer 0 this would be T0CKI -Timer0
ClocK Input)
Note: Some timers can only count the internal
clock - check the datasheet.
N.B. When counting the internal clock it is
divided by 4 first Fosc/4.
There are two ways to use a timer polled or interrupt.
You can continuously read the timer
values until you detect a value you want to measure e.g. to count to 1000
compare the timer registers to 1000 then do something.
Although it's simple the disadvantage is that the microcontroller can do
nothing else while polling (or can do very little as it has to keep going back
and looking at the timer registers).
When a timer overflows (passes from its maximum value to zero) it generates
an interrupt signal which you can use to interrupt the CPU to tell it
something has happened.
This means the CPU can go and do other processing tasks while the timer
hardware is running in the background.
Although more complex to set up and use an interrupt driven timer is the better
way to use a timer if you need to do other processing tasks.
When you add in other peripheralsinterrupts
are essential e.g. measuring time while servicing a serial interface.
Timer 0 is an 8 bit timer with an 8 bit prescaler - in total it looks like a
16 bit timer and it was the original peripheral (actually the only peripheral
in the 16F84!). Its slightly tricky to use when starting out as you can not
read the prescaler value (there are ways around this).
So lets just look at the next timer:
Timer1 is a 16bit timer with a
prescaler that can be set to 1,2,4 or 8 and it can take an input clock from a
pin or use the internal oscillator (Fosc/4).
A prescaler is just a divider so if you had a clock frequency of 8MHz and the
prescaler as set to 8 the output from the prescaler would be 1MHz.
Timer 2 is an 8 bit timer that can only count periods of the internal clock
Fosc/4. It has a 2 bit prescaler and a 4 bit postscaler - these make the
range out output periods (or frequency) flexible.
In addition it has a period counting register that resets the counter when the
counter reaches a programmed count (programmed by you). This means Timer 2
can generate a wide range of output frequencies easily and this is used to
generate the baud clock for the internal USART.
A timer measures out set periods of time or counts periods but they are
limited by the maximum count that they can store.
The maximum count is important as it sets a limit on the usefulness of the
timer (without extra programming).
So for Timer1 prescaler set to 1 the maximum count is 65535. So you could
count up to a maximum of 65535 events.
To overcome this limit you can use a variable to store the number of times that
the Timer overflows - the variable would then store the input event count in
multiples of the Timer's maximum value.
This makes it practical to measure any number of events.
Next time...
... Overview of other Internal Peripherals.
Comments
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.