单片机
返回首页

STM32F0xx_EXTI中断配置详细过程-按键检测

2019-01-15 来源:eefocus

1、概述

EXIT外部中断在使用到按键或者开关控制等应用中比较常见,低功耗中断唤醒也是很常见的一种。因此,EXIT在实际项目开发中也是比较常见的一种。EXTI(External interrupt/event controller) —外部中断/事件控制器, 管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。 EXTI 可以实现对每个中断/事件线进行单独置可以单独配置为中断或者事件,以及触发事件的属性。


EXTI功能框图:


EXTI功能框图


2、准备工作


本次采用按键作为触发源的方式来使得控制器产生中断,并在中断服务函数中执行相应的命令。按键按下->LED状态做出相应的改变,并尝试用不同优先级的中断来让LED灯做出相应的改变。


硬件设计:

 

轻触按键在按下时会使得引脚接通,通过电路设计可以使得按下时产生电平变化。


按键消抖硬件设计 


3、代码描述


3.1 初始化用来中断的GPIO


3.2 初始化EXTI


3.3 配置NVIC


3.4编写中断服务函数


按键和EXTI宏定义:


按键和EXTI宏定义


嵌套向量中断控制器NVIC配置:

/**************************************************/

static void NVIC_Configuration(void)

{

    NVIC_InitTypeDef    NVIC_InitStructure;


    /*配置中断源:KEY2*/

    NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;

    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;  //指定IRQ通道的优先级在NVIC_IRQChannel中,这个参数可以设定为0到3之间

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    /*配置中断源:KEY1*/

    NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;

    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;  //指定IRQ通道的优先级在NVIC_IRQChannel中,这个参数可以设定为0到3之间

    NVIC_Init(&NVIC_InitStructure);


}


这个优先级参数可以自行设定(参数设定为0到3之间,0的优先级最高)


EXTI中断配置:

/*中断EXTI_PA0配置初始化*/

void EXTI_PA0_Config(void)

{

    GPIO_InitTypeDef    GPIO_InitStructure;

    EXTI_InitTypeDef    EXTI_InitStructure;

    //时钟使能

    RCC_AHBPeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);

    RCC_APB2PeriphClockCmd(KEY1_INT_EXTI_CLK,ENABLE);


    NVIC_Configuration();

    //外部按键GPIO初始化,PA0

    GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;


    GPIO_Init(KEY1_INT_GPIO_PORT,&GPIO_InitStructure);


    //将EXTI0指向PA0

    SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,EXTI_PinSource0);

    //EXTI0中断线配置

    EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//下降沿中断


    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

}


void EXTI_PA2_Config(void)

{

    GPIO_InitTypeDef    GPIO_InitStructure;

    EXTI_InitTypeDef    EXTI_InitStructure;

    //时钟使能

    RCC_AHBPeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE);

    RCC_APB2PeriphClockCmd(KEY2_INT_EXTI_CLK,ENABLE);


    NVIC_Configuration();

    //外部按键GPIO初始化,PA2

    GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;


    GPIO_Init(KEY2_INT_GPIO_PORT,&GPIO_InitStructure);


    //将EXTI2指向PA2

    SYSCFG_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE,EXTI_PinSource2);

    //EXTI2中断线配置

    EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//下降沿中断


    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

}



EXTI中断服务函数:

//KEY1_IRQHandler()中断服务函数

void KEY1_IRQHandler(void)

{

    if(EXTI_GetITStatus(EXTI_Line0)!=RESET) //确保中断是否产生

    {

        //中断处理

        LED_ON();

        delay_ms(500);

        LED_OFF();

        delay_ms(500);

        LED_ON();

        delay_ms(500);

        LED_OFF();

        delay_ms(500);

        LED_ON();

        delay_ms(500);

        LED_OFF();

        delay_ms(500);

        LED_ON();

        delay_ms(500);


    }

    EXTI_ClearFlag(EXTI_Line0); //清除中断标志位

}


//KEY2_IRQHandler()中断服务函数

void KEY2_IRQHandler(void)

{

    if(EXTI_GetITStatus(EXTI_Line2)!=RESET) //确保中断是否产生

    {

        //中断处理

        LED_OFF();//LED熄灭

        delay_ms(1000);

    }

    EXTI_ClearFlag(EXTI_Line2); //清除中断标志位


}


当中断发生时,相应的中断服务函数就会被执行,我们可以在中断函数中实现一些控制。 

一般为确保中断确实发生,我们会在中断服务函数中调用中断标志位状态读取函数读取外设中断标志位并判断标志位状态。


主函数:

#include 'ALL_Includes.h' //包含所有的头文件


int main(void)

{

    //初始化函数

    LED_Init();

    Delay_Init(48);

    LED_ON();

    delay_ms(5000);


    EXTI_PA0_Config(); //初始化中断

    EXTI_PA2_Config();

    while(1)

    {

        //等待

    }

}


总结:


stm32f030的中断配置与stm32f103的中断配置是有些许的不同,但是大致还是差不多的。


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 用数字电路CD4069制作的万能遥控轻触开关

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章