1. External interrupt
Each IO of STM32F4 can be used as an interrupt input port for external interrupts, which is also the strength of STM32F4. The interrupt controller of STM32F407 supports 22 external interrupt/event requests. Each interrupt has a status bit, and each interrupt/event has independent trigger and mask settings.
The 22 external interrupts of STM32F407 are:
EXTI lines 0~15: correspond to input interrupts of external IO ports.
EXTI line 16: Connect to PVD output.
EXTI line 17: connected to the RTC alarm event.
EXTI line 18: connected to USB OTG FS wake-up event.
EXTI line 19: Connected to Ethernet wake-up event.
EXTI line 20: connected to USB OTG HS (configured in FS) wake-up event.
EXTI line 21: Connected to RTC intrusion and timestamp events.
EXTI line 22: connected to RTC wake-up event.
As can be seen from the above, the STM32F4 has only 16 interrupt lines for IO ports, but the STM32F4 has far more than 16 IO ports. So how does the STM32F4 match the 16 interrupt lines to the IO ports one by one? So the STM32 is designed like this, and the GPIO management GPIOx.0~GPIOx.15 (x=A, B, C, D, E, F, G, H, I) corresponds to interrupt lines 0~15 respectively. In this way, each interrupt line corresponds to a maximum of 9 IO ports. Take line 0 as an example: it corresponds to GPIOA.0, GPIOB.0, GPIOC.0, GPIOD.0. The interrupt line can only be connected to one IO port at a time, so it is necessary to determine which GPIO the corresponding interrupt line is configured to through configuration. Let's take a look at the mapping relationship diagram between GPIO and interrupt lines
2. External interrupt application
There are several steps required to operate an interrupt:
1) Enable the IO port clock and initialize the IO port as input
First, we need to use the IO port as interrupt input, so we need to enable the corresponding IO port clock and initialize the corresponding IO port to input mode.
2) Turn on the SYSCFG clock and set the mapping relationship between the IO port and the interrupt line.
Next, we need to configure the mapping relationship between GPIO and interrupt line, so we need to turn on SYSCFG clock first. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//Enable SYSCFG clock Please note that as long as we use external interrupts, we must turn on SYSCFG clock.
Next, we configure the mapping relationship between GPIO and interrupt line. In the library function, the function SYSCFG_EXTILineConfig() that configures the mapping relationship between GPIO and interrupt line is implemented:
voidSYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);
This function maps the GPIO port to the interrupt line. The usage example is:
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
Mapping interrupt line 0 to GPIOA, it is obvious that GPIOA.0 is connected to EXTI1 interrupt line. After setting the interrupt line mapping, how is the interrupt from this IO port triggered? Next, we need to set the initialization parameters of the interrupt on the interrupt line.
3) Initialize online interrupts, set trigger conditions, etc.
The initialization of the interrupt on the interrupt line is implemented by the function EXTI_Init(). The definition of the EXTI_Init() function is
voidEXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
Below we use an example to illustrate the use of this function:
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line4;
EXTI_InitStructure.EXTI_Mode= EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd= ENABLE;
EXTI_Init(&EXTI_InitStructure); //Initialize the peripheral EXTI register
The above example sets the interrupt on interrupt line 4 to be triggered by the falling edge. The initialization of STM32 peripherals is done by setting the initial values through the structure. The process of structure initialization will not be explained here. Let's take a look at the member variables of the structure EXTI_InitTypeDef:
typedefstruct
{uint32_t EXTI_Line;
EXTIMode_TypeDefEXTI_Mode;
EXTITrigger_TypeDefEXTI_Trigger;
FunctionalStateEXTI_LineCmd;
}EXTI_InitTypeDef;
As can be seen from the definition, there are 4 parameters that need to be set. The first parameter is the label of the interrupt line. For our external interrupt, the value range is EXTI_Line0~EXTI_Line15. The concept of interrupt line has been mentioned above. In other words, this function configures the interrupt parameters on a certain interrupt line. The second parameter is the interrupt mode. The optional values are interrupt EXTI_Mode_Interrupt and event EXTI_Mode_Event. The third parameter is the trigger mode, which can be falling edge trigger EXTI_Trigger_Falling, rising edge trigger EXTI_Trigger_Rising, or any level (rising and falling edges) trigger EXTI_Trigger_Rising_Falling.
4) Configure the interrupt group (NVIC) and enable interrupts.
We set the interrupt line and GPIO mapping, and then set the interrupt trigger mode and other initialization parameters. Since it is an external interrupt, we must also set the NVIC interrupt priority. This has been explained before. Here we continue with the above example and set the interrupt priority of interrupt line 2.
NVIC_InitTypeDefNVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel= EXTI2_IRQn; //Enable key external interrupt channel
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //Preemption priority 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //Response priority 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable external interrupt channel
NVIC_Init(&NVIC_InitStructure); //Interrupt priority group initialization
5) Write the interrupt service function.
After we configure the interrupt priority, the next thing to do is to write the interrupt service function. The name of the interrupt service function is pre-defined in MDK. It should be noted here that the STM32F4 IO port has only 7 external interrupt functions, namely:
EXPORTEXTI0_IRQHandler
EXPORTEXTI1_IRQHandler
EXPORTEXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORTEXTI4_IRQHandler
EXPORTEXTI9_5_IRQHandler
EXPORTEXTI15_10_IRQHandler
Each interrupt line 0-4 corresponds to an interrupt function, interrupt lines 5-9 share the interrupt function EXTI9_5_IRQHandler, and interrupt lines 10-15 share the interrupt function EXTI15_10_IRQHandler. When writing interrupt service functions, two functions are often used. The first function is to determine whether an interrupt occurs on a certain interrupt line (whether the flag bit is set):
ITStatusEXTI_GetITStatus(uint32_t EXTI_Line);
This function is generally used at the beginning of the interrupt service function to determine whether an interrupt has occurred. Another function is to clear the interrupt flag on a certain interrupt line:
voidEXTI_ClearITPendingBit(uint32_t EXTI_Line);
This function is generally used to clear the interrupt flag before the end of the interrupt service function.
The commonly used interrupt service function format is:
voidEXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//Judge whether an interruption on a line occurs
{ ...interrupt logic...
EXTI_ClearITPendingBit(EXTI_Line3); //Clear the interrupt flag on LINE
}
}
It should be noted here that the firmware library also provides two functions to determine the external interrupt status and clear the external status flag, EXTI_GetFlagStatus and EXTI_ClearFlag, which are similar to the previous two functions. However, in the EXTI_GetITStatus function, it will first determine whether the interrupt is enabled, and then determine the interrupt flag if it is enabled, while EXTI_GetFlagStatus is used directly to determine the status flag.
At this point, I believe everyone has a certain understanding of STM32's IO port external interrupts. Let's summarize the general steps of using IO port external interrupts:
1) Enable the IO port clock and initialize the IO port as input.
2) Enable the SYSCFG clock and set the mapping relationship between the IO port and the interrupt line.
3) Initialize online interrupts, set trigger conditions, etc.
4) Configure the interrupt group (NVIC) and enable interrupts.
5) Write the interrupt service function.
Through the settings of the above steps, we can use external interrupts normally.
3. Original code analysis
This source code is an experiment to realize the user PA0 key trigger interrupt. When the terminal is detected, the LED will be always on and the monitor button will be printed.
Exit.h
#ifndef_EXIT_H_H_H
#define_EXIT_H_H_H
voidEXTIX_Init(void);
#endif
Exit.c
#include "exit.h"
#include "key.h"
#include "delay.h"
#include "uart.h"
#include "led.h"
voidEXTI0_IRQHandler(void)
{
delay_ms(10);
printf("monitor button\r\n");
LED_Operate(LED_ORANGE,LED_ON);
EXTI_ClearITPendingBit(EXTI_Line0); //Clear the interrupt flag on LINE0
}
void EXTIX_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
KEY_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode =EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel =EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Main,c
#include "led.h"
#include "key.h"
#include "delay.h"
#include "uart.h"
#include "exit.h"
void User_Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}
static int count = 0;
int main(void)
{
#if 1
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
My_USART2_Init();
delay_init(168); //Initialize delay function
LED_Init();
printf("http://blog.csdn.net/XiaoXiaoPengBo\r\n");
EXTIX_Init();
while(1);
#endif
}
4. Program Execution Diagram
According to the schematic diagram, the normal state of PA0 is low level.
After the key triggers the interrupt, it becomes a high level
There is one more thing to note here:
If the interrupt is triggered by the falling edge, this is the way: EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;
Then the interrupt will be entered at the moment the key is released
If the interrupt is triggered on the rising edge, this is the way: EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Rising;
Then it will enter the interruption at the moment of pressing
Previous article:STM32 peripheral interrupt configuration process
Next article:STM32_External interrupt button control to light up the LED
Recommended ReadingLatest update time:2024-11-16 17:37
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- F28335 learning ADC configuration
- Please recommend a step-down circuit
- C6000 Cache
- FPGA_100 Days_Binary to Decimal
- What parameters determine the emission distance of the infrared transmitter tube?
- Msp430PID control motor speed programming example
- A New Decision Feedback Equalizer Architecture Based on FPGA
- Reply and give points: 5G is coming, will you change to a 5G mobile phone?
- Application of ultra-high threshold voltage depletion-mode MOSFET DMZ0615E in mobile phone fast charging
- Forum member long521's niece is sick, please help her!