STM32 key interrupt

Preface

Interrupts were not used in the previous section. In this section, interrupts will be used. When the button is pressed, the interrupt is triggered. The interrupt is handled in the interrupt service function.

1. NVIC Nested Vectored Interrupt Controller

NVIC is a nested vector interrupt controller, which controls interrupt related functions in the entire chip, and is a peripheral in the core.
The interrupt vector in the manual: divided into system interrupt and peripheral interrupt. The red frame is the system interrupt, there are 10. There are more than 60 peripheral interrupts, and the picture only shows a small part.
Insert picture description here
Insert picture description here

Priority definition: In
principle, the configurable priority of each external interrupt is 0~255, the smaller the value, the higher the priority. Priorities are grouped into preemptive priority and sub-priority. If multiple interrupts respond at the same time, the preemption priority will be executed first. If the preemption priority is the same, compare the sub-priority. If the sub-priority is the same, compare the hardware interrupt number, which is the Pritorty number in the figure above. The smaller the number, the higher the priority.

The priority groups are as follows:
Insert picture description here
NVIC-related functions in the firmware library

//设置分组优先级
void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
//获取分组优先级
uint32_t NVIC_GetPriorityGrouping(void)

//中断使能
void NVIC_EnableIRQ(IRQn_Type IRQn)
//中断失效
void NVIC_DisableIRQ(IRQn_Type IRQn)
//获取中断
uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
//设置中断
void NVIC_SetPendingIRQ(IRQn_Type IRQn)
//清除中断
void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
//设置中断优先级
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
//获取中断优先级
uint32_t NVIC_GetPriority(IRQn_Type IRQn)

Interrupt programming steps :
1) Set peripheral interrupts, such as serial port transceiver interrupts;
2) Initialize the NVIC_InitTypeDef structure;

typedef struct
{
    
    
  uint8_t NVIC_IRQChannel;//中断源,参考IRQn_Type 
  uint8_t NVIC_IRQChannelPreemptionPriority; //中断优先级 参考NVIC_Priority_Table 
  uint8_t NVIC_IRQChannelSubPriority;//中断子优先级NVIC_Priority_Table 
  FunctionalState NVIC_IRQChannelCmd; //This parameter can be set either to ENABLE or DISABLE   
} NVIC_InitTypeDef;

3) Interrupt service function

2. EXIT external interrupt controller

EXIT (External interrupt/event controller) external interrupt/event controller. Each interrupt/event line corresponds to an edge detector, which can detect the rising edge and falling edge of the input signal. The input line is generally a signal with a level change. EXIT can be divided into two categories, one is to generate an interrupt, and the other is to generate an event. The interrupt is directly given to the NVIC to further realize the interrupt. Interrupt events are delivered to peripheral circuits, such as ADC and timer TIM.

Insert picture description here
EXTI has 20 interrupt/event lines. Each GPIO can be set as an input line, occupying EXTI0 to EXTI15, and there are seven other lines for specific peripheral events. The relationship between input source and interrupt/event is as follows
Insert picture description here

Insert picture description here
Configure external interrupts/events on the GPIO line through AFIO_EXTICRx
Insert picture description here

EXIT structure:

typedef struct
{
    
    
  uint32_t EXTI_Line;  /* 中断/事件线,EXTI0-EXTI19 combination of @ref EXTI_Lines */
  EXTIMode_TypeDef EXTI_Mode;/* 模式选择@ref EXTIMode_TypeDef */
  EXTITrigger_TypeDef EXTI_Trigger; /* 触发选择,上升沿,下降沿,上升沿和下降沿 @ref EXTIMode_TypeDef */
  FunctionalState EXTI_LineCmd;  /* 是否使能ENABLE or DISABLE */ 
}EXTI_InitTypeDef;

3. External interruption experiment

Use the external button as the trigger source to make the controller generate an interrupt, and realize the task of controlling the lighting in the interrupt service function. The GPIO corresponding to the button KEY1 uses PA0, EXTI corresponds to the EXTI0 interrupt line; NVIC corresponds to the EXTI0_IRQn interrupt source.

Insert picture description here

1) Initialize the GPIO used to generate interrupts

2) Initialize EXTI

3) Configure NVIC

4) Write interrupt service function

head File

#include "stm32f10x.h"

#define KEY1_INT_GPIO_PORT         GPIOA//组 PA
#define KEY1_INT_GPIO_CLK          (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)//时钟需要开启AFIO 配置中断 APB2
#define KEY1_INT_GPIO_PIN          GPIO_Pin_0//引脚

#define KEY1_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOA//端口
#define KEY1_INT_EXTI_PINSOURCE    GPIO_PinSource0//引脚
#define KEY1_INT_EXTI_LINE         EXTI_Line0//中断线
#define KEY1_INT_EXTI_IRQ          EXTI0_IRQn//中断源中断/事件
#define KEY1_IRQHandler            EXTI0_IRQHandler//中断服务函数

Configure EXTI, GPIO that generates interrupt

void EXTI_Key_Config(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure; 
	EXTI_InitTypeDef EXTI_InitStructure;
	/*时钟设置*/
	RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);											
	/* NVIC中断*/
	NVIC_Configuration();	
	/*按键使用的GPIO*/
  GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
  /* 浮空 */	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
	/* 选择EXTI信号源 Selects the GPIO pin used as EXTI Line */
  GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); 
  /*中断事件*/
  EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
	/* 中断模式*/
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	/* 触发模式,上升沿*/
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  /* 使能 */	
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
}

The configuration of the external interrupt register GPIO_EXTILineConfig function is used to specify the input source of the interrupt/event line. It actually sets the AFIO_EXTICRx value of the external interrupt configuration register. This function receives two parameters. The first parameter specifies the GPIO port source, the second The parameter is to select the corresponding GPIO pin source number.

Configure NVIC

static void NVIC_Configuration(void)
{
    
    
  NVIC_InitTypeDef NVIC_InitStructure;
  /*优先级选择,组1 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  /* 中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
  /* 主优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /*子优先级*/
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /*使能中断*/
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  //初始化
  NVIC_Init(&NVIC_InitStructure);
}

Interrupt service function

void KEY1_IRQHandler(void)
{
    
    
  //获取中断线EXTI line状态
	if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) 
	{
    
    
		//翻转LED灯	
		LED1_TOGGLE;
		EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);     
	}  
}

Guess you like

Origin blog.csdn.net/WANGYONGZIXUE/article/details/115280667