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

来源:互联网 发布:网络歌曲想问问你慢四 编辑:程序博客网 时间:2024/06/08 08:48

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

第一种方法:扫描查询法

优点:无延迟,高灵敏,无中断
思想:也是别人的代码总结出来的,当按键连续读到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 1extern 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 

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

阅读全文
1 0
原创粉丝点击