中断

概述

中断指的是 CPU 来处理和响应外部发生的异常,中断也就意味着打断,比如打断正在做的事,然后去处理一个紧急的事,处理完成后在继续做刚才没做完的事。

ARM Cortex M4 中断机制

当中断控制器通知 cpu,产生 xx 中断,这个时候,cpu 会停止正在做的事件,转到中断处理上来。而且,M4 给不同的事件(中断),一个唯一的中断编号(为了区分不同的中断事件)。当不同的中断事件产生时,cpu 作不同的处理。

任何中断产生到 cpu 响应,都要经过两个大的阶段:

  1. 中断源的控制
  2. 中断控制器的控制  NVIC

中断源的分析

中断源指的是中断发生的源头,中断源在内核中已经定义好了,也称为向量表

中断向量表:一个函数指针数组,保存不同中断事件处理函数的地址的数组 P234

NVIC 的概述

NVIC 指的是嵌套向量中断控制器,属于内核中的外设,作用是管理所有的中断,比如中断的使能或失能、中断的优先级.....。

  • 中断的使能与失能

    NVIC 管理中断通道的打开与关闭,可以把 NVIC 理解为所有中断的开关,想要使用中断发送中断请求,就必须提前打开中断的通道。关于 NVIC 的使用都存储在一个结构体中,这个结构体和 NVIC 的函数接口都定义在 misc.c 和 misc.h 中。

    /** 
      * @brief  NVIC Init Structure definition  
      */
    
    typedef struct
    {
      uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
                                                       This parameter can be an enumerator of @ref IRQn_Type 
                                                       enumeration (For the complete STM32 Devices IRQ Channels
                                                       list, please refer to stm32f4xx.h file) */
    
      uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel
                                                       specified in NVIC_IRQChannel. This parameter can be a value
                                                       between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
                                                       A lower priority value indicates a higher priority */
    
      uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified
                                                       in NVIC_IRQChannel. This parameter can be a value
                                                       between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
                                                       A lower priority value indicates a higher priority */
    
      FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
                                                       will be enabled or disabled. 
                                                       This parameter can be set either to ENABLE or DISABLE */   
    } NVIC_InitTypeDef;
    
  • 中断的优先级设置

    NVIC 利用 4bit 的优先级来管理所有的中断通道

    STM32 中断的优先级分为两种:抢占式优先级(主优先级) + 响应式优先级(次优先级),每种都有 16 个优先级(0~15),数字越小,优先级越高。

    意义:如果同时发生多个中断请求,但是又不能同时处理,就根据中断请求的优先级来处理和响应中断。

    抢占优先级(主优先级):抢占优先级高的中断可以打断抢占优先级低的中断的执行。

    响应优先级(次优先级):在同时发生多个中断的情况下,响应优先级高的先执行。

    (1) 抢占优先级高的中断可以打断抢占优先级低的中断的执行

    (2) 抢占优先级一样高的中断,响应优先级高的中断不可以打断响应优先级低的中

    (3) 抢占优先级一样高的中断,如果同时发生的情况下响应优先级高的先执行

    (4) 抢占优先级和响应优先级一样高的中断同时发生,则按照向量表中的优先级执行

  • 为了方便用户管理和响应中断,NVIC 提供一个函数接口可以对中断优先级进行分组

    image

    /**
      * @brief  Configures the priority grouping: pre-emption priority and subpriority.
      * @param  NVIC_PriorityGroup: specifies the priority grouping bits length. 
      *   This parameter can be one of the following values:
      *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
      *                                4 bits for subpriority
      *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
      *                                3 bits for subpriority
      *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
      *                                2 bits for subpriority
      *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
      *                                1 bits for subpriority
      *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
      *                                0 bits for subpriority
      * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. 
      *         The pending IRQ priority will be managed only by the subpriority. 
      * @retval None
      */
    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
    
    
    函数原型
    
    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
    
    函数参数
    
    参数一:NVIC_PriorityGroup   打算设置的NVIC优先级分组  一般为NVIC_PriorityGroup_2
    
    返回值 None
    

    注意:设置中断优先级分组应该在主程序运行的开头部分进行,并且不能随意修改分组,否则会出现中断管理混乱,导致程序出现未知问题。

    int main()
    {
    //设置优先级分组
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    //对硬件进行初始化
    .......
    }
    

EXTI 的概述

EXTI 指的是外部中断/事件控制器,一共有 23 个,每个都有一个内部的边沿检测器,可以检测上升沿或者下降沿,每根线都可以产生事件或者中断。

上升沿:指的是电平信号由低变高的那一刻

下降沿:指的是电平信号由高变低的那一刻

EXTI 使用流程

image

注意:每个 GPIO 引脚都可以配置为外部中断,但是和 GPIO 相关的外部中断线一共只有 16 根,分别为 EXTI0~EXTI15

STM32F407 系列有 114 个 GPIO 口,通过映射的方式与外部中断线关联

  • 对应的函数接口

    /**
      * @brief  Selects the GPIO pin used as EXTI Line.
      * @param  EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for
      *          EXTI lines where x can be (A..K) for STM32F42xxx/43xxx devices, (A..I) 
      *          for STM32F405xx/407xx and STM32F415xx/417xx devices or (A, B, C, D and H)
      *          for STM32401xx devices.  
      *          
      * @param  EXTI_PinSourcex: specifies the EXTI line to be configured.
      *           This parameter can be EXTI_PinSourcex where x can be (0..15, except
      *           for EXTI_PortSourceGPIOI x can be (0..11) for STM32F405xx/407xx
      *           and STM32F405xx/407xx devices and for EXTI_PortSourceGPIOK x can   
      *           be (0..7) for STM32F42xxx/43xxx devices. 
      *           
      * @retval None
      */
    void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);
    
    函数原型
    void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)
    
    函数参数
    参数一:EXTI_PortSourceGPIOx  想要映射的GPIO端口   	如 EXTI_PortSourceGPIOA
    参数二:EXTI_PinSourcex		想要映射的GPIO引脚    	如 EXTI_PinSource0 
    
    

    因为建立映射的时候需要使用系统配置控制器(SYSCFG),所以在编写代码的时候必须打开 SYSCFG 外设的时钟,挂载在 APB2 总线下  调用 RCC_APB2PeriphClockCmd()函数

外部中断的代码编写

注意:所有端口都具有外部中断功能。要使用外部中断线,必须将端口配置为输入模式

                       ##### How to use this driver #####
 ===============================================================================
 
 [..] In order to use an I/O pin as an external interrupt source, follow steps 
      below:
   (#) Configure the I/O in input mode using GPIO_Init()
   (#) Select the input source pin for the EXTI line using SYSCFG_EXTILineConfig()
   (#) Select the mode(interrupt, event) and configure the trigger 
       selection (Rising, falling or both) using EXTI_Init()
   (#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init()

 [..]   
   (@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx
       registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  1. 工程中添加 stm32f4xx_exti.c 以及 stm32f4xx_syscfg.c 两个源文件

  2. 打开 GPIO 时钟外设(挂载 AHB1 总线) + SYSCFG 外设时钟(挂载 APB2 总线)

  3. 定义 GPIO 初始化结构体,将引脚模式配置为输入模式 + 初始化

  4. 调用 SYSCFG_EXTILineConfig()函数来对外部中断线和 GPIO 引脚建立映射关系

  5. 定义 EXTI 初始化结构体,需要配置外部中断线(模式、触发方式.....) + 初始化

    /** 
      * @brief  EXTI Init Structure definition  
      */
    
    typedef struct
    {
      uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.
                                             This parameter can be any combination value of @ref EXTI_Lines */
    
      EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.
                                             This parameter can be a value of @ref EXTIMode_TypeDef */
    
      EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
                                             This parameter can be a value of @ref EXTITrigger_TypeDef */
    
      FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.
                                             This parameter can be set either to ENABLE or DISABLE */ 
    }EXTI_InitTypeDef;
    
    • EXTI_Line 需要使用的外部中断线

      /** @defgroup EXTI_Lines 
        * @{
        */
      
      #define EXTI_Line0       ((uint32_t)0x00001)     /*!< External interrupt line 0 */
      #define EXTI_Line1       ((uint32_t)0x00002)     /*!< External interrupt line 1 */
      #define EXTI_Line2       ((uint32_t)0x00004)     /*!< External interrupt line 2 */
      #define EXTI_Line3       ((uint32_t)0x00008)     /*!< External interrupt line 3 */
      #define EXTI_Line4       ((uint32_t)0x00010)     /*!< External interrupt line 4 */
      #define EXTI_Line5       ((uint32_t)0x00020)     /*!< External interrupt line 5 */
      #define EXTI_Line6       ((uint32_t)0x00040)     /*!< External interrupt line 6 */
      #define EXTI_Line7       ((uint32_t)0x00080)     /*!< External interrupt line 7 */
      #define EXTI_Line8       ((uint32_t)0x00100)     /*!< External interrupt line 8 */
      #define EXTI_Line9       ((uint32_t)0x00200)     /*!< External interrupt line 9 */
      #define EXTI_Line10      ((uint32_t)0x00400)     /*!< External interrupt line 10 */
      #define EXTI_Line11      ((uint32_t)0x00800)     /*!< External interrupt line 11 */
      #define EXTI_Line12      ((uint32_t)0x01000)     /*!< External interrupt line 12 */
      #define EXTI_Line13      ((uint32_t)0x02000)     /*!< External interrupt line 13 */
      #define EXTI_Line14      ((uint32_t)0x04000)     /*!< External interrupt line 14 */
      #define EXTI_Line15      ((uint32_t)0x08000)     /*!< External interrupt line 15 */
      #define EXTI_Line16      ((uint32_t)0x10000)     /*!< External interrupt line 16 Connected to the PVD Output */
      #define EXTI_Line17      ((uint32_t)0x20000)     /*!< External interrupt line 17 Connected to the RTC Alarm event */
      #define EXTI_Line18      ((uint32_t)0x40000)     /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup from suspend event */                                    
      #define EXTI_Line19      ((uint32_t)0x80000)     /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
      #define EXTI_Line20      ((uint32_t)0x00100000)  /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event  */
      #define EXTI_Line21      ((uint32_t)0x00200000)  /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */                                               
      #define EXTI_Line22      ((uint32_t)0x00400000)  /*!< External interrupt line 22 Connected to the RTC Wakeup event */
      #define EXTI_Line23      ((uint32_t)0x00800000)  /*!< External interrupt line 23 Connected to the LPTIM Wakeup event */
      
      
    • EXTI_Mode 外部中断线的模式 (中断 or 事件)

      /** 
        * @brief  EXTI mode enumeration  
        */
      
      typedef enum
      {
        EXTI_Mode_Interrupt = 0x00,
        EXTI_Mode_Event = 0x04
      }EXTIMode_TypeDef;
      
    • EXTI_Trigger 边沿检测方式(上升沿、下降沿、边沿)

      /** 
        * @brief  EXTI Trigger enumeration  
        */
      
      typedef enum
      {
        EXTI_Trigger_Rising = 0x08,
        EXTI_Trigger_Falling = 0x0C,  
        EXTI_Trigger_Rising_Falling = 0x10
      }EXTITrigger_TypeDef;
      
    • EXTI_LineCmd 外部中断线使能 ENABLE or DISABLE

    • 初始化 EXTI

      /**
        * @brief  Initializes the EXTI peripheral according to the specified
        *         parameters in the EXTI_InitStruct.
        * @param  EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
        *         that contains the configuration information for the EXTI peripheral.
        * @retval None
        */
      void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
      
      
  6. 定义 NVIC 的初始化结构体,并进行赋值(中断通道....) + 初始化

    • NVIC_IRQChannel 需要打开的中断通道

      image

    • NVIC_IRQChannelPreemptionPriority 抢占优先级 需要根据分组进行填写

      image

    • l NVIC_IRQChannelSubPriority 响应优先级 需要根据分组进行填写

      image

    • NVIC_IRQChannelCmd 中断通道的使能 ENABLE or DISABLE

    • 初始化 NVIC

      /**
        * @brief  Initializes the NVIC peripheral according to the specified
        *         parameters in the NVIC_InitStruct.
        * @note   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
        *         function should be called before. 
        * @param  NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
        *         the configuration information for the specified NVIC peripheral.
        * @retval None
        */
      void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
      
  7. 编写中断服务函数 中断服务函数的名字必须从启动文件中进行拷贝

注意:中断服务函数的格式是固定的(没有返回值、没有参数) 名字也是固定的

注意:中断服务函数是不需要手动调用的,并且不要再中断中添加过长的延时时间,会导致系统的响应能力降低,所以如果打算处理比较复杂的事件,可以在中断中定义一个标志位,然后回到主程序中进行处理。

实例

/* main.c */
#include "stm32f4xx.h"  

void LED_Init(void)
{
	// LED 0 | 1
	GPIO_InitTypeDef   GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_OUT;			//输出模式
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;			//推挽输出
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_100MHz;		//输出速率
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL;			//无上下拉
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_9|GPIO_Pin_10;				//引脚编号
	GPIO_Init(GPIOF, &GPIO_InitStructure);

	GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10); //默认不亮


	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_OUT;			//输出模式
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;			//推挽输出
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_100MHz;		//输出速率
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL;			//无上下拉
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_13|GPIO_Pin_14;				//引脚编号
	GPIO_Init(GPIOE, &GPIO_InitStructure);

	GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14); //默认不亮

}

void KEY_Init(void)
{
	// init key 0 | 1
	GPIO_InitTypeDef   key0,key1;

	/*打开GPIOA外设时钟*/
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

	/*打开GPIOE外设时钟*/
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

	/*配置PA0引脚*/
	key0.GPIO_Mode 	= GPIO_Mode_IN;				//输入模式
	key0.GPIO_PuPd 	= GPIO_PuPd_NOPULL;			//无上下拉
	key0.GPIO_Pin 	= GPIO_Pin_0;				//引脚编号
	GPIO_Init(GPIOA, &key0);

	/*配置PE2 PE3 PE4引脚*/
	key1.GPIO_Mode 	= GPIO_Mode_IN;				//输入模式
	key1.GPIO_PuPd 	= GPIO_PuPd_NOPULL;			//无上下拉
	key1.GPIO_Pin 	= GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;	//引脚编号
	GPIO_Init(GPIOE, &key1);
}

void EXTI0_1_Init(void)
{
	EXTI_InitTypeDef   EXTI_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;

	/*打开SYSCFG外设时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

/*------------------------------------------------配置PA中断------------------------------------------------------------------------*/

	/*引脚和外部中断线建立映射关系*/
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

	/*配置外部中断线*/
	EXTI_InitStructure.EXTI_Line 	= EXTI_Line0;				//外部中断线0
	EXTI_InitStructure.EXTI_Mode 	= EXTI_Mode_Interrupt;		//中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  	//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能外部中断线0
	EXTI_Init(&EXTI_InitStructure);


	/*配置中断优先级*/
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能通道
	NVIC_Init(&NVIC_InitStructure);

/*------------------------------------------------配置PE2中断------------------------------------------------------------------------*/
	/*GPIOE引脚和外部中断线建立映射关系*/
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);

	/* 配置外部中断线*/
	EXTI_InitStructure.EXTI_Line	= EXTI_Line2;				//外部中断线1
	EXTI_InitStructure.EXTI_Mode	= EXTI_Mode_Interrupt;		//中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 	//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能外部中断线1
	EXTI_Init(&EXTI_InitStructure);


	/*配置中断优先级*/
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;			//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能通道
	NVIC_Init(&NVIC_InitStructure);

/*------------------------------------------------配置PE3中断------------------------------------------------------------------------*/
	/*GPIOE引脚和外部中断线建立映射关系*/
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);

	/* 配置外部中断线*/
	EXTI_InitStructure.EXTI_Line	= EXTI_Line3;				//外部中断线1
	EXTI_InitStructure.EXTI_Mode	= EXTI_Mode_Interrupt;		//中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 	//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能外部中断线1
	EXTI_Init(&EXTI_InitStructure);


	/*配置中断优先级*/
	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;			//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能通道
	NVIC_Init(&NVIC_InitStructure);


/*------------------------------------------------配置PE4中断------------------------------------------------------------------------*/
	/*GPIOE引脚和外部中断线建立映射关系*/
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);

	/* 配置外部中断线*/
	EXTI_InitStructure.EXTI_Line	= EXTI_Line4;				//外部中断线1
	EXTI_InitStructure.EXTI_Mode	= EXTI_Mode_Interrupt;		//中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 	//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能外部中断线1
	EXTI_Init(&EXTI_InitStructure);


	/*配置中断优先级*/
	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;			//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 			//使能通道
	NVIC_Init(&NVIC_InitStructure);

}

int main()
{
	//1.硬件初始化
	LED_Init();
	KEY_Init();
	EXTI0_1_Init();

	//2.进入死循环
	while(1)
	{
//		if( GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) == RESET )	//说明被按下
//		{
//			GPIO_ResetBits(GPIOF,GPIO_Pin_10);	//设置低电平  LED亮
//		}
//		else
//		{
//			GPIO_SetBits(GPIOF,GPIO_Pin_10);		//设置高电平  LED灭
//		}
	}
}

//中断服务函数  不需要手动调用   尽量精简(尽量不要添加很长的延时)
void EXTI2_IRQHandler(void)
{
	//检测中断线的标志
	if( EXTI_GetITStatus(EXTI_Line2) != RESET )
	{
		GPIO_ToggleBits(GPIOF,GPIO_Pin_10); //LED电平翻转
		//清除中断标志位
		EXTI_ClearITPendingBit(EXTI_Line2);
	}
}

//中断服务函数  不需要手动调用   尽量精简(尽量不要添加很长的延时)
void EXTI3_IRQHandler(void)
{
	//检测中断线的标志
	if( EXTI_GetITStatus(EXTI_Line3) != RESET )
	{
		GPIO_ToggleBits(GPIOE,GPIO_Pin_13); //LED电平翻转
		//清除中断标志位
		EXTI_ClearITPendingBit(EXTI_Line3);
	}
}

//中断服务函数  不需要手动调用   尽量精简(尽量不要添加很长的延时)
void EXTI4_IRQHandler(void)
{
	//检测中断线的标志
	if( EXTI_GetITStatus(EXTI_Line4) != RESET )
	{
		GPIO_ToggleBits(GPIOE,GPIO_Pin_14); //LED电平翻转
		//清除中断标志位
		EXTI_ClearITPendingBit(EXTI_Line4);
	}
}

//中断服务函数  不需要手动调用   尽量精简(尽量不要添加很长的延时)
void EXTI0_IRQHandler(void)
{
	//检测中断线的标志
	if( EXTI_GetITStatus(EXTI_Line0) != RESET )
	{
		GPIO_ToggleBits(GPIOF,GPIO_Pin_9); //LED电平翻转
		//清除中断标志位
		EXTI_ClearITPendingBit(EXTI_Line0);
	}
}


  • 中断
    2 引用
  • STM32

    STM32 系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的 ARM Cortex®-M0,M0+,M3, M4 和 M7 内核。按内核架构分为不同产品: 主流产品(STM32F0、STM32F1、STM32F3)、超低功耗产品(STM32L0、STM32L1、STM32L4、STM32L4+)、高性能产品(STM32F2、STM32F4、STM32F7、STM32H7)

    9 引用 • 2 回帖 • 1 关注

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...