M3 processor automatically disables interrupts when it
starts an ISR and re-enables them when it leaves an ISR.
Other MCUs such as those in the PIC families require ISR
software to handle these tasks.
exist outside the main portion of a program. The
asynchronous nature of interrupts can complicate testing
because programmers cannot predetermine when an
interrupt will occur.
The following program illustrates a simple ISR that
turns on an LED when the input signal at mbed pin p12
changes from a logic 1 to a logic 0; a falling edge. (You
can download all the software for this article and an extra
program at the article link.) In the example below, the
Interrupts for an MCP2515
“infinite” while-loop statements cannot affect the LED
called LED_irq. Only the ISR can do that, and it exists as a
section of code separate from the main program:
Because we don’t know when a CAN controller will
receive data, an interrupt can let an MCU immediately
attend to the receiver buffers. The MCP2515 CAN
controller provides one interrupt-output signal (/INT) at
pin 12. The MCP2515 CANINTF (CAN Interrupt Flag)
register holds flag bits for eight devices or events. A logic
1 bit indicates a request for service:
//Interrupt Test INTJT.cpp
//header file for mbed MCUs
1. RX0IF and RX1IF show when the corresponding
receiver buffer has new data.
//define output for flashing LED
//LED for interrupt indication
//Use mbed pin 12 as interrupt input
2. TX0IF, TX1IF, and TX2IF mark the corresponding
transmitter as having completed a transmission.
3. ERRIF lets software know an error of some type
void LED_ISR() //Interrupt service routine
IRQ_led = 1; //Turn on LED4 on mbed
} //End of ISR code
4. WAKEIF lets an MCU know the MCP2515 has
detected bus activity while in the low power “sleep” state.
5. MERRF indicates an error occurred during
transmission or reception of a message.
//Use internal pull-up resistor
//IRQ_pin will detect a falling edge of
//pulse. Specify thelocation of the ISR code
IRQ_led = 0; //Turn off LED4
As explained earlier, software can read the CANINTF
register value and test flag bits at any time to determine
whether a device or event needs attention. (After the
software takes action, it must reset the corresponding
INTF-register flag bit to a logic 0.) The CANINTF bits alone
will not cause an interrupt.
while(1) //Run this loop forever
myled = 1;
//Blink LED1 to show this code runs
myled = 0;
} //End of while loop
} //End of main
A program also must set the corresponding bit or bits
in the CAN Interrupt Enable (CANINTE) register. The
contents of this eight-bit register let us enable (logic 1) or
disable (logic 0) interrupts as needed. Figure 3 shows the
In this program, I identify two onboard LEDs and
define mbed pin 12 as an interrupt input I call
IRQ_pin. You may choose another name if you wish.
The ISR — named LED_ISR — contains one instruction
that will turn on LED4. In the main portion of the
code, the IRQ_pin.mode(PullUp); statement turns on
an internal pull-up resistor at the IRQ_pin so the input
becomes a logic 1 if left unconnected. (You could use
an external pullup resistor instead.) The statement
IRQ_pin.fall(&LED _ISR); sets the mbed pin so it will
cause an interrupt only when it detects a logic 1 to
logic 0 edge. It includes the address of the LED_ISR
If you run this program and then ground mbed pin
12, LED4 will turn on. Nowhere in the main program
does the MCU test the state of pin 12. When you use
the online mbed tools and libraries, the mbed Cortex-
FIGURE 3. A simplified diagram of the registers, gates, and signals
involved in MCP2515 interrupts. Pin numbers refer to the DIP
version of an MCP2515 IC. Register read-write operations occur
through an SPI connection with an MCU.
30 April 2017