STM32L476 Memory Map Overview
STM32L476 Memory Map Overview
1
The STM32L476 Memory Map
Memory Address Size
Main Flash Memory Bank 1 0x0800 000-0x0807 FFFF 512 KB
Main Flash Memory Bank 2 0x0808 000-0x080F FFFF 512 KB
SRAM2 0x1000 000-0x1000 7FFF 32 KB
System Memory Bank 1 (Flash) 0x1FFF 0000-0x1FFF 6FFF 28 KB
OTP (one-time programmable) 0x1FFF 7000-0x1FFF 73FF 1 KB
Option bytes (Flash) Bank 1 0x1FFF 7800 - 0x1FFF 780F 16 B
System Memory Bank 2 (Flash) 0x1FFF 8000 - 0x1FFF EFFF 28 KB
Option bytes (Flash) Bank 2 0x1FFF F800 - 0x1FFF F80F 16 B
SRAM1 0x2000 000-0x2001 7FFF 96 KB
2
General Purpose Input/Output (GPIO)
8 GPIO Ports:
Port E
Port A A, B, C, D, E, F, G, H
Port F
Port B Up to 16 pins in each port
Port G
Port C
Port H
Port D
STM32L4
3
General Purpose Input/Output (GPIO)
8 GPIO Ports:
A, B, C, D, E, F, G, H
Up to 16 pins in each
port
4
General Purpose Input/Output (GPIO)
D Bus
ARM Cortex- FLASH
AHB Bus
I Bus
Matrix
M4 SRAM
S Bus
FPU
GPIO A
GPIO B APB Bus
GPIO C Matrix
GPIO D
GPIO E UART
GPIO F
GPIO G SPI
GPIO H
Timer
…
STM32L4
5
The STM32L476 General-purpose inputs/outputs
Eachof the General-purpose inputs/output (GPIO) pins can
be configured by software:
as output (push-pull or open-drain)
as input (with or without pull-up or pull-down)
as peripheral alternate function
Most of the GPIO pins are shared with digital or analog
alternate functions.
FastI/O toggling can be achieved thanks to their mapping on
the AHB2 bus.
6
The STM32L476 AHB/APB bridges
The two AHB/APB bridges provide full synchronous connections between the
AHB and the two APB buses, allowing flexible selection of the peripheral
frequency.
After each device reset, all peripheral clocks are disabled (except for the
SRAM1/2 and Flash memory interface).
Before using a peripheral you have to enable its clock in the following resisters:
RCC_AHB1ENR
RCC_AHB2ENR
RCC_AHB3ENR
RCC_APB1ENR1
RCC_APB1ENR2
RCC_APB2ENR
7
The STM32L476 peripheral clock enable
registers
Flash
ART
Memory
Advanced High-
performance
Bus (AHB1)
TSC CRC
Direction Memory
Access Controllers
DMA1
DMA2
8
The STM32L476 peripheral clock enable
registers
USB OTG
AHB2
9
The STM32L476 peripheral clock enable
registers
10
The STM32L476 peripheral clock enable
registers
TIM2 USART4
TIM3 USART5
TIM4 I2C1/SMBUS
TIM5 I2C2/SMBUS
TIM6 I2C3/SMBUS
TIM7 CAN1
LCD PWR
AHB Bus Matrix RTC DAC1
WWDG OpAmp
SPI2 LPTIM1
Flash SPI3 LPUART1
ART USART2 SWPMI1
Memory
USART3 LPTIM2
Advanced High-
performance APB1
Bus (AHB1) AHB to APB Bridge 1
AHB to APB Bridge 2
ABP2
TSC CRC
11
The STM32L476 peripheral clock enable
registers
TIM2 USART4
TIM3 USART5
TIM4 I2C1/SMBUS
TIM5 I2C2/SMBUS
TIM6 I2C3/SMBUS
TIM7 CAN1
LCD PWR
AHB Bus Matrix RTC DAC1
WWDG OpAmp
SPI2 LPTIM1
Flash SPI3 LPUART1
ART USART2 SWPMI1
Memory
USART3 LPTIM2
Advanced High-
performance APB1
Bus (AHB1) AHB to APB Bridge 1
AHB to APB Bridge 2
ABP2
TSC CRC
12
The STM32L476 peripheral clock enable
registers
Advanced High-
TSC CRC
VREF USART1
COMP1 TIM15
COMP2 TIM16
Firewall TIM17
SDIO/MMC1 SAI1
TIM1/PWM SAI2
SPI1 DFSDM
TIM8/PWM EXTI/WKUP
13
The STM32L476 Memory organization
14
The STM32L476 Memory organization
15
The STM32L476 Memory organization
16
The STM32L476 Memory organization
17
Interfacing Peripherals
Port-mapped I/O
Use special CPU instructions: Special_instruction Reg, Port
Memory-mapped I/O
Most CPUs these days do I/O via memory mapped I/O
A simpler and more convenient way to interface I/O devices
Each device registers is assigned to a memory address in the address space of the
microprocessor
Use native load/store instructions to input or output data: LDR/STR Reg, [Reg, #imm]
When you write to this “special memory location”, the data you write,
is sent to, the corresponding I/O device
0x4800002
4
0x4800002
0
Core Pin output
STR 0x4800001
C GPIO
0x4800001 Output
8
GPIOSpace
0x4800001Memory Data Output Register
18
4
ARM0x4800001
Cortex-M microprocessors use memory-mapped I/O.
Memory Map of Cortex-M4: Peripheral region
0xFFFFFFFF
0.5 GB System The peripheral region covers the memory
0xE0000000
addresses of all on-chip peripherals, such as
GPIO, timers, USART, SPI, and ADC.
1 GB External Device
0x60000000
0.5 GB Peripheral
0x40000000
0.5 GB SRAM
0x20000000
0.5 GB Code
0x00000000
…
1 GB External RAM
0x48001000
GPIO D (1 KB)
0x60000000 0x48000C00
0.5 GB Peripheral GPIO C (1 KB)
0x40000000 0x48000800
GPIO B (1 KB)
0.5 GB SRAM 0x48000400
0x20000000 GPIO A (1 KB)
0.5 GB Code 0x48000000
0x40000000
…
0x00000000
ASCR
Within this 48-byte memory region, the GPIO mode register 0x4800002C
MODER, is mapped to the lowest memory address, and the BRR
0x48000028
GPIO analog switch control register, ASCR, is mapped to
0x48000024
AFR[1]
the highest memory address.
AFR[0]
0x48000020
0x48000400 LCKR
0x4800001C
GPIO A (1 KB) BSRR
0x48000000 0x48000018 48 bytes
0x48000014
ODR
IDR
0x48000010
PUPDR
0x4800000C
OSPEEDR
0x48000008
0x48000004
OTYPER
MODER
0x48000000
21
Each register has 4 bytes.
GPIO A Memory Map
0x48000400
Suppose we want to set the output of
pin 14 of Port A to high.
To achieve this, we need to set bit 14
of the output data register (ODR) of ASCR
0x4800002C
GPIO A, to 1. BRR
0x48000028
0x48000024
AFR[1]
AFR[0]
0x48000020
0x48000400 LCKR
0x4800001C
GPIO A (1 KB) BSRR
0x48000000 0x48000018 48 bytes
0x48000014
ODR
IDR
0x48000010
PUPDR
Set pin A.14 to high 0x4800000C Set bit 14
OSPEEDR
0x48000008 of ODR
0x48000004
OTYPER to high
MODER
0x48000000
22
Output Data Register (ODR)
0x48000017
ODR 1 word (i.e. 32 bits)
0x48000014
0x48000017
0x48000016
4 bytes
0x48000015
0x48000014
Little Endian
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1
lUL is an
*((uint32_t *) 0x48000014) |= 1UL<<14; unsigned long
integer with a
value of 1
23 Dereferencing a pointer Bitwise OR
The STM32L476 Address of peripheral
registers
#define PERIPH_BASE ((uint32_t)0x40000000U)
24
The STM32L476 peripheral registers: GPIOB
25
The STM32L476 peripheral registers: GPIOB
In memory-mapped I/O, all registers of a GPIO port, are mapped to a
contiguous block of physical memory. This memory block can be
ASCR represented by using a struct.
0x4800042C
BRR typedef struct {
0x48000428 volatile uint32_t MODER; // Mode register
0x48000424
AFR[1] volatile uint32_t OTYPER; // Output type register
volatile uint32_t OSPEEDR; // Output speed register
AFR[0]
0x48000420 volatile uint32_t PUPDR; // Pull-up/pull-down
LCKR register
0x4800041C volatile uint32_t IDR; // Input data register
BSRR volatile uint32_t ODR; // Output data register
0x48000418 volatile uint32_t BSRR; // Bit set/reset register
0x48000414
ODR volatile uint32_t LCKR; // Configuration lock
IDR register
0x48000410 volatile uint32_t AFR[2]; // Alternate function
PUPDR registers
0x4800040C volatile uint32_t BRR; // Bit Reset register
OSPEEDR volatile uint32_t ASCR; // Analog switch control
0x48000408
0x48000404
OTYPER register
} GPIO_TypeDef;
MODER
0x48000400 // Casting memory address to a pointer
#define
[Link]
Let's ((GPIO_TypeDef *) 0x48000400)
We use a macro definition here to give a name to the struct pGPIOB->ODR |= 1UL<<14;
name the macro GPIOA. To set bit 14, we can use the membership
operator to access the data output register ODR. We can either use the
arrow operator, or the dot operator, to access the output data register ODR. or(*pGPIOB).ODR |= 1UL<<14;
26
The STM32L476 peripheral registers: GPIOB
typedef struct {
volatile uint32_t MODER; // Mode register
volatile uint32_t OTYPER; // Output type register
volatile uint32_t OSPEEDR; // Output speed register
volatile uint32_t PUPDR; // Pull-up/pull-down register
volatile uint32_t IDR; // Input data register
volatile uint32_t ODR; // Output data register
volatile uint32_t BSRR; // Bit set/reset register
volatile uint32_t LCKR; // Configuration lock register
volatile uint32_t AFR[2]; // Alternate function registers
volatile uint32_t BRR; // Bit Reset register
volatile uint32_t ASCR; // Analog switch control register
} GPIO_TypeDef;
GPIOB->ODR |= 1UL<<14;
27
Exception
A special event that requires the CPU to stop normal program execution
and perform some service related to the event.
Examples of exceptions include
I/O completion, timer time-out, end of conversion,
illegal opcodes, arithmetic overflow, divide-by-0.
28
Exception
29
Software Interrupt
Software can also generate interrupt signals by setting the interrupt
pending registers or by using special instructions.
There are two major usages of software interrupt:
exception handling
privileged hardware access
30
Software Interrupt: Exception Handling
When exceptional conditions occur during execution, such as division by
zero, illegal opcode, and invalid memory access, the processors should
handle these abnormal situations to potentially correct software errors.
The processor can capture two software faults, including division by
error and unaligned memory access, if software enables these fault
capture features. A software interrupt invoked by software faults is often
referred to as a trap.
31
Software Interrupt: Privileged Hardware Access
When a user application runs in unprivileged mode and needs to
access a hardware resource that is only accessible in privileged mode,
a special instruction svc (supervisor call) generates a software
interrupt and makes the processor switch from the unprivileged mode
to the privilege mode.
32
The STM32L476 Nested vectored interrupt controller (NVIC)
The NVIC hardware block provides flexible interrupt
management features with minimal interrupt latency
33
Nested vectored interrupt controller (NVIC)
Up to 240 interrupts
81 maskable interrupt channels
16 programmable priority levels (4 bits of interrupt priority are used)
A programmable priority level of 0-15 for each interrupt.
A higher level corresponds to a lower priority, so level 0 is the highest
interrupt priority.
Grouping of priority values into group priority and subpriority fields
34
The STM32L476 Nested vectored interrupt controller (NVIC)
handle up to 82 maskable interrupt channels
handle the 16 interrupt lines of the Cortex®-M4
manage 16 priority levels
Interrupt entry vector table address passed directly to the core
Allows early processing of interrupts
Processing of late arriving higher priority interrupts
Support for tail chaining
Processor state automatically saved on interrupt entry, and
restored on interrupt exit, with no instruction overhead.
35
Nested vectored interrupt controller (NVIC)
Level and pulse detection of interrupt signals
Interrupt tail-chaining
An external Non-maskable interrupt (NMI)
Low-latency exception and interrupt handling
Power management control
Implementation of System Control Registers
36
The STM32L476 Extended interrupt/event controller (EXTI)
Generation of up to 40 event/interrupt requests
26 configurable lines
14 direct lines
Independent mask on each event/interrupt line
Configurable rising or falling edge (configurable lines only)
Dedicated status bit (configurable lines only)
Emulation of event/interrupt requests (configurable lines only)
37
EXTI main features
38
The STM32L476 Extended interrupt/event controller (EXTI)
40 edge detector lines used to generate interrupt/event
requests and wake-up the system from Stop mode.
41
Extended interrupts and events controller (EXTI) block
diagram
42
Extended interrupts and events controller (EXTI) block
diagram
43
Event vs Interrupt
Interrupts will typically be used to execute a few lines of code by the ARM
core (NVIC, interrupt handlers, etc.).
Events don't necessary execute code but can signal another peripheral to
do something without processor intervention.
45
External Interrupt (EXTI) Controller
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.
EXTI main features
The interrupt/event lines are either configurable or direct:
The configurable lines: the active edge can be chosen independently,
and a status flag indicates the source of the interrupt. The
configurable lines are used by the I/Os external interrupts, and by few
peripherals.
The direct lines: they are used by some peripherals to generate a
wakeup from Stop event or interrupt. The status flag is provided by the
peripheral.
47
External Interrupt (EXTI) Controller
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.
Also, software can trigger EXTI interrupts by writing to the EXTI
software interrupt event register (EXTI_SWI ER1,2).
External Interrupt (EXTI) Controller
For direct external interrupts, only rising edge can generate an interrupt
request.
50
EXTI main features
51
EXTI main features
Generation of up to 40 event/interrupt requests
26 configurable lines
14 direct lines
Independent mask on each event/interrupt line
Configurable rising or falling edge (configurable lines only)
Dedicated status bit (configurable lines only)
Emulation of event/interrupt requests (configurable lines only)
52
Configure and enable interrupt lines
Program the two trigger registers with the desired edge detection.
Enable the interrupt request by writing a ‘1’ to the corresponding bit in
the interrupt mask register.
When the selected edge occurs on the interrupt line, an interrupt
request is generated. The pending bit corresponding to the interrupt line
is also set.
This request is cleared by writing a ‘1’ in the pending register.
For the direct interrupt lines, the interrupt is enabled by default in the
interrupt mask register and there is no corresponding pending bit in the
pending register.
53
Configure and enable events
program the two trigger registers with the desired edge detection.
enable the event request by writing a ‘1’ to the corresponding bit in the
event mask register.
When the selected edge occurs on the event line, an event pulse is
generated.
The pending bit corresponding to the event line is not set.
For the configurable lines, an interrupt/event request can also be
generated by software by writing a ‘1’ in the software interrupt/event
register.
54
External Interrupt
The external interrupt controller supports 16 external interrupts,
named EXTI0, EXTI1, ..., EXTI15.
Each of these interrupts is only associated with one specific GPIO pin.
55
NVIC register summary
Name Description
56
Interrupt Number in CMSIS Library
Interrupt number defined in ARM software library
System Peripheral interrupt
Exceptions Interrupts number
-16 -1 0 239
CMSIS Interrupt Number
First 16 are system exceptions
CMSIS defines their interrupt numbers as negative
Defined by ARM core
The rest 240 are peripheral interrupts
Peripheral interrupt number starts with 0.
Defined by chip manufacturers.
57
Interrupt Number in CMSIS Library
Interrupt number defined in ARM software library
System Peripheral interrupt
Exceptions Interrupts number
-16 -1 0 239
CMSIS Interrupt Number
A Cortex M microcontroller supports up to 256 interrupts. Each interrupt, except the interrupt reset,
has an interrupt number.
The first 16 interrupts are system interrupts, also called system exceptions. Exceptions are the
interrupts that come from the core. CMSIS defines all system exceptions by using negative values.
58
Interrupt Number in CMSIS Library
Interrupt number defined in ARM software library
System Peripheral interrupt
Exceptions Interrupts number
-16 -1 0 239
CMSIS Interrupt Number
The rest 240 interrupts are peripheral interrupts, also called non-system exceptions. The peripheral
interrupt number starts with 0.
This number scheme allows software to easily distinguish system exceptions and peripheral
interrupts.
Peripheral interrupts are defined by chip manufacturers. The total number of peripheral interrupts
supported varies among chips.
59
Interrupt Number in CMIS Library
For a given microprocessor, the definition of the interrupt numbers is usually given in its device
header file.
stm32l476xx.h
This is the interrupt number definition for STM32L4 Cortex-M4 microprocessors. It includes
negative values for system exceptions, and non-negative values for peripheral interrupts.
60
Interrupt Number in CMIS Library
/****** Cortex-M4 System Exceptions
********************************************************/
NonMaskableInt_IRQn = -14, /* 2 Cortex-M4 Non Maskable Interrupt
*/
HardFault_IRQn = -13, /* 3 Cortex-M4 Hard Fault Interrupt
*/ System
MemoryManagement_IRQn = -12, /* 4 Cortex-M4 Memory Management Exceptions
Interrupt
*/
Defined by ARM
BusFault_IRQn = -11, /* 5 Cortex-M4 Bus Fault Interrupt
*/
UsageFault_IRQn = -10, /* 6 Cortex-M4 Usage Fault Interrupt
*/
SVCall_IRQn = -5, /* 11 Cortex-M4 SV Call Interrupt
*/
DebugMonitor_IRQn = -4, /* 12 Cortex-M4 Debug Monitor Interrupt
*/
PendSV_IRQn = -2, /* 14 Cortex-M4 Pend SV Interrupt
*/
SysTick_IRQn = -1, /* 15 Cortex-M4 System Peripheral
Tick Interrupt
Interrupts
*/
Defined by chip vendor
/****** Peripheral Interrupt Numbers
*******************************************************/
61 WWDG_IRQn = 0, /*stm32l476xx.h
Window WatchDog Interrupt
*/
Interrupt Number in CMIS Library
62
Interrupt Number in CMSIS vs in PSR
Interrupt number in Program Status Register (PSR)
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Thumb state flag GE[3:0]: Greater or equal flags (only available on Cortex-M4 and M7)
Overflow flag
Carry/Borrow flag
Zero flag
63
Interrupt Number in CMSIS vs in PSR
Several CMSIS functions use the interrupt number as an input parameter, such as the
function of NVIC disable interrupt, and NVIC enable interrupt. NVIC stands for Nested Vector
Interrupt Controller.
On the other hand, when an interrupt is serviced, the current interrupt or exception number is
recorded in the program status register (PSR). However, the definition of interrupt numbers in
PSR is different from the definition of interrupt number in CMSIS functions.
Specifically, interrupt number of PSR equals 16 plus the interrupt number for CMSIS.
In this lecture, when we say interrupt number, we mean the interrupt number defined for
CMSIS.
64
Interrupt Number
Interrupt number defined in ARM software library
System Peripheral interrupt
Exceptions Interrupts number
-16 -1 0 239
CMSIS Interrupt Number
65
Enable an Interrupt
Enable a system exception
Some system exceptions, such as reset and hard fault, cannot be disabled.
They are always enabled
No centralized registers for enabling/disabling
Each are control by its corresponding components, such as SysTick module
66
Enable Peripheral Interrupts
We can enable a peripheral interrupt by writing 1 to the corresponding bit of the
NVIC_ISER0-NVIC_ISER7 registers.
Note that, write 0 to a bit in a NVIC_ISER register does not disable the corresponding
interrupt.
67
Enabling Peripheral Interrupts
68
Enable Peripheral Interrupts
Example: we will show how to enable the interrupt Timer 7.
The interrupt number of Timer 7 is 44 for STM32L processor.
To enable interrupt 44, we need to set bit 12 of NVIC_ISER1 to 1.
TIM5_IRQn = 44
NVIC->ISER[1] = 1 << 12; // Enable Timer 7
interrupt
69
Enable Peripheral Interrupts
Example: we will show how to enable the interrupt Timer 5.
The following C program can enable a peripheral interrupt whose interrupt number is
IRQn. Bit j in register NVIC_ISER i enables interrupt IRQn = j + 32 x i
70
Disable/Enable Peripheral Interrupts
For all peripheral interrupts: IRQn ≥ 0
Method 1:
NVIC_EnableIRQ (IRQn); // Enable interrupt
NVIC_DisableIRQ (IRQn); // Disable interrupt
Method 2:
Enable:
NVIC->ISER[ IRQn / 32] = 1 << (IRQn % 32);
Better solution:
NVIC->ISER[ IRQn >> 5] = 1 << (IRQn & 0x1F);
Disable:
NVIC->ICER[ IRQn >> 5] = 1 << (IRQn & 0x1F);
71
Interrupt Priority
Inverse Relationship:
Lower priority value means higher urgency.
Priority of Interrupt A = 5,
Priority of Interrupt B = 2,
B has a higher priority/urgency than A.
For example, STM32L4 processors implement four priority bits, which are
placed as the most significant bits of the priority byte.
By default, the preempt priority has the upper two bits, and the sub-priority
has the lower two bits.
default setting
74
Interrupt Priority
The preempt priority defines whether an interrupt can preempt an already
executing interrupt.
default setting
75
Interrupt Priority
The sub priority determines which interrupt will be handled first, when two
interrupts of the same preempt priority arrive at the same time.
That is to say, the sub priority is used, only when two interrupts with the same
preempt priority value are pending. Specifically, the interrupt with the lower
sub priority value will be handled first.
default setting
76
Interrupt Priority
The priority bits are divided into two parts, including preempt priority and sub priority.
By default, the preempt priority has the upper two bits, and the sub-priority has the lower two
bits.
However, the number of bits assigned to each part is configurable using PRIGROUP bits (bits
8-10) of AIRCR register.
77
Preemption and Sub-priority
Configuration
NVIC_SetPriorityGrouping(n)
Perform unlock, and update AIRCR register
Default
n=2
78
Interrupt Priority
Interrupt priority is configured by Interrupt Priority Registers (NVIC_IPR0-
NVIC_IPR59)
The NVIC_IPRx (x = 0 to 59) byte-accessible registers provide 8-bit priority
fields IP[N] (N = 0 to 239) for each of the 240 interrupts.
Every register holds four IP[N] fields of the CMSIS interrupt priority array, as
shown in Figure.
79
Interrupt Priority
IP[N] (N = 0 to 239) consists of two fields, including preempt priority
number and sub-priority number.
The preempt priority number defines the priority for preemption.
The sub-priority number determines the order when multiple interrupts are pending with
the same preempt priority number.
default setting
80
Interrupt Priority
For a peripheral interrupt IRQn, its priority can be set as follows. Note that the
interrupt priority (IP) array is defined as an array of bytes, not words.
81
Interrupt Priority
Figure 11-9 shows the memory layout of interrupt priority registers for the
first 16 peripheral interrupt.
82
Interrupt Priority
Interrupt priority is configured by Interrupt Priority Registers (NVIC_IPR0-
NVIC_IPR59)
0 1 1 0 0 0 0 0
NVIC->IP[7] = (6 << 4) & 0xff;
IP = 0x60 = 96
83
Priority of System Interrupts
FAULTMASK: Like PRIMASK but change the current priority level to -1,
so that even hard fault handler is blocked
BASEPRI: Disable interrupts only with priority lower than a certain level
Example, disable all exceptions with priority level higher than 0x60
MOV R0, #0x60
MSR BASEPRI, R0
85
Global Interrupt Enable and Disable
Besides using NVIC to configure individual interrupts, the Cortex-M
processors also allow us to enable and disable a group of interrupts.
86
Global Interrupt Enable and Disable
87
Global Interrupt Enable and Disable
you can change the value of PRIMARK register using CPS (Change Processor
State) instructions.
The PRIMASK register can also be accessed using the MRS and MSR instructions.
Note that MOV or MOVS cannot access these special registers.
Instruction Action Equivalent
Disable interrupts & MOVS R0, #1
CPSID I configurable fault MSR PRIMASK, R0 ; Write 1 to PRIMASK
handlers ; to disable all interrupts
MOVS R0, #1
Disable interrupts and all
CPSID F MSR FAULTMASK, R0 ; Write 1 to FAULTMASK
fault handlers
; to disable all interrupts
Enable interrupts and MOVS R0, #0
CPSIE I configurable fault MSR PRIMASK, R0 ; Write 0 to PRIMASK to
handlers ; allow all interrupts
MOVS R0, #0
Enable interrupts and fault
CPSIE F MSR FAULTMASK, R0 ; Write 0 to FAULTMASK
handlers
; to allow all interrupts
88
Masking Priority
In embedded systems, we often have to perform some critical
operations, in which data should not be corrupted by other interrupts.
Therefore, we need to disable all interrupts with less urgency to ensure
that the execution of the critical code will not be interrupts by other
interrupts.
We can use the Base Priority Mask Register (BASEPRI) to achieve the
protection of critical code.
89
Masking Priority
The BASEPRI register defines the minimum priority for exception
processing.
When BASEPRI is set to a nonzero value, it prevents the activation of all
exceptions with the same or lower priority level as the BASEPRI value.
90
Masking Priority
When the base priority mask register (BASEPRI) is non-zero, all interrupts
with a priority value higher than or equal to BASEPRI are disabled.
In this case, we also say that interrupts with a priority value lower than
BASEPRI are unmasked (i.e., enabled).
A larger priority value represents lower priority (i.e., lower urgency).
91
Masking Priority
Disable all interrupts with less urgency
For critical code, only certain interrupts are allowed.
BASEPRI: Disable all interrupts of specific priority level or higher priority level
In this example, we disable all interrupts with a priority value of 5 or higher.
After executing the critical code, we can remove the interrupt masking by
resetting the BASEPRI register to zero
// Disable interrupts with priority value same or
higher
__set_BASEPRI( 5 << 4 )
// Critical code
...
93
Vector Table
94
Automatic Stacking & Unstacking
Interrupt
Exit
Interrupt Handler
Interrupt
Unstacking
Signal
95
Automatic Stacking & Unstacking
96
Vector Table
For a given interrupt or exception number i defined in CMSIS, the
memory address of its corresponding ISR or exception hander is:
Address of ISR = 4 + 4 x (i+15)
The interrupt vector table is stored at the memory address
0x00000004.
Because each entry in the table represents a memory address, each
entry takes four bytes in memory.
97
Vector Table
For example, the interrupt number of SysTick is -1, the memory address of
SysTick_Handler can be founding by reading the word stored at the following
address.
…
13 0x00000074 DMA1_Channel3_IRQHandler
Vector Table 12
11
10
0x00000070
0x0000006C
0x00000068
DMA1_Channel2_IRQHandler
DMA1_Channel1_IRQHandler
EXTI4_IRQHandler
void DMA1_Channel1_IRQHandler () {
}
...
…
9 0x00000064 EXTI3_IRQHandler void EXTI1_Handler () {
...
8 0x00000060 EXTI2_IRQHandler }
7 0x0000005C EXTI1_IRQHandler
void EXTI0_Handler () {
6 0x00000058 EXTI0_IRQHandler ...
}
5 0x00000054 RCC_IRQHandler
4 0x00000050 FLASH_IRQHandler
3 0x0000004C RTC_WKUP_IRQHandler
…
2 0x00000048 TAMPER_STAMP_IRQHandler
1 0x00000044 PVD_IRQHandler
0 0x00000040 WWDG_IRQHandler
void SysTick_Handler () {
-1 0x0000003C SysTick_Handler ...
}
-2 0x00000038 PendSV_Handler
-3 0x00000034 Reserved
…
-4 0x00000030 DebugMon_Handler
void SVC_Handler () {
-5 0x0000002C SVC_Handler ...
}
-6 0x00000028 Reserved
-7 0x00000024 Reserved
…
-10 0x00000018 UsageFault_Handler
99
Vector Table
Address Priority
Interrupt Acronym Description
Number Type of priority
0x0000 002C 3 -5 settable SVC_Handler System service call via SWI instruction
100
Vector Table
Address Priority
Interrupt Type of Acronym Description
Number priority
0x0000
7 0 settable WWDG Window Watchdog interrupt
0040
0x0000 PVD/PVM1/PVM2/PVM3/PVM4 through
8 1 settable PVD_PVM
0044 EXTI lines 16/35/36/37/38 interrupts
…
…
0x0000 009C 30 23 settable EXTI9_5 EXTI Line[9:5] interrupts
…
0x0000 00E0 47 40 settable EXTI15_10 EXTI Line[15:10] interrupts
101
Interrupt Vector Table
Interrupt Number Memory Address of ISR
(8 bits) (32 bits)
... ...
EXTI0_IRQn = 6 EXTI0_IRQHandler
EXTI1_IRQn = 7 EXTI1_IRQHandler
EXTI2_IRQn = 8 EXTI2_IRQHandler
EXTI3_IRQn = 9 EXTI3_IRQHandler
EXTI4_IRQn = 10 EXTI4_IRQHandler
... ...
EXTI9_5_IRQn = 23 EXTI9_5_IRQHandler
... ...
EXTI15_10_IRQn = 40 EXTI15_10_IRQHandler
... ...
102
Extended interrupts and events controller (EXTI) block
diagram
103
EXTI main features
The extended interrupts and events controller (EXTI) manages the
external and internal asynchronous events/interrupts and generates the
event request to the CPU/Interrupt Controller and a wake-up request to the
Power Controller.
104
Event vs Interrupt
Interrupts will typically be used to execute a few lines of code by the ARM
core (NVIC, interrupt handlers, etc.).
Events don't necessary execute code but can signal another peripheral to
do something without processor intervention.
107
External Interrupt (EXTI) Controller
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.
Also, software can trigger EXTI interrupts by writing to the EXTI
software interrupt event register (EXTI_SWI ER1,2).
External Interrupt (EXTI) Controller
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.
Peripherals asynchronous Interrupts
Some peripherals are able to generate events when the system is in run
mode and also when the system is in Stop mode, allowing to wake up
the system from Stop mode.
To accomplish this, the peripheral generates both a synchronized (to the
system clock, e.g. APB clock) and an asynchronous version of the
event. This asynchronous event is connected to an EXTI direct line.
110
EXTI main features
111
EXTI main features
Generation of up to 40 event/interrupt requests
26 configurable lines
14 direct lines
Independent mask on each event/interrupt line
Configurable rising or falling edge (configurable lines only)
Dedicated status bit (configurable lines only)
Emulation of event/interrupt requests (configurable lines only)
112
Configure and enable interrupt lines
Program the two trigger registers with the desired edge detection.
Enable the interrupt request by writing a ‘1’ to the corresponding bit in
the interrupt mask register.
When the selected edge occurs on the interrupt line, an interrupt
request is generated. The pending bit corresponding to the interrupt line
is also set.
This request is cleared by writing a ‘1’ in the pending register.
For the direct interrupt lines, the interrupt is enabled by default in the
interrupt mask register and there is no corresponding pending bit in the
pending register.
113
Configure and enable events
program the two trigger registers with the desired edge detection.
enable the event request by writing a ‘1’ to the corresponding bit in the
event mask register.
When the selected edge occurs on the event line, an event pulse is
generated.
The pending bit corresponding to the event line is not set.
For the configurable lines, an interrupt/event request can also be
generated by software by writing a ‘1’ in the software interrupt/event
register.
114
External Interrupt
The external interrupt controller supports 16 external interrupts,
named EXTI0, EXTI1, ..., EXTI15.
Each of these interrupts is only associated with one specific GPIO pin.
115
External Interrupt
The GPIO pins with the same pin number in all GPIO ports are
assigned to the same external interrupt.
In other words, only pins with the pin number k can be the source of
external interrupt EXTI k. For example, the processor can map GPIO
pin PA 0 to EXTI 0, PA 1 to EXTI 1, PA 2 to EXTI 2, and so on.
Also, there is only one external interrupt on all pins with the same
number out of all GPIO ports. For example, if the pin PA 3 has an
external interrupt on it, we cannot use the pins PB 3, PC 3, PD 3, or PE
3 as the external interrupt source.
116
External interrupt/event GPIO mapping
117
External interrupt/event GPIO mapping
118
External interrupt/event GPIO mapping
119
External Interrupt: SYSCFG_EXTICR1
SYSCFG external interrupt configuration register 1
The bits of this register are written by software to select the source input
for the EXTI0-EXTI3 external interrupts.
120
External Interrupt: SYSCFG_EXTICR2
SYSCFG external interrupt configuration register 2
The bits of this register are written by software to select the source
input for the EXTI4-EXTI7 external interrupts.
121
External Interrupt: SYSCFG_EXTICR3
SYSCFG external interrupt configuration register 3
The bits of this register are written by software to select the source
input for the EXTI8-EXTI11 external interrupts.
122
External Interrupt: SYSCFG_EXTICR4
SYSCFG external interrupt configuration register 4
The bits of this register are written by software to select the source input
for the EXTI12-EXTI15 external interrupts.
123
External interrupt/event GPIO mapping
124
External interrupt/event GPIO mapping
The GPIOs are connected to 16
configurable interrupt/event lines.
125
Hardware interrupt selection
To configure a line as an interrupt source, use the following procedure:
1. Configure the corresponding mask bit in the EXTI_IMR1 or EXTI_IMR2
register.
2. Configure the Trigger Selection bits of the Interrupt line (EXTI_RTSR1 and
EXTI_FTSR1) or (EXTI_RTSR2 and EXTI_FTSR2).
3. Configure the enable and mask bits that control the NVIC IRQ channel
mapped to the EXTI so that an interrupt coming from one of the EXTI lines can
be correctly acknowledged.
126
Hardware event selection
To configure a line as an event source, use the following procedure:
1. Configure the corresponding mask bit in the EXTI_EMR1 or EXTI_EMR2
register.
2. Configure the Trigger Selection bits of the Event line (EXTI_RTSR1 and
EXTI_FTSR1) or (EXTI_RTSR2 and EXTI_FTSR2).
127
Software interrupt/event selection
Any of the configurable lines can be configured as a software
interrupt/event line. The procedure to generate a software interrupt is as
follows:
1. Configure the corresponding mask bit (EXTI_IMR1, EXTI_EMR1,
EXTI_IMR2, EXTI_EMR2).
2. Set the required bit of the software interrupt register (EXTI_SWIER1,
EXTI_SWIER2).
128
EXTI registers
Register Keil Operation
Interrupt Mask on line x (x = 0 to 31)
Interrupt mask
EXTI->IMR1 0: Interrupt request from Line x is masked
register (EXTI_IMR1)
1: Interrupt request from Line x is not masked
Event Mask on line x (x = 0 to 31)
Event mask register
EXTI->EMR1 0: Event request from Line x is masked
(EXTI_EMR1)
1: Event request from Line x is not masked
Rising trigger event configuration bit of line x (x = 0 to 16 and
Rising trigger
18 to 22)
selection register 1 EXTI->RTSR1
0: Rising trigger disabled (for Event and Interrupt) for input line
(EXTI_RTSR1)
1: Rising trigger enabled (for Event and Interrupt) for input line
Falling trigger event configuration bit of line x (x = 0 to 16 and
Falling trigger
18 to 22)
selection register 1 EXTI->FTSR1
0: Falling trigger disabled (for Event and Interrupt) for input line
(EXTI_FTSR1)
1: Falling trigger enabled (for Event and Interrupt) for input line
Software interrupt on line x (x = 0 to 16 and 18 to 22)
If the interrupt is enabled on this line in the EXTI_IMR1, writing a
Software interrupt
'1' to this bit when it is at '0' sets the corresponding pending bit
event register 1 EXTI->SWIER1
in EXTI_PR1 resulting in an interrupt request generation.
(EXTI_SWIER1)
This bit is cleared by clearing the corresponding bit of EXTI_PR1
(by writing a ‘1’ into the bit)
Pending interrupt flag on line x (x = 0 to 16 and 18 to 22)
0: No trigger request occurred
Pending register 1
EXTI->PR1 1: Selected trigger request occurred
(EXTI_PR1)
This bit is set when the selected edge event arrives on the
129 interrupt line. This bit is cleared by writing a ‘1’ to the bit.
EXTI registers
Register Keil Operation
Interrupt Mask on line x (x = 32 to 40)
Interrupt mask
EXTI->IMR2 0: Interrupt request from Line x is masked
register (EXTI_IMR2)
1: Interrupt request from Line x is not masked
Event Mask on line x (x = 32 to 40)
Event mask register
EXTI->EMR2 0: Event request from Line x is masked
(EXTI_EMR2)
1: Event request from Line x is not masked
Rising trigger Rising trigger event configuration bit of line x (x = 35 to 38)
selection register 2 EXTI->RTSR2 0: Rising trigger disabled (for Event and Interrupt) for input line
(EXTI_RTSR2) 1: Rising trigger enabled (for Event and Interrupt) for input line
Falling trigger Falling trigger event configuration bit of line x (x = 35 to 38)
selection register 2 EXTI->FTSR2 0: Falling trigger disabled (for Event and Interrupt) for input line
(EXTI_FTSR2) 1: Falling trigger enabled (for Event and Interrupt) for input line
Software interrupt on line x (x = 35 to 38)
If the interrupt is enabled on this line in the EXTI_IMR2, writing a
Software interrupt
'1' to this bit when it is at '0' sets the corresponding pending bit
event register 2 EXTI->SWIER2
in EXTI_PR2 resulting in an interrupt request generation.
(EXTI_SWIER2)
This bit is cleared by clearing the corresponding bit of EXTI_PR2
(by writing a ‘1’ into the bit)
Pending interrupt flag on line x (x = 35 to 38)
0: No trigger request occurred
Pending register 2
EXTI->PR2 1: Selected trigger request occurred
(EXTI_PR2)
This bit is set when the selected edge event arrives on the
interrupt line. This bit is cleared by writing a ‘1’ to the bit.
130
EXTI registers
131
EXTI registers
132
EXTI registers
133
EXTI registers
134
EXTI registers
135
EXTI registers
136
EXTI registers
137
EXTI registers
138
External Interrupt
139
External Interrupt
140
External Interrupt
141
GPIO pin k as the EXTI k
1. Enable the clock of SYSCFG and corresponding GPIO port.
2. Configure the GPIO pink as input.
3. Set up the SYSCFG external interrupt configuration register
(SYSCFG_EXTICR1,2,3,4) to map the GPIO pin k to the external
interrupt input line k.
4. Select the active edge that can trigger EXTI k. The signal can be a
rising edge, a falling edge or both. This is programmed via the rising
edge trigger selection register (EXTI_RTSR1 or EXTI_RTSR2) and the
falling edge trigger selection register (EXTI_FTSR1 or EXTI_FTSR2).
142
GPIO pin k as the EXTI k
5. Enable EXTI k by setting the kth bit in EXTI interrupt mask register
(EXTI_IMR1 or EXTI_IMR2) . An interrupt can only be generated if the
corresponding bit in the interrupt mask register is 1 (or called unmasked).
6. Enable interrupt EXTI k on NVIC controller via NVIC_EnableIRQ.
7. Write the interrupt handler for EXTI k. The EXTI pending register (EXTI_PR1
or EXTI_PR2) records the source of the interrupt. The function name of the
interrupt handler is given by the startup assembly file startup_stm32l476xx.s.
For example, the handler for EXTI 3 is called EXTI3_IRQHandler().
8. In the interrupt handler, software needs to clear the corresponding pending
bit to indicate the current request has been handled. Surprisingly, writing it to 1
clears a pending bit.
143
GPIO PA.3 as the EXTI3
Example shows the code of the external interrupt handler of EXTI 3, which
toggles an LED when PA 3 triggers an external interrupt.
144
GPIO PA.3 as the EXTI3
One mistake that new programmers often make is that interrupt handlers do
not clear interrupt pending flags.
If the interrupt handler does not clear an interrupt pending flag after processing
the interrupt, the microcontroller would mistakenly think another interrupt
request has arrived and then repeatedly execute the interrupt handler.
145
GPIO PA.3 as the EXTI3
First of all, software must enable the clock of GPIO port A.
// Pull PA.3 down internally; Trigger on rising
edge The RCC_ AHB2ENR_GPIOAEN is defined in the device header file
int main(void) {
// Enable GPIO Clock //stm32l476xx.h
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; #define RCC_AHB2ENR_GPIOAEN
// GPIO Mode: Input(00), Output (01), ((uint32_t)0x00000001U)
// AF(10), Analog (11)
GPIOA->MODER &= ~3U << 6;
// GPIO Push-Pull: No pull-up, pull-down (00), AHB2 peripheral clock enable register (AHB2ENR)
// Pull-up (01), Pull-down (10), Reserved
(11)
GPIOA->PUPDR &= ~3U << 6;
GPIOA->PUPDR |= 2U << 6; // Pull down
NVIC_EnableIRQ(EXTI3_IRQn); // Enable
Interrupt
146 while(1);
}
GPIO PA.3 as the EXTI3
Then, software configures, the mode of pin PA.3, as digital input.
// Pull PA.3 down internally; Trigger on rising
edge
This is achieved by clearing, two bits in the
int main(void) { mode register, corresponding to pin 3.
// Enable GPIO Clock
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; Specifically, we clear bit 6, and bit 7, in the
// GPIO Mode: Input(00), Output (01),
// AF(10), Analog (11, default) mode register of GPIO Port A
GPIOA->MODER &= ~3U << 6;
// GPIO Push-Pull: No pull-up, pull-down (00),
// Pull-up (01), Pull-down (10), Reserved
(11)
GPIOA->PUPDR &= ~3U << 6;
GPIOA->PUPDR |= 2U << 6; // Pull down Digital Input
Mode bits =
NVIC_EnableIRQ(EXTI3_IRQn); // Enable 00
Interrupt 01 Digital Output
// Connect External Line to the GPI
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; 10
SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR1_EXTI3; Alternative
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PA; GPIO Pin 11 Function
// Interrupt Mask Register
// 0 = marked, 1 = not masked (enabled) Analog
EXTI->IMR1 |= EXTI_IMR1_IM3;
147 while(1);
}
GPIO PA.3 as the EXTI3
The processor has to pull the pin down internally.
// Pull PA.3 down internally; Trigger on rising
edge
int main(void) {
// Enable GPIO Clock
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
// GPIO Mode: Input(00), Output (01),
// AF(10), Analog (11)
GPIOA->MODER &= ~3U << 6; +3.3V
// GPIO Push-Pull: No pull-up, pull-down (00),
// Pull-up (01), Pull-down (10), Reserved
(11) 100Ω
GPIOA->PUPDR &= ~3U << 6;
GPIOA->PUPDR |= 2U << 6; // Pull down Processor Chip Input Pin
PA.3 Joy_up
NVIC_EnableIRQ(EXTI3_IRQn); // Enable Input
Interrupt
Pull down
// Connect External Line to the GPI resistor
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR1_EXTI3;
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PA;
148 while(1);
}
GPIO PA.3 as the EXTI3
We enable external interrupt 3, by calling the function, NVIC_EnableIRQ.
// Pull PA.3 down internally; Trigger on rising
edge
int main(void) {
// Enable GPIO Clock
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
// GPIO Mode: Input(00), Output (01),
// AF(10), Analog (11)
GPIOA->MODER &= ~3U << 6;
// GPIO Push-Pull: No pull-up, pull-down (00), Nested-Vectored
// Pull-up (01), Pull-down (10), Reserved
(11) Interrupt Controller
GPIOA->PUPDR &= ~3U << 6; PA.3 (NVIC)
EXTI3
Corte
NVIC
x-M4
GPIOA->PUPDR |= 2U << 6; // Pull down
NVIC_EnableIRQ(EXTI3_IRQn); // Enable
Interrupt
149 while(1);
}
GPIO PA.3 as the EXTI3
We select PA.3 as the source of external interrupt 3.
// Pull PA.3 down internally; Trigger on rising
edge
int main(void) { SYSCFG external
// Enable GPIO Clock interrupt configuration
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
// GPIO Mode: Input(00), Output (01), register
// AF(10), Analog (11) 000 (SYSCFG_EXTICR)
GPIOA->MODER &= ~3U << 6; PA.3 source selection
// GPIO Push-Pull: No pull-up, pull-down (00), 001
// Pull-up (01), Pull-down (10), Reserved PB.3
(11)
010
GPIOA->PUPDR &= ~3U << 6; PC.3
GPIOA->PUPDR |= 2U << 6; // Pull down
011
PD.3
NVIC_EnableIRQ(EXTI3_IRQn); // Enable
100 EXTI.3
Interrupt
PE.3
// Connect External Line to the GPI 101
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; PF.3
SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR1_EXTI3; 110
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PA; PG.3
111
// Interrupt Mask Register PH.3
// 0 = marked, 1 = not masked (enabled)
EXTI->IMR1 |= EXTI_IMR1_IM3;
150 while(1);
}
GPIO PA.3 as the EXTI3
We select the rising edge as the active edge, to trigger external interrupts.
// Pull PA.3 down internally; Trigger on rising
edge +3V
int main(void) {
// Enable GPIO Clock
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; 100Ω
// GPIO Mode: Input(00), Output (01),
// AF(10), Analog (11) Processor Chip
GPIOA->MODER &= ~3U << 6;
Input Pin Joy_up
// GPIO Push-Pull: No pull-up, pull-down (00), PA.3
// Pull-up (01), Pull-down (10), Reserved Input
(11)
GPIOA->PUPDR &= ~3U << 6; Pull down
resistor
GPIOA->PUPDR |= 2U << 6; // Pull down
NVIC_EnableIRQ(EXTI3_IRQn); // Enable
Interrupt
151 while(1);
}
GPIO PA.3 as the EXTI3
We set the corresponding bit to 1, in the IMR, in order to enable the interrupt request.
// Pull PA.3 down internally; Trigger on rising
edge
int main(void) {
// Enable GPIO Clock
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
// GPIO Mode: Input(00), Output (01),
// AF(10), Analog (11)
GPIOA->MODER &= ~3U << 6;
// GPIO Push-Pull: No pull-up, pull-down (00),
// Pull-up (01), Pull-down (10), Reserved
(11)
GPIOA->PUPDR &= ~3U << 6;
GPIOA->PUPDR |= 2U << 6; // Pull down
IMR
NVIC_EnableIRQ(EXTI3_IRQn); // Enable
Interrupt
AND
// Connect External Line to the GPI
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR1_EXTI3;
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PA;
152 while(1);
}
GPIO PA.3 as the EXTI3
software At the end of the main function, we put a dead loop.
// Pull PA.3 down internally; Trigger on rising
edge
int main(void) {
// Enable GPIO Clock
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
// GPIO Mode: Input(00), Output (01),
// AF(10), Analog (11)
GPIOA->MODER &= ~3U << 6;
// GPIO Push-Pull: No pull-up, pull-down (00),
// Pull-up (01), Pull-down (10), Reserved
(11)
GPIOA->PUPDR &= ~3U << 6;
GPIOA->PUPDR |= 2U << 6; // Pull down
NVIC_EnableIRQ(EXTI3_IRQn); // Enable
Interrupt
153 while(1);
}
Interrupt Service Routine (ISR)
void EXTI3_IRQHandler(void) {
if ((EXTI->PR1 & EXTI_PR1_PIF3) != 0) { EXTI3_IRQHandl
er unstacking
// Toggle LED stacking
...
while(1); while(1);
// Cleared flag by writing 1
EXTI->PR1 |= EXTI_PR1_PIF3;
} time
}
154
Extended interrupts and events controller (EXTI) block
diagram
155
Configurable lines in the EXTI of STM32L476 provide flexibility by allowing independent selection of the active edge (rising, falling, or both) for generating interrupts. Each line can be masked independently, which allows fine control over which external signals can trigger interrupts at any given time. Moreover, status flags and software-emulated requests add operational versatility, enabling dynamic reconfiguration of interrupt responses as different application states require .
The EXTI differentiates between events and interrupts such that interrupts typically involve executing a few lines of code, whereas events may trigger peripheral actions without processor intervention, e.g., using DMA to execute tasks. This separation allows critical tasks to run efficiently and reduce processor load, thus enhancing system efficiency by minimizing overhead for non-critical operations .
Manually triggering an EXTI interrupt involves writing a '1' to the EXTI software interrupt/event register (EXTI_SWIER). This operation might be necessary for testing or simulating hardware conditions without needing a physical event, allowing developers to verify interrupt handling logic and system responses outside of real environmental triggers .
The STM32L476 EXTI enhances interrupt handling efficiency by supporting up to 40 event/interrupt requests with 26 configurable lines and 14 direct lines. Each external line can independently choose trigger events (rising, falling, or both edges), which can also be masked independently. An interrupt request pending register maintains status, allowing for effective handling of requests. The STM32L476 can even detect pulse width shorter than the internal clock period .
Peripheral event generation in the EXTI affects the system's power management by enabling wake-ups from Stop modes. Peripherals can generate both synchronized and asynchronous versions of events during run and Stop modes, respectively. The asynchronous event capability ensures that the system only wakes when necessary, thereby conserving power especially when peripherals generate events that do not require processor intervention .
Configuring GPIO pins correctly is crucial for setting up external interrupts because improper configuration can prevent interrupts from being detected or cause incorrect executions. The mode, pull-up/down, and trigger selections determine how and when an interrupt is generated. For instance, failing to set a pin to the correct mode can prevent necessary signals from reaching the EXTI lines, leading to missed or spurious interrupts .
The EXTI handles rising edge detection differently by granting configurable lines the flexibility to choose between rising, falling, or both edges for interrupt generation via edge trigger registers. In contrast, direct external interrupt lines are restricted to generating interrupt requests on rising edges only, which is predefined and cannot be changed by software. This separation allows critical peripherals to wake the system reliably from Stop modes using standard triggers .
Tail-chaining is beneficial as it allows multiple interrupts to be handled with minimal latency by avoiding full processor state saving/restoring between consecutive interrupts. This mechanism leverages processor efficiency, reduces overhead, and ensures high-priority tasks are executed swiftly, thereby maintaining responsive system performance even under high interrupt loads .
The NVIC in STM32L476 is crucial for handling interrupts efficiently. It allows vector table addresses to be directly passed to the core, enabling early processing of interrupts with minimal latency. The NVIC also supports nested interrupts with automatic saving and restoring of processor state, enabling prioritization and tail-chaining of interrupts without instruction overhead. This leads to efficient processing of both high-priority and late-arriving interrupts .
A common pitfall for programmers is failing to clear interrupt pending flags after processing an interrupt. If a pending flag is not cleared, the microcontroller may incorrectly assume a new interrupt has occurred, leading to repeated execution of the interrupt handler. This can result in unintended behavior or system instability .