zoukankan      html  css  js  c++  java
  • STM32 外部中断

    摘要

    本文介绍STM32配置的步骤以及相关的步骤,通过触发按键外部中断实现摁键点灯操作,即摁下摁键,触发中断,LED灯亮,松开LED灯灭。

    STM32外部中断简介

    STM32 的每个 IO 都可以作为外部中断的中断输入口, STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F103 的19 个外部中断为:

    线 0~15:对应外部 IO 口的输入中断。

    线 16:连接到 PVD 输出。

    线 17:连接到 RTC 闹钟事件。

    线 18:连接到 USB 唤醒事件。

    所以STM32可以作为GPIO外部中断的线路共有16个,其具体的映射关系如下:

    STM32F1外部中断配置的一般步骤如下:

    1)将对应的GPIO口初始化维输入模式

    2)开启AFIO时钟,开启端口的复用

    3)根据GPIO和中断的映射关系配置IO口与中断的映射关系

    4)初始化GPIO外部中断线,并设置触发条件等内容

    5)配置中断,包括使能中断和为中断分组等

    6)根据项目需求配置中断服务程序

    预实现的功能

    摁下UP_LED对应的按键,点亮UP引脚连接的LED灯,松开UP_LED按键,熄灭LED引脚连接的LED灯。

    程序代码

    端口宏定义:、

    /*配置GPIO输入模式*/

    #define UP_LED_PORT                        GPIOB

    #define UP_LED_PIN                        GPIO_Pin_3

    #define UP_LED_RCC                        RCC_APB2Periph_GPIOB

    #define UP_LED_Mode                        GPIO_Mode_IPU                //上拉输入

    #define UP_LED_Speed                GPIO_Speed_50MHz

       

    /*配置GPIO外部中断相关的信息 按键接在PB3,对应的3号中断线和USART3_IRQ中断*/

    #define UP_LED_EXTI_PORT        GPIO_PortSourceGPIOB

    #define UP_LED_EXTI_Source        GPIO_PinSource3

    #define UP_LED_EXTI_LINE        EXTI_Line3

    #define UP_LED_EXTI_MODE        EXTI_Mode_Interrupt

    #define UP_LED_EXTI_TRIGGER        EXTI_Trigger_Rising_Falling        //上升下降沿触发

       

    #define UP_LED_NVIC_IRQChannel        EXTI3_IRQn

       

    /*配置UP对应的LED状态,推挽输出*/

    #define UP_PORT                                GPIOD

    #define UP_PIN                                GPIO_Pin_2

    #define UP_RCC                                RCC_APB2Periph_GPIOD

    #define UP_Mode                                GPIO_Mode_Out_PP        //push pull

    #define UP_Speed                        GPIO_Speed_50MHz

    /*宏定义LED灯电平状态*/

    #define UP(x)        x?GPIO_SetBits(UP_PORT,UP_PIN):GPIO_ResetBits(UP_PORT,UP_PIN)

    #define UP_Elevator_LED_ON        UP(0)                //电梯按钮亮

    #define UP_Elevator_LED_OFF        UP(1)                //电梯按钮灭

    /*宏定义UP_LED 读取电平状态*/

    #define READ_UP_LED        GPIO_ReadInputDataBit(UP_LED_PORT,UP_LED_PIN)

       

    LED对应的引脚功能初始化: 推挽输出模式

    void Elevator_LED_Configuration(void)

    {

       

    GPIO_InitTypeDef Elevator_GPIO_InitStruct;

       

    RCC_APB2PeriphClockCmd(UP_RCC,ENABLE);        //ENABLE the CLOCK

    /*初始化UP的引脚功能,推挽输出模式*/

    Elevator_GPIO_InitStruct.GPIO_Pin = UP_PIN;

    Elevator_GPIO_InitStruct.GPIO_Mode = UP_Mode;

    Elevator_GPIO_InitStruct.GPIO_Speed = UP_Speed;

    GPIO_Init(UP_PORT,&Elevator_GPIO_InitStruct);

    /*设置默认输出状态*/

    UP_Elevator_LED_OFF;

    }

       

    按钮对应的引脚功能初始化,上拉输入

    void Elevator_Key_Configuration(void)

    {

    GPIO_InitTypeDef Elevator_GPIO_InitStruct;

       

    RCC_APB2PeriphClockCmd(UP_LED_RCC,ENABLE);        //ENABLE the CLOCK

    /*初始化UP_LED的引脚功能,输入模式*/

    Elevator_GPIO_InitStruct.GPIO_Pin = UP_LED_PIN;

    Elevator_GPIO_InitStruct.GPIO_Mode = UP_LED_Mode;

    Elevator_GPIO_InitStruct.GPIO_Speed = UP_LED_Speed;

    GPIO_Init(UP_LED_PORT,&Elevator_GPIO_InitStruct);

    }

    按键对应的引脚外部中断初始化配置。

    void Elevator_Key_EXTI_Configuration(void)

    {

    EXTI_InitTypeDef Elevator_Key_EXTI_InitStructure;

    NVIC_InitTypeDef Elevator_Key_NVIC_InitStructure;

       

    Elevator_Key_Configuration();        //初始化电梯按钮为输入模式

       

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //开始AFIO时钟

       

       

    /*配置UP_LED对应的电梯按钮中断线*/

    GPIO_EXTILineConfig(UP_LED_EXTI_PORT,UP_LED_EXTI_Source);

       

    Elevator_Key_EXTI_InitStructure.EXTI_Line = UP_LED_EXTI_LINE;

    Elevator_Key_EXTI_InitStructure.EXTI_Mode = UP_LED_EXTI_MODE;

    Elevator_Key_EXTI_InitStructure.EXTI_Trigger = UP_LED_EXTI_TRIGGER;        //配置触发方式,下降沿触发

    Elevator_Key_EXTI_InitStructure.EXTI_LineCmd = ENABLE;

       

    EXTI_Init(&Elevator_Key_EXTI_InitStructure);

       

    Elevator_Key_NVIC_InitStructure.NVIC_IRQChannel = UP_LED_NVIC_IRQChannel;        //使能外部中断通道

    Elevator_Key_NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;

    Elevator_Key_NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;

    Elevator_Key_NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

       

    NVIC_Init(&Elevator_Key_NVIC_InitStructure);

       

    }

    中断服务程序,本次项目中需要同时检测摁下和松手,所以配置成上升下降沿触发,所以无论是摁下还是松开均会触发中断服务函数,通过以下中断服务程序的处理便实现当按键摁下时,对应的LED灯亮,松开即关闭的效果。

    void EXTI3_IRQHandler(void)

    {

    if(READ_UP_LED==RESET)                //检测到下降沿,即摁键摁下

    {

    UP_Elevator_LED_ON;                //点亮内部LED

    UP_KeyMode = 1;                        //摁下标志位置1

    }

    else                                                //检测到上升沿,即摁键弹起

    {

    UP_Elevator_LED_OFF;        //熄灭内部LED

    UP_KeyMode = 0;                        //复位摁下标志位

    }

    EXTI_ClearITPendingBit(UP_LED_EXTI_LINE);//清除中断线路

    }

     

    虽然本文所提的控制目标也可以使用扫描的方式实现,但是在实际项目中,为了提高系统响应的灵敏度,通常建议使用触发中断的方式检测按键。

  • 相关阅读:
    11.分类与监督学习,朴素贝叶斯分类算法
    9、主成分分析
    7.逻辑回归实践
    8、特征选择
    6.逻辑归回
    5.线性回归算法
    6.10第十四次作业
    6.2第十三次作业
    5.27第十二次作业
    5.20第十一次作业
  • 原文地址:https://www.cnblogs.com/Mr-Wangblogs/p/13227361.html
Copyright © 2011-2022 走看看