【stm32f407】External interrupt to realize key interrupt mode

Publisher:世界因你而精彩Latest update time:2018-07-20 Source: eefocusKeywords:stm32f407 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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


Keywords:stm32f407 Reference address:【stm32f407】External interrupt to realize key interrupt mode

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

Summary of driver modification errors for STM32F407 Ethernet external clock source
In the sample code: void ETH_GPIO_Config(void) {      GPIO_InitTypeDef GPIO_InitStructure;     /* Enable GPIOs clocks */     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |                          RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE |                          RCC_AHB1Periph _GPIOG, ENABL
[Microcontroller]
STM32F405 and STM32F407CAN configuration
The CAN configurations of STM32F405 and STM32F407 are slightly different. The difference is that 407 has an additional level pull-up and pull-down mode, so be sure to pay attention to this when configuring. Secondly, to open CAN2, CAN1 must be opened, because CAN1 is the master and CAN2 is the slave; after opening the
[Microcontroller]
STM32F407 implements matrix keyboard program
I'm working on a project related to buttons recently, and I use a matrix keyboard. There are few programs related to matrix keyboards on the Internet, so I wrote one and posted it for your reference. The GPIO ports used in the program are PD0--PD7. As for the principle of the matrix keyboard, I won't describe it one b
[Microcontroller]
STM32F407 advanced timer dead zone complementary PWM (operation register)
There are many functions of the advanced timer, and here we only introduce the dead zone complementary PWM output function. In fact, the dead zone complementary PWM is not much different from the PWM configuration of the general timer, except that it is necessary to set several bits in the multi-CCER register and the
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号