Skip Navigation Links
Microcontroller Beginner Kit
Microcontroller Beginner Kit
$30.95
Image of the Atmega324p
Atmega324P

$8.50
330 ohm metal film resistor
330 Ohm Through Hole Resistor
$0.15
Thumbnail: 10K through hole 1/4 watt resistor
10K Resistor 1/4 watt Through Hole
$0.15
3 Foot USB Cable Type A to USB Cable Type A
USB Cable Type A Male to USB Type A Male - 3 FT
$2.65
USB 2.0 Cable 10 Foot Type A Male to Type B Male
USB 2.0 Cable Type A Male to Type B Male - 10 FT
$4.80
Red Through Hole LED (Light emitting diode)
Single Red Through Hole LED (Light Emitting Diode)
$0.34
Green through hole LED (light emitting diode)
Single Green Through Hole LED (Light Emitting Diode)
$0.34
Yellow through hole LED (light emitting diode)
Single Yellow Through Hole LED (Light Emitting Diode)
$0.34
Thumbnail: An Accelerometer and 2 headers with drafting pencil in foreground for scale
ADXL345 Breakout board (I2C/SPI)

$27.95

Microcontroller - A Beginners Guide - Introduction to Interrupts - Using the Timer/Counter as an Example

Since our brains are still warm on the subject of timers and counters, we will investigate how interrupts work using the counter as an example. Interrupts really enhance the use of microcontrollers ina big way. Interrupts make your programs react to the hardware of the microcontrollers, which may be a reaction from the circuit/evironment outside of the microcontoller.

Basically, an interrupt is exactly defined by it's title... it interrupts the normal program flow to do something else (other code block that you program). Imagine your program is doing its normal blinking LEDs or something and you want it to react to, say, a PIR (Passive Infra Red) sensor (connected to an interrupt pin), and goes to a special code block to, say, make a beep from a buzzer connected to another pin. If you tell the microcontroller to do this, it will stop the program in its tracks and go to the code that belongs to that interrupt (make a beep). After the interrupt code is executed, the program continues exactly where it left off. In some cases, interrupts would be an alternative to polling something, which requires program cycles. For example, say your program is wanting to only beep when a person passes the PIR sensor. Your program could keep testing that pin to see if it has a high reading over and over within the never ending loop (while(1)). Instead, remove all of the polling program code to test the pn for a high reading and let the interrupt automatically go to the beep code when the micocontroller senses the high reading.

So, what types of interrupts are available for the AVR Microcontroller? Interrupts can be established for events such as a counter's number, a pin changing state (from low to high or high to low), serial communication receiving of information, or the Analog to Digital having established a conversion. Here is a full list of interrupt vectors that you can use. Other tutorials will make use of many of these interrupt vectors.

We are going to use the timer/counter as an example. We will inform the timer/counter of a number that the TCNT1 (the couter) will need to match. The number to match will go into a register called OCR1A (Output Compare Register). The "1" represents the specific counter we are using which is the 16-bit version. We have two OCRs, the A and the B. We will use A for this example. However, do we know if the counter will reset to zero when th match is made? We definitely want the TCNT1 to go back to zero so the count will start over and we get another match at our intended number, but this isn't done in code like we did last time (remember the TCNT1 = 0;). This time, we will want to turn on another switch in the TCCR1B control register called WGM12 (waveform Generation Mode for timer 1). The #2 in that switch just represents which WGM it is, since there are a few. We will also be using the CS10 and CS11 again to set the prescaling to 64 as in the intro to timers video.

Then the timer/counter will need to know that we intend to use the interrupt feature. This is done through the TIMSK (Timer/Counter Interrupt Mask Register). We only need to turn on one switch in this register: the OCIE1A (Output Compare A Match Interrupt Enable) switch. Once the number put into the OCR1A is matched by the counter, the program will be interrupted to toggle the LED. For an interrupt to happen, we will need to enable the global interrupts "sei()", then we will need to enable the interrupt for the timer/counter, and finally the interrupt service routine (ISR) will need to be created. The interrupt service routine is just like the functions that were made in the button game example. The interrupt service routine is just a code block outside of the main routine and begins with ISR with the vector within parenthesis "(vector)", ollowed by the block of code within brackets"{Code}". For the timer/counter (16-bit version), and the fact that we are using the A version of the OCR1, the vector name is: TIMER1_COMPA_vect. So the routine would be: ISR(TIMER1_COMPA_vect) { code to execute }.

We used a number in the intro to timers video that represented one second: 15625, so we will use this one for the OCR1A. But, the number should consider indexing from 0, so we will need to use the number 15624 instead.

Let's put all of this information together in a program:

#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
sei();

DDRB |= 1<<PINB0;

TCCR1B |= 1<<CS10 | 1<<CS11 | 1<<WGM12;
TIMSK |= 1<<OCIE1A; //If using atmega324, this regester is TIMSK1
OCR1A = 15624;

while(1)
{
}
}

ISR(TIMER1_COMPA_vect)
{
PORTB ^= 1<<PINB0;
}

Here is the pseudocode version:

  • Include some basic information to properly configure our microcontroller.
  • Include the interrupt library that has all the interrupt functions we need.
  • Start the main routine (do the indented stuff)
    • Enable the global interrups
    • Since we are using an LED, enable that pin to be output
    • Turn on the timer and use 64 prescaling (skip 64 clock ticks)
    • Enable the output compare register and set a number to represent one second
    • Loop Forever
    • No code needed in the forever loop this time
  • End main routine
  • Start Interrupt routine (for the correct vector)
    • Toggle the pin to which the LED is connected
  • End Interrupt routine (go back to where the program left off)