MX016 - Measuring Time with Interrupts - Matrix Multimedia Ltd
MX016 - Measuring Time with Interrupts - Matrix Multimedia Ltd
MX016 - Measuring Time with Interrupts - Matrix Multimedia Ltd
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
© <strong>Matrix</strong> <strong>Multimedia</strong> 2011 <strong>MX016</strong> - <strong>Measuring</strong> <strong>Time</strong> <strong>with</strong> <strong>Interrupts</strong><br />
<strong>Measuring</strong> <strong>Time</strong> <strong>with</strong> <strong>Interrupts</strong><br />
Page 1<br />
by Ben Rowland, May 2009<br />
Abstract<br />
One problem <strong>with</strong> using or designing embedded systems is that it is hard to tie in real<br />
world values like time or an incoming frequency to the operation of the embedded<br />
system, the answer is to use onboard timers present in the majority of microcontrollers.<br />
This article will attempt to explain interrupts and how you can use them in your<br />
own programs.<br />
Requirements<br />
Software:<br />
• Any licence type of Flowcode v3 or v4 for any variant.<br />
Hardware:<br />
• No specific hardware required.<br />
Introduction<br />
One problem <strong>with</strong> using or designing embedded systems is that it is hard to tie in real world values<br />
like time or an incoming frequency to the operation of the embedded system. What is required is a<br />
regular tick that will not vary over time and is slow enough to be collected <strong>with</strong>in the main running<br />
program.<br />
To generate this tick we will be using a timer interrupt. Most microcontroller devices have at least one<br />
or more onboard timers. The main difference between timers is the size of the counting register. This<br />
can either be 8-bit, 16-bit or 32-bit. The PICmicro devices normally have a total of three timers consisting<br />
of two 8-bit timers named timer0 and timer2 as well as a 16-bit timer named timer1.<br />
When a timer interrupt is enabled the timer starts counting via the internal clock and the timer registers<br />
then start to increment. As the registers increment there will be a point where the maximum<br />
count value is reached (255 for 8-bit, 65535 for 16-bit). When this occurs, the timer count registers<br />
reset to zero and the interrupt routine is triggered.<br />
Note that the timer registers are still counting while you are processing the interrupt routine so the<br />
main aim is to process your interrupt and return to your main program well before another timer overflow<br />
occurs. If the interrupt routine carries on past the next timer rollover then you could either miss a<br />
tick or worse still you could become trapped inside the interrupt service routine and never actually<br />
process any of your main background program.<br />
The timer interrupt enable settings normally show a clock source assigned to the timer count registers.<br />
Unless you are providing an external clock to drive the timers this setting should always be set<br />
to “CLKO” or “Internal Clock Out” in English.<br />
So assuming we have designed our program to have a nice fast interrupt macro we will get a steady<br />
tick that can be used for a great range of applications. Over the page are listed a few I can think of<br />
off the top of my head.
© <strong>Matrix</strong> <strong>Multimedia</strong> 2011 <strong>MX016</strong> - <strong>Measuring</strong> <strong>Time</strong> <strong>with</strong> <strong>Interrupts</strong><br />
• Clocks / Stopwatches<br />
• Frequency generators / counters / analysers<br />
• Data loggers<br />
• Alarm systems<br />
• Feedback / Closed-loop systems<br />
• Real time operating systems<br />
• Etc<br />
Example Programs<br />
Two example programs have been provided as part of this article. These can be found in the accompanying<br />
downloadThe first deals <strong>with</strong> counting seconds to drive a clock based system. The second<br />
uses interrupts to measure the frequency of an incoming digital waveform.<br />
Example Program 1. Building a flexible and reliable second counter.<br />
Firstly I added an interrupt icon to my program and double clicked it to access the properties.<br />
I assigned the interrupt source to the TMR0 Overflow and created a new macro for the Interrupt to<br />
call.<br />
I then clicked properties to access the properties of the timer.<br />
Inside the properties I changed the clock source to the Internal Clock CLKO<br />
I also changed the Prescaler rate to give me a tick frequency of 150Hz or 150 ticks per second. This<br />
is based on my clock speed of 19.6608MHz so if you are using a different clock speed then try and<br />
find a nice whole number frequency so you are not loosing accuracy as your program runs. Also remember<br />
that nothing will work correctly unless the clock speed setting in Flowcode matches your<br />
actual hardware clock speed.<br />
Page 2
© <strong>Matrix</strong> <strong>Multimedia</strong> 2011 <strong>MX016</strong> - <strong>Measuring</strong> <strong>Time</strong> <strong>with</strong> <strong>Interrupts</strong><br />
I have made a couple of comments in the example about how I improved the functionality so as to<br />
never miss a second even if the main loop were to take more than a second to complete.<br />
I also started to hint at how a minute variable could be worked in to create a full working clock. If you<br />
should want to implement a fully working clock then example TUT_22 in the Flowcode V3/Examples<br />
directory contains a fully working version.<br />
Example Program 2. Working out delays or frequencies based on timer overflows.<br />
In this example our main program is monitoring the status of pin RA0. Whenever pin RA0 goes low<br />
and then high we increment our frequency count value by 1. The Pin we are monitoring can be edited<br />
by changing the input icon inside the Read_Input Macro. At the same time this is happening we<br />
have an interrupt running at 75Hz. We count the number of interrupts and when a count value of 75<br />
is reached we know that a second has passed. Seeing as frequency is measured in cycles per second<br />
it seems like a good option to use this as our refresh interval. Also it means no further calculations<br />
are necessary to work out the actual pulse frequency.<br />
When the interrupt count value has reached 1 second the update display flag is set. This causes the<br />
input checking while loops to exit immediately to go and service the display.<br />
(in = 1) && (update_display = 0)<br />
The double and (&&) is used to tell the compiler that we only want to stay in the loop if in is equal to<br />
one AND update_display is equal to 0. If you wanted to check for this OR that then you can use the<br />
double OR symbol which looks like this ‘||’. So we don’t get a false reading of one when there is no<br />
incoming frequency we take a copy of the frequency variable before the while loops are forcibly exited<br />
and this is the value that is then passed onto the LCD.<br />
Once the display has been updated the program then clears the count variables and also clears the<br />
timer interrupt count register. This means we are all ready to begin recoding the frequency reliably<br />
<strong>with</strong> an accurate starting position.<br />
Page 3
© <strong>Matrix</strong> <strong>Multimedia</strong> 2011 <strong>MX016</strong> - <strong>Measuring</strong> <strong>Time</strong> <strong>with</strong> <strong>Interrupts</strong><br />
Further reading<br />
Below are some links to other resources and articles on related subjects, and technical documentation<br />
relating to the hardware used for this project...<br />
Flowcode: http://www.matrixmultimedia.com/flowcode.php<br />
Learning Centre: http://www.matrixmultimedia.com/lc_index.php<br />
User Forums: http://www.matrixmultimedia.com/mmforums<br />
Product Support: http://www.matrixmultimedia.com/sup_menu.php<br />
Copyright © <strong>Matrix</strong> <strong>Multimedia</strong> Limited 2011<br />
Flowcode, E-blocks, ECIO, MIAC and Locktronics are trademarks of <strong>Matrix</strong> <strong>Multimedia</strong> Limited.<br />
PIC and PICmicro are registered trademarks of Arizona Microchip Inc.<br />
AVR, ATMega and ATTiny are registered trademarks of the ATMEL corporation.<br />
ARM is a registered trademark of ARM <strong>Ltd</strong>.<br />
Page 4