each bank having a single interrupt
associated with it. Within each bank,
we can set which individual pins
trigger an interrupt. However, we
can’t (using registers) easily work out
which pin within a bank triggered an
interrupt. To do that, we’d need to do
some coding that compared actual
pin values to stored values.
External Interrupts have
additional functionality but are only
available on pins PD2 and PD3. They
are labelled INT0 and INT1 (refer to
Figure 1), and can be configured to
trigger more complex interrupts. They
can trigger on a rising edge (a change
on the pin from a low to a high state),
a falling edge (change from high to
low state), a pin toggle, and on a low
signal (the interrupt will continue to
trigger while the pin is low).
Both of these interrupts have their
own dedicated handlers.
We haven’t yet touched on
timers, and they don’t form an obvious part of the
Arduino IDE, so may not be familiar to you. However, we
will delve into them in a future article. In brief, your
ATmega328P has a number of internal timers that tick
away every clock cycle, and are useful for measuring
elapsed time. These timers can be configured to generate
an interrupt when they reach certain values — think of
them as tiny alarm clocks that trigger an alarm every x
In addition, there is a special kind of timer called —
interestingly — a watchdog timer. Again, we won’t have
time to go into watchdog timers now, but suffice it to say
they are also capable of generating interrupts.
When we deal with timers in a month or two, you’ll
see that the interrupts are fundamental to using them.
Last month, we dealt with serial communications
using the UART. You may remember when we transmitted
a data frame that we had to wait in a loop for the data
register to be empty before we could send the next byte.
Using interrupts, we can rewrite this code so that we
aren’t waiting around for the buffer to empty — we can
get the UART to tell us by triggering an interrupt.
In addition to this interrupt, we can also get the UART
to tell us after a data frame has been transmitted, and
when data has been received on the UART. I’m sure you
can see that these interrupts will remove the need for us
to keep polling various registers. We can keep working,
and (for example) only worry about reading incoming data
once there is actually data coming in.
Similar interrupts exist for other serial modes and
protocols such as SPI and I2C (TWI).
Other Peripheral Interrupts
A number of other peripheral interrupts exist. The
ADC (analog-to-digital converter) we looked at in the May
2015 article can generate interrupts when it has
completed a conversion. Again, this means we don’t need
to sit in a loop waiting for the ADC; we can carry on with
other tasks and then deal with the result when the
conversion is complete. The analog comparator can also
generate interrupts, as can the EEPROM module.
Please Do Not Disturb
Before we start on a practical project, let’s briefly look
at why we’d want to hang a “Please Do Disturb” sign in
our projects, as well as at a couple of cardinal rules.
Tell Me Why
From the discussion that we’ve had so far, you’ve
probably picked out a number of reasons why we’d want
to use interrupts in our projects. Here are some of the
By Andrew Retallack
July 2015 27
Post comments on this article and find any associated files and/or downloads
at www.nutsvolts.com/index.php?/magazine/article/july2015_Retallack. www.crash-bang.com
Figure 1: Interrupts
available on the external
pins of the ATmega328.