Detailed explanation of STM32 gpio external interrupt

What are interrupts?

Interrupting the CPU from executing a normal program, switching to an emergency program, and then returning to the original suspended program to continue running is called an interrupt

The role and significance of interruptioninsert image description here

Significance of interruption: Efficiently handle emergency programs without occupying CPU resources all the time

STM32 GPIO external interrupt diagram

insert image description here

NVIC

What are NVICs? NVIC is the nested vectored interrupt controller, the full name is Nested vectored interrupt controller. It
is the core device.
M3/M4/M7 cores support 256
interrupts, including 16 system interrupts and 240 external interrupts, and have 256 levels of programmable interrupt settings. However, chip
manufacturers generally will not use up all these resources of the core. For example, STM32F407 has 10 system interrupts and
82 external interrupts. insert image description here
About the 82 external interrupts, there is a detailed
list in Section 10.2 of "STM32F4xx Reference Manual_V4 (Chinese Version).pdf", so it will not be listed here. The interrupt vector table of STM32F407 is defined in the stm32f407xx.h file.

NVIC register

NVIC related register definition can be found in core_cm4.h file.
We directly analyze the NVIC-related registers through the definition of the program , which are defined as follows:

typedef struct
{
    
    
  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
        uint32_t RESERVED0[24U];
  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
        uint32_t RSERVED1[24U];
  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
        uint32_t RESERVED2[24U];
  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
        uint32_t RESERVED3[24U];
  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
        uint32_t RESERVED4[56U];
  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
        uint32_t RESERVED5[644U];
  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
}  NVIC_Type;

The STM32F407 interrupts are executed sequentially under the control of these registers. Only by understanding these interrupt registers can
the interrupts of STM32F407 be used conveniently. The following highlights these registers:
ISER[8]: The full name of ISER is: Interrupt Set Enable Registers, which is an interrupt enable register group. It is mentioned above
that the CM4 core supports 256 interrupts, which are controlled by 8 32-bit registers, and each bit controls an interrupt. But
STM32F407 has only 82 maskable interrupts at most, so for us, two (ISER[0~3]) are useful, which
can represent 128 interrupts in total. The STM32F407 only uses 82 of them. Bit0~31 of ISER[0] corresponds to interrupt
0~31; bit0~31 of ISER[1] corresponds to interrupt 32~63; bit0~16 of ISER[2] corresponds to interrupt 64~81, so a total of 82 interrupts can
be corresponding to each other. If you want to enable an interrupt, you must set the corresponding ISER bit to 1 to enable the interrupt
(this is only to enable, but also to cooperate with interrupt grouping, masking, IO port mapping and other settings to be considered a complete interrupt setting ).
For which interrupt each bit corresponds to, please refer to line 68 in stm32f407xx.h.
ICER[8]: The full name is: Interrupt Clear Enable Registers, which is an interrupt disable register group. The function of this register group
is just opposite to that of ISER, and it is used to clear the enable of an interrupt. The function of its corresponding bit is also the same as ISER.
Here, it is necessary to set an ICER to clear the interrupt bit, instead of writing 0 to ISER to clear it, because
writing 1 to these registers of NVIC is valid, and writing 0 is invalid.
ISPR[8]: The full name is: Interrupt Set Pending Registers, which is an interrupt enable pending control register group.
The interrupt corresponding to each bit is the same as ISER . Set to 1 to suspend an ongoing interrupt and execute
an interrupt of the same level or higher. Writing 0 has no effect.
ICPR[8]: The full name is: Interrupt Clear Pending Registers, which is an interrupt release control register group. Its function
is opposite to ISPR, and the corresponding bit is the same as ISER. By setting 1, the suspended interrupt can be unsuspended. Writing 0 has no effect.
APR[8]: The full name is: Interrupt Active Bit Registers, which is an interrupt activation flag bit register group.
The interrupt represented by the corresponding bit is the same as ISER, if it is 1, it means that the interrupt corresponding to this bit is being executed. This is a read-only register
, through which you can know which interrupt is currently being executed. It is automatically cleared by hardware after the interrupt is executed.
IP [240]: The full name is: Interrupt Priority Registers, which is a register group for interrupt priority control. This register
set is very important! The interrupt grouping of STM32F407 is closely related to this register group. The IP register group consists of 240 8-bit
registers, and each maskable interrupt occupies 8 bits, so that a total of 240 maskable interrupts can be represented. The STM32F407
only uses 82 of them. IP[81]~IP[0] correspond to interrupt 81~0 respectively. The 8 bits occupied by each maskable interrupt are not
used entirely, but only the upper 4 bits are used. These 4 bits are further divided into preemptive priority and sub-priority. The preemption priority comes first, and the sub
-priority comes after. How many bits each of these two priorities occupy depends on the interrupt grouping settings in SCB->AIRCR. The register group for interrupt
priority control will be explained in detail below.

interrupt priority

The interrupt priority in STM32 can be divided into: preemptive priority and response priority. Response priority is also called sub-priority.
Each interrupt source needs to be assigned these two priorities. The difference between preemptive priority and response priority:

Preemptive priority: An interrupt with a high preemptive priority can interrupt an ongoing interrupt with a low preemptive priority.
Response priority: the preemptive priority is the same, interrupts with high priority cannot interrupt interrupts with low priority
.
Another situation is that when two or more interrupts have the same preemptive priority and response priority, then follow the
natural priority, see the interrupt sorting of the interrupt vector table, the smaller the value, the higher the priority.

In the NVIC, there are 60 registers, NVIC_IPR0-NVIC_IPR59, to control the interrupt priority. Every 8 bits of each register are divided into one group, which can be divided into four groups, so there are 240 groups of interrupt priority control registers with a width of 8 bits. , in principle, the configurable priority of each external interrupt is 0~255, the smaller the value, the higher the priority. But in fact, in order to simplify the design, the M3/M4/M7 chip only uses the upper four bits [7:4], and the lower four bits are zero, so that there are only 16 levels of interrupt nesting at most, that is, 2^4=16.
insert image description here
Through this table, we can clearly see the configuration relationship corresponding to groups 0~4. For example, if the priority group is set to 3, then for all
82 interrupts at this time, the upper four bits of each interrupt's interrupt priority register The highest 3 bits are the preemption priority, and
the lower 1 bit is the response priority. For each interrupt, you can set the preemption priority to 0~7, and the response priority to 1 or 0. Preemption priority
is a higher level than response priority. The smaller the value, the higher the priority.
Let’s illustrate with an example: Assume that the interrupt priority group is set to 2, and then the
preemptive priority of interrupt 3 (RTC_WKUP interrupt) is set to 2, and the response priority is 1. The preemptive priority of interrupt 6 (external interrupt 0) is 3, and the response priority is 0.
The preemptive priority of interrupt 7 (external interrupt 1) is 2, and the response priority is 0. Then the priority order of these 3 interrupts is:
Interrupt 7>Interrupt 3>Interrupt 6.
Both interrupt 3 and interrupt 7 in the above example can interrupt the interrupt of interrupt 6. However, interrupt 7 and interrupt 3 cannot
interrupt each other!

NVIC related functions

ST company encapsulates the NVIC-related functions of the core_cm4.h file into the stm32f4xx_hal_cortex.c file, and
the more commonly used functions are listed below.

1. HAL_NVIC_SetPriorityGrouping function

HAL_NVIC_SetPriorityGrouping is to set interrupt priority grouping function. Its declaration is as follows:
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
⚫ Function description:
used to set interrupt priority grouping.
⚫ Function formal parameter:
formal parameter 1 is the interrupt priority group number, which can be selected from NVIC_PRIORITYGROUP_0 to
NVIC_PRIORITYGROUP_4 (5 groups in total).
⚫ Function return value: None
⚫ Note:
This function is basically only called once in a project, and it has already been called in the program HAL library initialization function
, and will not be called later. Because when subsequent calls are set to different interrupt priority groups, it may cause a
mismatch between the previously set preemption priority and the response priority.

2. HAL_NVIC_SetPriority function

void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority,
uint32_t SubPriority);
⚫ Function description:
used to set the interrupt preemption priority and response priority (subpriority).
⚫ Function parameter:
Parameter 1 is the interrupt number, and the range can be selected: the enumeration type defined by IRQn_Type, defined in stm32f407xx.h.
Formal parameter 2 is the preemption priority, which can be selected from 0 to 15.
Formal parameter 3 is the response priority, which can be selected from 0 to 15.

3. HAL_NVIC_EnableIRQ function

id HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
⚫ Function description:
used to enable interrupt.
⚫ Function parameter:
Parameter 1 is the interrupt number, and the range can be selected: the enumeration type defined by IRQn_Type, defined in stm32f407xx.h.
⚫ Function return value: None

4. HAL_NVIC_DisableIRQ function

HAL_NVIC_DisableIRQ is the interrupt disable function. Its declaration is as follows:
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
⚫ Function description:
used to disable interrupt.
⚫ Function parameter: None
⚫ Function return value: None

5. HAL_NVIC_SystemReset function

HAL_NVIC_SystemReset is the system reset function. Its declaration is as follows:
void HAL_NVIC_SystemReset(void);
⚫ Function description:
used for software reset system.
⚫ Function parameter: None
⚫ Function return value: None

Introduction to EXTI

EXTI is the external interrupt and event controller, which is composed of 20 edge detectors that generate event/interrupt requests. Each
input line can independently configure the input type (pulse or suspend) and the corresponding trigger event (rising edge or falling edge or
both edge triggers). Each input line can be shielded independently. The pending register holds the status line interrupt requests.

insert image description here
It can be seen from the EXTI function block diagram that there are two main lines, one is from the input line to the NVIC interrupt controller, and the other is from the
input line to the pulse generator. This is precisely the two major functions of EXTI, generating interrupts and generating events, which
are different from the hardware.

Let's take a look at the circuit that generates interrupts in the EXTI functional block diagram, and the final signal flows into the NVIC controller. The input line is the information input terminal of the line, which can be set to any GPIO port or some peripheral events through the configuration register. Input lines are generally signals with level changes.

Label ①: ==== is an edge detection circuit, including edge detection circuit, rising edge trigger selection register (EXTI_RTSR) and
falling edge trigger selection register (EXTI_FTSR). The edge detection circuit uses the input line as the signal input terminal. If an
edge transition is detected, it will output a valid signal '1', and then output a valid signal '1' to the circuit marked ②, otherwise it will input an invalid signal '0'.
The standard of edge transition is the setting of the corresponding bit of the rising edge trigger selection register or falling edge trigger selection register at the beginning. For the
setting of the corresponding bit, please refer to Table 16.1.2.1.
Label ②: is an OR gate circuit, and its two signal input terminals are the software interrupt event register (EXTI_SWIER) and the input signal of the edge detection circuit respectively. As long as there is a signal '1' at the input of the OR gate circuit, it will output '1', so it will output '1' to the circuit marked ③ and the circuit marked ④.
The interrupt/ event line can be started by reading and writing the software interrupt event register , which is equivalent to outputting a valid signal '1' to the input terminal of the OR gate circuit.
Label ③: It is an AND gate circuit, and its two signal input terminals are the interrupt mask register (EXTI_IMR) and the output signal of the label ② circuit. The AND gate circuit requires all inputs to be '1' to output '1'. In this case, if the interrupt mask register (EXTI_IMR) is set to 0, regardless of the signal characteristics output from the label ② circuit, the final label ③ circuit output All signals
are 0; if the interrupt mask register (EXTI_IMR) is set to 1, the output signal of the final label ③ circuit is
determined by the output signal of the label ② circuit, so that the purpose of interrupt can be achieved simply by controlling EXTI_IMR. Label ④ outputting
'1' will set the corresponding position of the request pending register (EXTI_PR) to 1.
Finally, the content of the request pending register (EXTI_PR) is output to the NVIC to realize the control of the system interrupt event.
Next, let's look at the circuit that generates events in the EXTI functional block diagram. The event generation line is different from the interrupt line after label 2, and the previous lines are all shared. Label ④ is an AND gate, the input terminal comes from the circuit labeled 2 and from the event mask register (EXTI_EMR). If the EXTI_EMR register is set to 0, no matter whether the output signal of the label 2 circuit is '0' or '1', the output of the final label 4 is '0'; if the EXTI_EMR register is set to 1, the output signal of the final label ④ circuit is determined by the label ③The signal output by the circuit is determined, so that EXTI_EMR can be simply controlled to achieve the purpose of whether to generate an event.
Label ④: When the circuit outputs a valid signal 1, it will make the pulse generator circuit generate a pulse, while an invalid signal will not make it generate a pulse signal. Pulse signal generation can be used by other peripheral circuits, such as timers, analog-to-digital converters, etc. Such pulse signals are generally used to trigger TIM or ADC to start conversion.

The purpose of generating an interrupt line is to input the input signal to the NVIC, and further run the interrupt service function to realize the function. The purpose of generating
event lines is to transmit a pulse signal to other peripherals, which is a hardware-level function.
EXTI supports 23 external interrupt/event requests, these are information input terminals, that is, the input lines mentioned above are
as follows:
EXTI line 0~15: corresponding to the input interrupt of the external IO port
EXTI line 16: connected to PVD output
EXTI Line 17: Connect to RTC alarm event
EXTI Line 18: Connect to USB wake event
EXTI Line 19: Connect to Ethernet wake event
EXTI Line 20: Connect to USB OTG HS (configured in FS) wake event
EXTI Line 21: Connect to RTC Intrusion and Timestamp Event
EXTI Line 22: Connected to RTC Wakeup Event

It can be seen from the above that the STM32F407 has only 16 interrupt lines for the IO ports, but the IO
ports of the STM32F407 are far more than 16, so the STM32 uses the GPIO pins GPIOx.0~GPIOx.15(x=A,B ,C,D,E,F,G) correspond to
interrupt lines 0~15 respectively. In this way, each interrupt line corresponds to a maximum of 7 IO ports. Take line 0 as an example: it corresponds to GPIOA.0,
GPIOB.0, GPIOC.0, GPIOD.0, GPIOE.0, GPIOF.0 and GPIOG. 0. The interrupt line can only be connected to one
IO port at a time, so it needs to be configured to determine which GPIO the corresponding interrupt line is configured to.

How to use interrupts

insert image description here

STM32 EXTI configuration steps (external interrupt)

insert image description here

STM32 EXTI HAL library setting steps (external interrupt)

insert image description here

Generic Peripheral Driver Model (Four-Step Method)

insert image description here

Guess you like

Origin blog.csdn.net/weixin_45172119/article/details/130185337