Basic Schematic

Hardware Interrupts Demo and Tutorial for ATMEGA168/Arduino

by Lewis Loflin

The purpose of this page is to introduce the student to hardware interrupts on micro-controllers. A hardware interrupt causes the processor to save its state of execution and begin execution of an interrupt handler. Software interrupts are usually implemented as instructions in the instruction set, which we won't cover here. Interrupts are a commonly used technique for computer multitasking, especially in real-time computing. Such a system is said to be interrupt-driven. An act of interrupting is referred to as an interrupt request (IRQ).

Hardware interrupts were introduced as a way to avoid wasting the processor's valuable time in polling loops, waiting for external events. They may be implemented in hardware as a distinct system with control lines, or they may be integrated into the memory subsystem. If implemented in hardware, an interrupt controller circuit such as the IBM PC's Programmable Interrupt Controller (PIC) may be connected between the interrupting device and the processor's interrupt pin to multiplex several sources of interrupt onto the one or two CPU lines typically available. If implemented as part of the memory controller, interrupts are mapped into the system's memory address space. Interrupts can be categorized into: maskable interrupt (IRQ), non-maskable interrupt (NMI), interprocessor interrupt (IPI), software interrupt, and spurious interrupt.

A maskable interrupt (IRQ) is a hardware interrupt that may be ignored by setting a bit in an interrupt mask register's (IMR) bit-mask. Likewise, a non-maskable interrupt (NMI) is a hardware interrupt that lacks an associated bit-mask, so that it can never be ignored. NMIs are often used for timers, especially watchdog timers. An example of this is the obsolete 6502 used in early Apple computers.

A software interrupt is an interrupt generated within a processor by executing an instruction. Software interrupts are often used to implement System calls because they implement a subroutine call with a CPU ring level change. A spurious interrupt is a hardware interrupt that is unwanted typically caused by electrical noise on an interrupt line or through incorrectly designed hardware. This can also be caused by unstable or bad power supplies.

This tutorial will help the student become familiar with hardware interrupts. Here I'll look at the two hardware interrupts on the ATMEGA168/Arduino. The two ATMEGA168 interrupts can be enabled/disabled under program control, thus are maskable interrupts. In some ways a hardware reset could be considered a type of interrupt. See pages 56-66 in the ATMEGA168 spec sheet for more on interrupts.

Program and Test



For the function attachInterrupt(interrupt, IRQroutine, mode) is the key to the usage and control of the Arduino micro-controller interrupts on digital pins 2 and 3.

Parameter 'interrupt": 0 for interrupt 0 (digital pin 2) or 1 for interrupt 1. (digital pin 3)

"IRQroutine" is a subroutine that is called when the interrupt condition is met. They are structured in much the way other subroutines are structured.

Mode defines when and how the interrupt should be triggered. Four constants are predefined as valid values:

* LOW to trigger the interrupt whenever the pin is low.
* CHANGE to trigger the interrupt whenever the pin changes value.
* RISING to trigger when the pin goes from low to high. This is called positive edge-triggered.
* FALLING for when the pin goes from high to low. This is also called negative edge-triggered.

Note:
Inside the attached IRQ function, the delay() function won't work!
Serial data received while in the function may be lost.
You should declare as volatile any variables that you modify within the attached function.

The way to turn off an interrupt is use the detactInterrupt function:

detachInterrupt(0) shuts off any further interrupts from digital pin 2.
detachInterrupt(1) shuts off any further interrupts from digital pin 1.

To reactivate the interrupt one must call the attachIinterrupt() function again.

The function noInterrupts() disables both interrupts. Interrupts can disrupt some code if they come in before they processor is ready for them. The function interrupts() will reactivate both interrupts.

Caution: I've found the use delay(x) milliseconds function to be unreliable when using either of the two interrupt pins. For an alternate solution use following code:

For (int i = 0, i= delay_time; i++) { delayMicroseconds(1000); } // delay_time is number of milliseconds.

1000 microseconds = 1 millisecond.
1000 milliseconds = 1 second.

Operation and Test

Part 1) If all is wired correctly and the program is uploaded to the ATMEGA168, the following should be observed:

Press Sw1 and hold, when released LED1 should come on. Press and hold again, when released LED1 should go off. This is programmed as 'RISING' and when the switch is released the voltage on the pin goes from zero volts to five volts. As long as the switch is pressed nothing will happen until switch is released.

Press Sw2 and LED2 comes on immediately unlike with Sw1. Only when the switch is first pressed off-to-on will the LED2 change state or "toggle."

Part 2) Next go into Setup section below and change the following:

attachInterrupt(0, flag1, RISING); // interrupt 0 digital pin 2 connected sw1
attachInterrupt(1, flag2, FALLING); // interrupt 1 digital pin 3 connected sw2

to

attachInterrupt(0, flag1, CHANGE); // interrupt 0 digital pin 2 connected sw1
attachInterrupt(1, flag2, LOW); // interrupt 1 digital pin 3 connected sw2

Change the delay value below to 2000 in the 2nd "if" statement.

Recompile and upload the program.

Press Sw1 and the LED1 goes on when pressed and off when released. This is because the action produced two changes (HIGH to LOW and LOW to HIGH) of the state on the input pin.

Press Sw2 and LED2 comes on, release and it stays on for two seconds before going off. Explain why this happens.



// LED must be connected between digital pin and ground

#define led1 5
#define led2 6

// switch must be connected between digital pin and ground

#define sw1 2
#define sw2 3

// when using values in the main routine and IRQ routine must be volatile value

volatile byte flag_bit1 = LOW; // declare IRQ flag
volatile byte flag_bit2 = LOW; // declare IRQ flag


// HIGH = 1, LOW = 0

void setup()  {
  pinMode(led1, OUTPUT);  
  pinMode(led2, OUTPUT);
  digitalWrite(led1, 0); // LED off
  digitalWrite(led2, 0); // LED off
  pinMode(sw1, INPUT);
  pinMode(sw2, INPUT);
  digitalWrite(sw1, 1); // pull up on
  digitalWrite(sw2, 1); // pull up on
  attachInterrupt(0, flag1, RISING);  // interrupt 0 digital pin 2 connected sw1
  attachInterrupt(1, flag2, FALLING); // interrupt 1 digital pin 3 connected sw2
}

// In this particular program when a switch is pressed the voltage on an input pin 
// goes from 5 volts to zero volts. When released 0 volts to 5 volts.

void loop() {

  if (flag_bit1 == 1) {
    toggle(led1); 
    flag_bit1 = 0; // clear flag
    delay(500);  // delay .5 second
  } 

  if (flag_bit2 == 1) {
    toggle(led2); 
    flag_bit2 = 0; // clear flag
    delay(500);  // delay .5 second, change to 2000 for part 2
  }   

} // end loop

// can't use delay(x) in IRQ routine
void flag1() // set bit
{
  flag_bit1 = 1; 
} 

// can't use delay(x) in IRQ routine
void flag2() // set bit
{
  flag_bit2 = 1; 
}

// this is a sample sub-routine that changes the state of an output pin

void toggle(int pinNum) {  // toggle the state on a pin

  int pinState = digitalRead(pinNum);
  pinState = !pinState;
  digitalWrite(pinNum, pinState); 
}

switch connection
Bare Bones Kit from Modern Device Company.
This is an example of what is out there, most do the same thing.
This doesn't include the DS1307, switches, etc.

[ My Homepage ] [ Electronics Mainpage ]

ATMEGA168 Arduino Micro Controller

For more technical details on this see ATMEGA168 Arduino Micro Controller Projects


[ Home ] [ Electronics ] [ Religion 1 ] [ Religion 2 ]
[ Racism ] [ Environmentalism as Religion ]
Guestbook Archive
E-Mail
Visitors since March 2002
counter


google
Search WWW Search www.sullivan-county.com