KEY.h
#ifndef __KEY_
#define __KEY_
void KEY_Init(void);
uint8_t GET_KeyNum(void);
#endif
KEY.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
void KEY_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStruct);
}
uint8_t GET_KeyNum(void)
{
uint8_t KeyNum = 0;
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0);//如果按键一直处于按下状态,则卡在这里,直到松手才把按键状态返回
Delay_ms(20);
KeyNum = 1;
}
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0);//如果按键一直处于按下状态,则卡在这里,直到松手才把按键状态返回
Delay_ms(20);
KeyNum = 2;
}
return KeyNum;
}
main.c
#include "stm32f10x.h" // Device header
#include "LED.h"
#include "KEY.h"
uint8_t KeyNum;
int main(void)
{
LED0_Init();
KEY_Init();
while(1)
{
KeyNum = GET_KeyNum();
if(KeyNum == 1){
LED0_On();
}
if(KeyNum == 2){
LED0_Off();
}
}
}
不推荐用EXTI中断触发按键事件:
按键的信号不是转瞬即逝的
不好处理按键抖动
推荐使用定时器中断
如果不消抖,CPU可能会误处理
怎么判断按键按下?
两种判定:
1、按下就处理(下降沿触发)
2、弹起才处理(上升沿触发)
下面介绍“按下就处理“(下降沿触发)的情况:
1)读取一次电平,只有检测到高电平,才继续处理
2)消抖20ms
3)在读取一次电平,若此时未低电平,才认为是一次按键事件。
对于可支持连按的模式(一次按键动作,无论停留多久,只算作一次按键事件),对于GPIO_ReadInputDataBit
这一函数,我们只能知道当前电平高低,如读取到的是低电平,我们无法判断是
连按模式
如何在此基础上,修改代码,变为非连按模式?
首先,增加上次一按键状态检测机制,即只有当第一次读取按键状态为弹起时,防抖后,再当第二次读取时,为按下状态,才认为是一次按键事件。
1)定义一个参数:标记当前按键是否按下
2)按键标记为弹起且检测到按键高电平->防抖->按键标记为按下,再读取一次,若为低电平,则认为是一次按键事件。
其中,当已经进行过一次按键事件,但此时按键未松开,且主函数重新运行一次到该按键扫描函数,此时按键标记为按下,就算检测到高电平,也无法触发按键入口;
再一次,主函数再一次运行到扫描函数,此时按键已经松开,读取到的是高电平,重置按键标记为弹起;
以上,一次按键事件彻底结束。
其中,是否支持连续按,最重要的是按下标志位文章来源:https://www.toymoban.com/news/detail-660763.html
文章来源地址https://www.toymoban.com/news/detail-660763.html
到了这里,关于KEY按键的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!