This lecture will show you how to configure and program external interrupts (EXTI).
External interrupts are generated by peripherals or devices, external to the microcontroller,
such as push buttons and key pads.
There are two approaches to monitoring and responding to external events.
One is polling.
The other is interrupt.
The polling approach is like picking up your phone every few seconds to check whether you
are getting a call.
The interrupt approach is like waiting for the phone to ring.
Apparently, interrupt is more efficient than polling.
You are free to do whatever you should do, and pick up the phone only when it rings.
Put it simply, an interrupt is essentially a hardware-triggered software action.
The interrupt controller temporally stops the normal flow of program execution, and
causes the interrupt service routine to be executed.
After the interrupt service routine completes, normal program execution is resumed at the
point where it was last.
When there are no interrupt events, the processor runs the normal program or enters a sleep
state to conserve energy.
We will use the joystick as an example to show the basic configuration and programming
of external interrupts.
Each STM32L4 discovery kit has a four-direction joystick.
The user may push in one of four directions: up, down, left, and right.
The user may also press the center of the joystick.
Let's quickly review the schematic diagram of STM32L4 discovery kit.
This diagram shows how processor's and joystick's pins are connected.
GPIO pins PA 0, PA 1, PA 5, PA 2, PA 3 are connected to the center, left, down, right,
and up pin of the joystick, respectively.
Each pin is connected to the ground via a capacitor.
These capacitors perform hardware debouncing.
Here is the internal diagram of the joystick.
It has five switches.
The common terminal is connected to positive 3 volts.
When the up of the joystick is pressed, this switch is then closed.
As result, PA 2 is then connected to the 3 volt via the common terminal.
Pay attention, the joystick center pin is pulled down to ground via a 10K ohms resistor.
Therefore, the default voltage on the center pin is zero.
However, the other four joystick terminals are not pulled down.
If these pins are neither pulled up nor pulled down internally, their voltage is un-deterministic.
Their default voltage may be high or low, depending on history usage.
We can use external interrupts to monitor whether the joystick is pressed or not.
Each pin can independently trigger an interrupt request signal.
Specifically, software can configure the external interrupt controller, such that PA 0 triggers
external interrupt 0, PA 1 triggers external interrupt 1, PA 5 triggers external interrupt
5, PA 2 triggers external interrupt 2, and finally, PA 3 triggers external interrupt 3.
In the next slide, I will show you how to select the source of external interrupts.
Both external circuit and the microcontroller can supply a voltage signal on a pin.
The external interrupt controller monitors the change of the voltage signal.
The rising or falling edge of the voltage signal can make the external interrupt controller
generate an interrupt request.
The interrupt request will be sent to the NVIC.
The external interrupt controller supports 16 external interrupts associated with GPIO pins.
These interrupts are named from external interrupt 0 to external interrupt 15.
Each of these interrupts is associated with one specific GPIO pin.
However, a processor has more than 16 GPIO pins.
How does the controller map GPIO pins to external interrupts?
STM32 takes a simple approach.
Specifically, only pins with the pin number x can be the source of external interrupt x.
For example, the source of external interrupt 3 can be PA 3, PB 3, PC 3, PD 3, etc.
The source selection bits in the SYSCFG external interrupt configuration register (EXTICR)
specifies which pin will be selected as external interrupt source.
Pay attention.
No multiple pins from this group can be used as the external interrupt source simultaneously.
For example, if the pin PA 3 has an external interrupt on it, we cannot use the pins PB
3 or PC 3 as the source for external interrupt 3.
In summary, the controller has one multiplexer for each of these 16 external interrupts.
The microcontroller has a total of 16 multiplexers.
As shown here, x is from 0 to 15.
A multiplexer, also called MUX, is a simple circuit.
It selects one of its inputs and forwards the selected input to the output.
The concept of interrupt vector table has been presented in the previous lecture.
There are five dedicated interrupt handlers for the first five external interrupts, including
external interrupt 0, external interrupt 1, external interrupt 2, external interrupt 3,
and external interrupt 4.
For example, pin PA 3 can be mapped to external interrupt 3, and its corresponding interrupt
handler is EXTI_3_IRQHandler.
External interrupts from number 5 to 9, share the same interrupt handler, EXTI_9_5_IRQ Handler.
External interrupts from number 10 to 15, share the same interrupt handler, EXTI_15_10_IRQHandler.
This is the basic diagram of the external interrupt controller.
The controller supports two types of external interrupts: configurable external interrupts,
and direct external interrupts.
Configurable external interrupts include those associated with GPIO, RTC, comparators, power
voltage detector (PVD), and peripheral voltage monitoring (PVM).
For these interrupts, the controller has a programmable edge detector, and software can
select which active edge generate an interrupt request.
An interrupt can be triggered on rising, falling, or both edges.
In addition, software can generate an interrupt request by writing 1 to the software interrupt
event register (SWIER).
For direct external interrupts, only rising edge can generate an interrupt request.
Direct external interrupts are mostly used for communication peripherals, low-power timer,
and LCD.
An interrupt can only be generated, if the corresponding bit in the interrupt mask register
is 1.
The interrupt signal can pass this AND gate if and only if the bit from the IMR register
is 1.
Now, let's work on the software part.
If we press the up button of the joystick, software turns on the LED.
The up button is connected to GPIO pin PA 3, which can generate the external interrupt
request 3.
Here is the main function.
First of all, software must enable the clock of GPIO port A. The constant GPIOAEN is defined
in the device header file.
This bitwise OR operation sets the least significant bit to 1 in the AHB2ENR register.
As result, the clock signal can pass through this logic AND gate and drive the circuit
of port A. Then, software configures the mode of pin
PA 3 as digital input.
This is achieved by clearing two bits in the mode register, corresponding to pin 3.
Specifically, we clear bit 6 and bit 7 in the mode register of GPIO Port A.
As discussed previously, pin PA 3 is neither pulled up nor pulled down externally.
It was connected to the ground via a capacitor.
If the processor does not pull it down internally, the voltage on pin PA 3 is floating.
Its voltage can be high or low, if the up button is not pressed down.
Therefore, the processor has to pull the pin down internally.
This is to ensure that, the voltage on pin PA 3 is low under the normal state.
Here are two lines of C code, which sets PA 3 as pull down.
Next, we enable external interrupt 3 by calling the function NVIC_EnableIRQ().
Pin 3 in all ports can generate, external interrupt 3.
These three lines of C code select PA 3 as the source of external interrupt 3.
When PA 3 is selected, the other pins, such as PB 3, PC 3, PD 3, etc., cannot be used
to generate external interrupts.
Under normal state, the voltage on pin PA 3 is low.
When the up button is pressed down, the voltage on PA 3 is raised to high.
When the up button is released, the voltage on pin PA 3 becomes low.
This waveform makes two transitions, and has a rising edge and a falling edge.
In this example, we select the rising edge as the active edge to trigger external interrupts.
Then, software sets the corresponding bit to 1 in the interrupt mask register in order
to enable the interrupt request.
At the end of the main function, we put a dead loop.
After the program perform the initialization of GPIO and external interrupt, the processor
will execute this dead loop forever.
The next important code is the interrupt handler for external interrupt 3.
When the up button is pressed down, the rising edge of the voltage on pin PA 3 triggers external
interrupt 3.
After receiving the interrupt request, the NVIC controller forces the processor to execute
the interrupt handler EXTI3_IRQHandler().
One of the most common mistakes many people make, is that, the interrupt handler does
not clear the interrupt status or pending flag before it exits.
If the interrupt handler does not clear the interrupt pending flag, the interrupt handler
will be executed repeatedly by mistake.
Please visit the book website for tutorials, and project templates.