3、【STM32F0系列学习】之—中断和事件

【STM32F0系列学习】之—中断和事件

  • 1、什么是“中断”
  • 2、中断优先级
  • 3、中断嵌套
  • 4、嵌套向量中断控制器 (NVIC)
  • 5、中断与事件的区别和主要特性
  • 6、外部中断(EXTI)配置
    • 6.1【标准库】的配置方式
    • 6.2【HAL库】的配置方式

1、什么是“中断”

        CPU执行程序时,由于发生了某种随机的事件(外部或内部),引起CPU暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程称为中断。
3、【STM32F0系列学习】之—中断和事件_第1张图片

2、中断优先级

所谓中断优先级,是指当中断来临时,CPU应该先执行哪个中断服务程序,不同中断再CPU看来重要程度是不一样的,高优先级的中断服务程序应被优先执行。中断的优先级分为两种,一种是硬件优先级,即芯片厂家出厂时就规定了哪些外设的中断优先级高,哪些的中断优先级低;第二种是软件优先级,指用户可以通过程序配置来修改中断优先级,一般主要是将硬件上低优先级的中断进行提高。当同一时间点有两个或以上中断同时来临时,系统会优先选择中断优先级高的中断服务函数进行执行,当软件的中断优先级一样时,会根据硬件中断优先级高的执行中断服务函数。中断优先级:0~3,数越小优先级越高

3、中断嵌套

上面第一点说只是说明了常规中断的含义,总结就是,在主程序运行期间产生中断需要先暂停执行主程序,转去执行中断服务程序,当中断服务程序执行完成后再返回到刚才主程序暂停的地方继续向下执行主程序。而中断嵌套,则是指在第一个中断服务程序还没执行完成的时候又来了一个中断优先级比当前中断高的中断,把当前中断服务程序暂停,转而去执行中断优先级更高的中断服务程序,当高优先级的中断程序执行完成后,再返回到次优先级的中断程序暂停点执行,然后再返回主程序暂停点继续执行主程序下面的内容。
3、【STM32F0系列学习】之—中断和事件_第2张图片

4、嵌套向量中断控制器 (NVIC)

STM32系列单片机内部有一个嵌套向量中断控制器 (NVIC)控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对 Cortex-M0 内核里面的 NVIC 进行裁剪,把不需要的部分去掉,所以说 STM32 的 NVIC 是 Cortex-M0 的 NVIC 的一个子集。

NVIC 主要特性
● 32 个可屏蔽中断通道 ( 不包含 16 个 Cortex-M0 的中断线 )
● 4 个可编程的优先级 ( 使用了 2 位的中断优先级 )
● 低延时的异常和中断处理
● 电源管理控制
● 系统控制寄存器的实现

5、中断与事件的区别和主要特性

区别:
(1)中断: 需要CPU参与处理才能完成任务。

(2)事件:
事件机制提供了一个完全由硬件自动完成的触发到产生结果的通道,不要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度(硬件总快于软件),是利用硬件来提升CPU芯片处理事件能力的一个有效方法;

主要特性:
● 支持产生多达 28 个事件 / 中断请求 ; 外部21条,内部7条;
● 作为外部或内部事件请求的每一线都可独立配置;
● 每个事件 / 中断线都有独立的屏蔽;
● 当系统不处于停机 (STOP) 模式时自动禁止内部各线;
● 独立触发外部事件 / 中断线 ;
● 每个外部中断线都有专用的状态位;
● 仿真所有的外部事件请求。
● 可以选择4种中断优先级(0~3)

中断向量表
3、【STM32F0系列学习】之—中断和事件_第3张图片
3、【STM32F0系列学习】之—中断和事件_第4张图片
3、【STM32F0系列学习】之—中断和事件_第5张图片
中断/事件 配置使用说明
        要产生中断,必须先配置好并使能中断线。根据需要的边沿检测设置2个触发寄存器,同时在中断屏蔽寄存器的相应位写’1 ’允许中断请求。当外部中断线上发生了期待的边沿时,将产生一个中断请求,对应的挂起位也随之被置’ 1 ’。在挂起寄存器的对应位写’ 1 ’,将清除该中断请求。
        对于内部中断线,触发沿都为上升沿,中断屏蔽寄存器相应值使能这些中断,但内部中断线没有相应的挂起位。
        如果需要产生事件,必须先配置好并使能事件线。根据需要的边沿检测通过设置 2 个触发寄存器,同时在事件屏蔽寄存器的相应位写’ 1 ’允许事件请求。当事件线上发生了期待的边沿时,将产生一个事件请求脉冲,对应的挂起位不被置’ 1 ’。
        对于外部中断线,一个中断 / 事件请求也可由软件对相应的软件中断 / 事件寄存器位写’ 1 ’来产生。

6、外部中断(EXTI)配置

6.1【标准库】的配置方式

其实EXIT外部引脚中断的原理很简单,配置相应引脚为输入模式,根据电路看是否需要上下拉电阻,将该引脚通过SYSCFG配置为中断线,再配置NVIC,编写中断处理的事情即可。下面以配置 PA0引脚作为按键的输入检测脚为例,即按键检测使用外部中断方式。

/*----------------------------------------- led.h -----------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : led.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : LED驱动头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _LED_H
#define _LED_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "stm32f0xx.h"

/* 宏定义 --------------------------------------------------------------------*/
#define LED_PORT                  GPIOC                    //LED端口
#define LED_1_PIN                 GPIO_Pin_6               //LED1
#define LED_R_PIN                 GPIO_Pin_7               //LED_R
#define LED_G_PIN                 GPIO_Pin_8               //LED_G
#define LED_B_PIN                 GPIO_Pin_9               //LED_B

#define LED_1_ON                  GPIO_ResetBits(LED_PORT,LED_1_PIN)        //点亮LED1
#define LED_1_OFF                 GPIO_SetBits(LED_PORT,LED_1_PIN)          //熄灭LED1
#define LED_1_TOGGLE              (LED_PORT->ODR ^= LED_1_PIN)              //LED1取反

#define LED_R_ON                  GPIO_ResetBits(LED_PORT,LED_R_PIN)        //点亮LED_R
#define LED_R_OFF                 GPIO_SetBits(LED_PORT,LED_R_PIN)          //熄灭LED_R
#define LED_R_TOGGLE              (LED_PORT->ODR ^= LED_R_PIN)              //LED_R取反

#define LED_G_ON                  GPIO_ResetBits(LED_PORT,LED_G_PIN)        //点亮LED_G
#define LED_G_OFF                 GPIO_SetBits(LED_PORT,LED_G_PIN)          //熄灭LED_G
#define LED_G_TOGGLE              (LED_PORT->ODR ^= LED_G_PIN)              //LED_G取反

#define LED_B_ON                  GPIO_ResetBits(LED_PORT,LED_B_PIN)        //点亮LED_B
#define LED_B_OFF                 GPIO_SetBits(LED_PORT,LED_B_PIN)          //熄灭LED_B
#define LED_B_TOGGLE              (LED_PORT->ODR ^= LED_B_PIN)              //LED_B取反

/* 函数申明 ------------------------------------------------------------------*/
void LED_GPIO_Config(void);

#endif /* _LED_H */

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/



/*----------------------------------------- led.c -----------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : led.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : LED驱动源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "led.h"

/************************************************
函数名称 : LED_GPIO_Config
功    能 : LED引脚配置
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void LED_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = LED_1_PIN;                           //LED1引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                      //输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //高速输出
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                     //推完输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                   //内部无上下拉,外部有1K上拉电阻
    GPIO_Init(LED_PORT, &GPIO_InitStructure);
    
    LED_1_OFF;                  //LED1熄灭
    
}

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/



/*----------------------------------------- key.h -----------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : key.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : 按键驱动头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _KEY_H
#define _KEY_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "stm32f0xx.h"

/* 宏定义 --------------------------------------------------------------------*/
#define KEY1_PORT       GPIOC           //KEY1端口
#define KEY2_PORT       GPIOC           //KEY2端口
#define KEY3_PORT       GPIOB           //KEY3端口
#define KEY4_PORT       GPIOB           //KEY4端口

#define K1_PIN          GPIO_Pin_12     //KEY1引脚
#define K2_PIN          GPIO_Pin_13     //KEY2引脚
#define K3_PIN          GPIO_Pin_0      //KEY3引脚
#define K4_PIN          GPIO_Pin_1      //KEY4引脚

/* 类型定义 --------------------------------------------------------------*/
typedef enum
{
	KEY_DOWN = 0,
	KEY_UP   = 1,  
}KEYState_TypeDef;

/* 函数申明 ------------------------------------------------------------------*/
void KEY_GPIO_Config(void);     //按键引脚配置
KEYState_TypeDef KEY_StateRead(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);     //按键状态读取
void KEY_EXTI_Config(void);     //按键外部中断配置

#endif /* _KEY_H */

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/



/*----------------------------------------- key.c -----------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : key.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : 按键驱动源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

/************************************************
函数名称 : KEY_GPIO_Config
功    能 : KEY引脚配置
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void KEY_GPIO_Config(void)
{
    /*定义一个GPIO_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef GPIO_InitStructure;
	/*选择要控制的GPIOC引脚*/
	GPIO_InitStructure.GPIO_Pin = K1_PIN; 
	/*设置要控制的GPIOC引脚为输入模式*/
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	/*调用库函数,初始化GPIOC*/
	GPIO_Init(KEY1_PORT, &GPIO_InitStructure);

}


/************************************************
函数名称 : KEY_StateRead
功    能 : 按键状态读取
参    数 : 无
返 回 值 : 0-按下,1-松开
作    者 : JayYang
*************************************************/
KEYState_TypeDef KEY_StateRead(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){
  /* 读取此时按键值并判断是否是被按下状态,如果是被按下状态进入函数内 */
  if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==0)
  {
    /* 延时一小段时间,消除抖动 */
    delay_ms(10);
    /* 延时时间后再来判断按键状态,如果还是按下状态说明按键确实被按下 */
    if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==0)
    {
      /* 等待按键弹开才退出按键扫描函数 */
      while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==0);
       /* 按键扫描完毕,确定按键被按下,返回按键被按下状态 */
      return KEY_DOWN;
    }
  }
  /* 按键没被按下,返回没被按下状态 */
  return KEY_UP;
}


/************************************************
函数名称 : KEY_EXTI_Config
功    能 : 按键外部中断配置
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void KEY_EXTI_Config(void){
    
    EXTI_InitTypeDef EXTI_InitStructure;
    
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,EXTI_PinSource12);   //选择PC12作为EXTI线使用的GPIO pin
    
    /* EXTI外部中断线配置 */
    EXTI_InitStructure.EXTI_Line = EXTI_Line12;              //配置外部中断线12
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;      //配置为中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //配置中断的触发边沿为下降沿
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                //使能中断线
    EXTI_Init(&EXTI_InitStructure);                          //初始化外部中断
       
}

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/


/*----------------------------------------- bsp.h -----------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : bsp.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : BSP板级支持包头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _BSP_H
#define _BSP_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "stm32f0xx.h"

#include "led.h"
#include "key.h"


/* 宏定义 --------------------------------------------------------------------*/


/* 函数申明 ------------------------------------------------------------------*/
void delay_ms(uint16_t nms);
void RCC_Configuration(void);
void NVIC_Configuration(void);
void BSP_Initializes(void);


#endif /* _BSP_H */

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/



/*----------------------------------------- bsp.c -----------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : bsp.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : BSP板级支持包源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

/****************************************************************************
* 名    称:delay_ms(u16 nms)
* 功    能:毫秒延时函数
* 入口参数:u16 nms
* 出口参数:无
* 说    明:输入范围(1~1000)ms
* 调用方法:无 
****************************************************************************/ 
void delay_ms(uint16_t nms)
{
	 uint32_t temp;
	 SysTick->LOAD = 6000*nms;
	 SysTick->VAL=0X00;//清空计数器
	 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
	 do
	 {
	  temp=SysTick->CTRL;//读取当前倒计数值
	 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
	 SysTick->CTRL=0x00; //关闭计数器
	 SysTick->VAL =0X00; //清空计数器
}

/************************************************
函数名称 : RCC_Configuration
功    能 : 时钟配置
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void RCC_Configuration(void)
{
    /* 使能AHB时钟 */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
}

/************************************************
函数名称 : NVIC_Configuration
功    能 : NVIC配置
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void NVIC_Configuration(void){
    
    NVIC_InitTypeDef NVIC_InitStructure;        //定义一个NVIC_InitTypeDef类型的结构体
    
    /* 外部中断 */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;       //配置中断优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       //使能中断
    NVIC_Init(&NVIC_InitStructure);                       //中断初始化
    
}

/************************************************
函数名称 : BSP_Initializes
功    能 : 底层初始化
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void BSP_Initializes(void)
{
    RCC_Configuration();        //时钟配置
    LED_GPIO_Config();          //LED引脚配置
    KEY_GPIO_Config();          //按键引脚配置
    KEY_EXTI_Config();          //按键外部中断配置
    NVIC_Configuration();       //NVIC配置
}


/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/



/*----------------------------------------- stm32f0xx_it.c -----------------------------------------*/
/************************************************
函数名称 : EXTI4_15_IRQHandler
功    能 : 外部中断4-15
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void EXTI4_15_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line12) != RESET)
    {
        if(KEY_StateRead(KEY1_PORT,K1_PIN)==KEY_DOWN)
        {
            LED_1_TOGGLE;    //如果K1被按下,LED1状态取反
        }
        
        EXTI_ClearITPendingBit(EXTI_Line12);               //清除标志位        
    }
} 

/*----------------------------------------- main.c -----------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : main.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : 主函数
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

/************************************************
函数名称 : main
功    能 : 主函数入口
参    数 : 无
返 回 值 : int
作    者 : JayYang
*************************************************/
int main(void)
{
    BSP_Initializes();

    while(1)
    {
        
    }
}

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

6.2【HAL库】的配置方式

步骤:
1、通过STM32CubeMX软件配置RCC时钟
3、【STM32F0系列学习】之—中断和事件_第6张图片
选择【Clock Configutration】选项卡进行时钟的设置,如图下图:
3、【STM32F0系列学习】之—中断和事件_第7张图片
2、管脚功能设定:
我们以 PC12 引脚用作KEY1进行外部中断检测来判断按键是否被按下,以 PC6 作为控制LED1的引脚,实现通过按键KEY1来点亮或熄灭LED1的案例作为实验说明,单机鼠标左键,就会弹出适用于 PC12 管脚 或 PC6 管脚 所有的功能选项,需要使用哪个功能,直接选中即可,如下图所示:
3、【STM32F0系列学习】之—中断和事件_第8张图片
3、管脚参数设置
3、【STM32F0系列学习】之—中断和事件_第9张图片
3、【STM32F0系列学习】之—中断和事件_第10张图片
3、【STM32F0系列学习】之—中断和事件_第11张图片
4、外部中断引脚的中断优先级设置
3、【STM32F0系列学习】之—中断和事件_第12张图片
说明:外部中断线4至15的中断优先级不能设置为 0 ,因为在外部中断的回调函数中,会对按键进行消抖处理,需要延时20ms,而这个延时函数是使用的HAL库提供的HAL_Delay延时函数,这个延时函数使用的是SysTick系统嘀嗒定时器中断的方式实现的延时,且从上图可以看到其中断优先级也是 0 ,所以,当按键外部下降沿中断触发时,进入中断回调函数,需要进行按键消抖判断,此时延时20ms,如果外部中断的优先级也设置为 0 的话,由于和延时的中断优先级一样,所以延时函数无法执行中断,程序卡死,看到的现象就是无论怎么按,LED灯都不亮。而把外部中断的中断优先级设置为 1 ,则当延时到来时,由于延时的中断优先级高,把外部中断所中断,形成中断嵌套,从而可以进行 20ms 的延时消抖,看到的现象就是反复按键按下LED亮和灭。

5、项目配置
3、【STM32F0系列学习】之—中断和事件_第13张图片
3、【STM32F0系列学习】之—中断和事件_第14张图片
3、【STM32F0系列学习】之—中断和事件_第15张图片
6、HAL源代码编译和补充
默认由STM32CubeMX软件生成的是相关外设的一些初始化代码,具体的业务逻辑代码还是需要用户自己添加的。

/*----------------------------------------- led.h -----------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : led.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : LED驱动头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _LED_H
#define _LED_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"

/* 宏定义 --------------------------------------------------------------------*/
#define LED_1_ON        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET)   //点亮LED1
#define LED_1_OFF       HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET)     //熄灭LED1
#define LED_1_TOGGLE    HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin)                   //LED1取反

#endif 
/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/


/*----------------------------------------- led.c -----------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : led.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : LED驱动源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/


/*----------------------------------------- stm32f0xx_it.c -----------------------------------------*/
/**
  * 在 stm32f0xx_it.c 中断服务函数源文件中找到外部中断的处理函数
  * @brief This function handles EXTI line 4 to 15 interrupts.
  */
void EXTI4_15_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI4_15_IRQn 0 */

  /* USER CODE END EXTI4_15_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);	//进入这个GPIO外部中断函数
  /* USER CODE BEGIN EXTI4_15_IRQn 1 */

  /* USER CODE END EXTI4_15_IRQn 1 */
}


/*----------------------------------------- stm32f0xx_hal_gpio.c -----------------------------------------*/
/**
  * @brief  Handle EXTI interrupt request.
  * @param  GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  { 
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);					//发现这个处理函数又调用了HAL_GPIO_EXTI_Callback这个回调函数,继续追踪
  }
}

/**
  * 发现处理GPIO外部中断的回调函数有__weak定义,说明是弱类型函数,用户可以在其他文件中重新定义这个同名的回调函数
  * 此案例我在 bsp.c 文件中进行了重定义
  * @brief  EXTI line detection callback.
  * @param  GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);

  /* NOTE: This function should not be modified, when the callback is needed,
            the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */ 
}


/*----------------------------------------- bsp.h -----------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : bsp.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : BSP板级支持包头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _BSP_H
#define _BSP_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"
#include "gpio.h"

#include "led.h"

#endif 
/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/


/*----------------------------------------- bsp.c -----------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : bsp.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : BSP板级支持包源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

/************************************************
函数名称 : HAL_GPIO_EXTI_Callback
功    能 : GPIO外部中断回调函数
参    数 : GPIO_Pin:GPIO引脚
返 回 值 : 无
作    者 : JayYang
*************************************************/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)						//重定义回调函数
{
	switch(GPIO_Pin)
	{
		case KEY1_Pin:												//判断当前是否是按键引脚
		{
			if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)        //判断 KEY1 是否被按下
			{
				HAL_Delay(20);                                      //延时消抖,中断方式延时,中断优先级为0
				if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)    //再次判断 KEY1 是否被按下
				{				
					LED_1_TOGGLE;									//使LED1亮灭取反
				}
			}
		}
		break;
	}
	
}
	
/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/


/*----------------------------------------- main.c -----------------------------------------*/
//主函数保持默认生成的代码
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

至此,关于STM32F0系列的中断相关如上所述,本内容纯粹使个人学习的一个记录过程,方便自己以后回顾,也方便有需要的人,内容如有不对的地方,烦请各位留言指出,谢谢!

你可能感兴趣的:(STM32F0单片机学习笔记,stm32,嵌入式,单片机)