STM32小白进阶之路----按键的模块化,低延时,高灵敏

两种按键查询方法,两种方式处理

第一种方法:扫描查询法

优点:无延迟,高灵敏,无中断
思想:也是别人的代码总结出来的,当按键连续读到10个或者20(这个看你的按键多敏感,我的10就够了)低电平,就算按键按下了

//需要循环扫描
u8 IsKey0Down()
{
    static u16 iCount = 0;
    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==0)
    {
        iCount ++;
        if(iCount>30){
            iCount = 0;
            return 1;
        }
    }else{
        iCount = 0;     
    }
    return 0;
}

第二种:沿触发进入中断,延时消抖再判断

#if KEY0_SUPPORT_EXTI   //支持外部中断的话,如下操作
u8 KEY0_IsDown;//1按下 0没有按下
void EXTI4_IRQHandler()
{
    delay_ms(10);
    if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)==0)
    {
        KEY0_IsDown = 1;
        EXTI_ClearFlag(EXTI_Line4);
    }else{
        KEY0_IsDown = 0;
        EXTI_ClearFlag(EXTI_Line4);
    }
}
#endif

key.c

/****************************************************************************
*按键使用模块说明
*两种:一种需要循环扫描,一种用中断
*使用方法:首先修改h头文件中的宏对按键决定是否需要外部中断,然后修改Key_Init,对哪几个按键初始化
*然后 Key_Init();,然后u8 IsKey0Down() u8 IsKey1Down() u8 IsKey2Down() u8 IsWK_UPDown()  (循环扫描)
*或者读u8 KEY0_IsDown; u8 KEY1_IsDown; u8 KEY2_IsDown; u8 WK_UP_IsDown;(中断)
*需要修改的地方,GPIO部分,中断线部分,中断优先级部分,中断函数部分
******************************************************************************/
#include "key.h"
#include "sys.h"
#include "delay.h"

void KEY0_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

#if KEY0_SUPPORT_EXTI   //支持外部中断的话,如下操作
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
#endif  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//用不同的引脚修改这里
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//该实验按键带下拉电阻,所以这里用下拉
    GPIO_Init(GPIOE, &GPIO_InitStructure);

#if KEY0_SUPPORT_EXTI//支持外部中断的话,如下操作
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);
    EXTI_InitStructure.EXTI_Line = EXTI_Line4;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     
    NVIC_Init(&NVIC_InitStructure);
#endif
}



void KEY1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
#if KEY1_SUPPORT_EXTI   //支持外部中断的话,如下操作
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
#endif  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//用不同的引脚修改这里
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//该实验按键带下拉电阻,所以这里用下拉
    GPIO_Init(GPIOE, &GPIO_InitStructure);
#if KEY1_SUPPORT_EXTI   //支持外部中断的话,如下操作
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);
    EXTI_InitStructure.EXTI_Line = EXTI_Line3;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     
    NVIC_Init(&NVIC_InitStructure);
#endif
}



void KEY2_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
#if KEY2_SUPPORT_EXTI   //支持外部中断的话,如下操作
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
#endif  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//用不同的引脚修改这里
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//该实验按键带下拉电阻,所以这里用下拉
    GPIO_Init(GPIOE, &GPIO_InitStructure);

#if KEY2_SUPPORT_EXTI   //支持外部中断的话,如下操作
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);
    EXTI_InitStructure.EXTI_Line = EXTI_Line2;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     
    NVIC_Init(&NVIC_InitStructure);
#endif
}



void WK_UP_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
#if WK_UP_SUPPORT_EXTI      //支持外部中断的话,如下操作
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
#endif  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//用不同的引脚修改这里
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//该实验按键带上拉电阻,所以这里用上拉
    GPIO_Init(GPIOA, &GPIO_InitStructure);
#if WK_UP_SUPPORT_EXTI  //支持外部中断的话,如下操作
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开复用    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//配置中断线

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     
    NVIC_Init(&NVIC_InitStructure);
#endif
}


void Key_Init(void)
{
    KEY0_Init();
    KEY1_Init();
    KEY2_Init();
    WK_UP_Init();
}

#if KEY0_SUPPORT_EXTI   //支持外部中断的话,如下操作
u8 KEY0_IsDown;//1按下 0没有按下
void EXTI4_IRQHandler()
{
    delay_ms(10);
    if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)==0)
    {
        KEY0_IsDown = 1;
        EXTI_ClearFlag(EXTI_Line4);
    }else{
        KEY0_IsDown = 0;
        EXTI_ClearFlag(EXTI_Line4);
    }
}
#endif

#if KEY1_SUPPORT_EXTI   //支持外部中断的话,如下操作
u8 KEY1_IsDown;//1按下 0没有按下
void EXTI3_IRQHandler()
{
    delay_ms(10);
    if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3)==0)
    {
        KEY1_IsDown = 1;
        EXTI_ClearFlag(EXTI_Line3);
    }else{
        KEY1_IsDown = 0;
        EXTI_ClearFlag(EXTI_Line3);
    }
}
#endif

#if KEY2_SUPPORT_EXTI   //支持外部中断的话,如下操作
u8 KEY2_IsDown;//1按下 0没有按下
void EXTI2_IRQHandler()
{
    delay_ms(10);
    if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2)== 0)
    {
        KEY2_IsDown = 1;
        EXTI_ClearFlag(EXTI_Line2);
    }else{
        KEY2_IsDown = 0;
        EXTI_ClearFlag(EXTI_Line2);
    }
}
#endif

#if WK_UP_SUPPORT_EXTI  //支持外部中断的话,如下操作
u8 WK_UP_IsDown;//1按下 0没有按下
void EXTI0_IRQHandler()
{
    delay_ms(10);
    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1)
    {
        WK_UP_IsDown = 1;
        EXTI_ClearFlag(EXTI_Line0);
    }else{
        WK_UP_IsDown = 0;
        EXTI_ClearFlag(EXTI_Line0);
    }
}
#endif



//需要循环扫描
u8 IsKey0Down()
{
    static u16 iCount = 0;
    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==0)
    {
        iCount ++;
        if(iCount>30){
            iCount = 0;
            return 1;
        }
    }else{
        iCount = 0;     
    }
    return 0;
}
u8 IsKey1Down()
{
    static u16 iCount = 0;
    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==0)
    {
        iCount ++;
        if(iCount>30){
            iCount = 0;
            return 1;
        }
    }else{
        iCount = 0;     
    }
    return 0;
}
u8 IsKey2Down()
{
    static u16 iCount = 0;
    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0)
    {
        iCount ++;
        if(iCount>30){
            iCount = 0;
            return 1;
        }
    }else{
        iCount = 0;     
    }
    return 0;
}
u8 IsWK_UPDown()
{
    static u16 iCount = 0;
    if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)
    {
        iCount ++;
        if(iCount>30){
            iCount = 0;
            return 1;
        }
    }else{
        iCount = 0;     
    }
    return 0;
}






key.h

#ifndef __KEY_H_
#define __KEY_H_

#include "stm32f10x.h"
//如果按键用外部中断,则修改下面对应按键的宏值为1

#define KEY0_SUPPORT_EXTI 1
#define KEY1_SUPPORT_EXTI 1
#define KEY2_SUPPORT_EXTI 1
#define WK_UP_SUPPORT_EXTI 1

extern u8 KEY0_IsDown;
extern u8 KEY1_IsDown;
extern u8 KEY2_IsDown;
extern u8 WK_UP_IsDown;

void KEY0_Init(void);
void KEY1_Init(void);
void KEY2_Init(void);
void WK_UP_Init(void);
void Key_Init(void);

u8 IsKey0Down(void);
u8 IsKey1Down(void);
u8 IsKey2Down(void);
u8 IsWK_UPDown(void);
#endif 

这里修改宏就可以打开和关闭按键的中断

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值