按键分为机械按键和(电容式/电阻式)触摸按键。
机械按键需要消抖操作,触摸按键灵敏度高可以不进行消抖处理。
按键单击属于常规操作,而双击和滑动如何实现呢?
双击判断:
在按键按下并松开后,在一段规定的时间内,判断按键是否再次按下,如果再次按下,即属于双击操作,注意这段规定的时间较短(几十几百毫秒)。
长按判断:
按键按下并维持一段规定的时间,即可判断是长按操作,注意这段规定的时间较长(几秒)。
滑动操作:
从A键滑动到B键,如何判断是滑动而不是A键和B键分别单击:当A键按下并在快松开时同时按住了A键和B键,然后松开A键并按住B键,中间有一个同时按住AB键的时隙,此操作即可判断是滑动。
代码如下:
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "touch_key.h"
#include "usart.h"
#define KEYA_SPEED1 100 //长按的时间长度(单位10mS),总共1S
#define KEYA_SPEED2 10 //双击的时间长度(单位20mS),总共200ms
int main (void){//主程序
u16 k=1000; //用于滑动加减计数
u8 a=0,b,c=0;
u8 s=0; //刚刚结束滑动标志
RCC_Configuration(); //系统时钟初始化
USART1_Init(115200); //串口初始化,参数中写波特率
LED_Init();//LED初始化
TOUCH_KEY_Init();//按键初始化
while(1)
{
//A
if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)) //检测按键是否按下
{
delay_ms(20); //延时去抖动
if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)) //判断长短键
{
while((!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2))&&c<KEYA_SPEED1) //循环判断长按,到时跳转
{
c++;
delay_ms(10); //长按判断的计时,1S
}
if(c>=KEYA_SPEED1) //长键处理
{
//长按后执行的程序放到此处
GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(0));//LED控制
printf("A键长按 \r\n");
while(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)); //等待按键松开
}
else //单击处理
{
if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)) //判断B键按下
{
k++; //用于显示的计数值
printf("A键右滑 %d \r\n",k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0)
{
for(b=0;b<KEYA_SPEED2;b++) //检测双击
{
delay_ms(20);
if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2))
{
a=1;
//双击后执行的程序放到此处
GPIO_WriteBit(GPIOE,GPIO_Pin_5,(BitAction)(0));//LED控制
printf("A键双击 \r\n");
while(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)); //等待按键松开
}
}
if(a==0) //判断单击
{
if(s==1) //判断是不是刚执行完滑动操作
{
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}
else //如果不是,则正常执行单击处理
{
//单击后执行的程序放到此处
//GPIO_WriteBit(LEDPORT,LED1|LED2,(BitAction)(0));//LED控制
GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1));
GPIO_WriteBit(GPIOE,GPIO_Pin_5,(BitAction)(1));
printf("A键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
}
}
}
代码解析:
首先判断是否长按(低电平维持1秒),然后判断是否右滑(B键同时按下),然后判断是否双击(200毫秒内再次按下按键),如果都不是即是单击。
实验现象:
声明:此文参考杜洋老师的STM32教学。