按键短按、长按,双击
- /*记录按键按下时间 时间小于1.5S,按键为短按;时间大于1.5S,按键为长按*/
- volatile unsigned int key1_timing = 0;
- /*记录两次短按之间的时间间隔*/
- volatile unsigned int key1_doublepress_timing = 0;
- /*定义按键键值结构体*/
- Key_Value k1_value;
- /*K1按键短按标志位*/
- bool k1_shortpress_happen = 0;
- /*K1按键长按标志位*/
- bool k1_longpress_happen = 0;
- /*K1按键双击标志位*/
- bool k1_doublepress_happen = 0;
- /*led1闪烁时间标志位,主函数检测到此标志位为1时,led1开始闪烁,否则,结束闪烁*/
- bool led1_flash_flag = 0;
- /*3个led全部闪烁标志位,主函数检测到此标志为1时,三个led灯开始同时闪烁,否则结束闪烁*/
- bool led_all_flash_flag = 0;
- /*流水灯事件标志位*/
- /*按键键值扫描函数*/
- void Key_Scan(void)
- {
- /*程序不支持两个按键同时按下*/
- // if((K1==0&&K2==0) || (K1==0&&K3==0) || (K2==0&&K3==0))
- // return ;
- if(K1==0) //当K1按键按下
- {
- if(k1_shortpress_happen==0)
- {
- k1_shortpress_happen = 1; //开始一次按键键值扫描
- key1_timing = 0; //按键按下计时变量清0,开始计时,此值每1ms加1,sysclk中断函数中实现自加
- }
- if(k1_shortpress_happen==1)
- {
- if(key1_timing > 1500) //按键按下时间超过1.5S,长按事件发生,置k1_value.long_press为1
- {
- k1_value.long_press = 1;
- k1_shortpress_happen = 0; //按键短按标志位置0
- }
- }
- }
- if(K1==1) //当K1按键抬起
- {
- if(k1_shortpress_happen==1) //按键抬起后,k1_shortpress_happen等于1,说明按键为短按,不是长按
- {
- k1_shortpress_happen = 0;
- if(k1_doublepress_happen==0)
- {
- k1_doublepress_happen = 1; //按键双击标志位置1,等待确认按键是否为双击
- key1_doublepress_timing = 0; //开始计时,同样1ms自增加1
- }
- else
- {
- if(key1_doublepress_timing < 500) //第一次短按发生后,在500ms时间内,发生第二次短按,完成一次双击,跟新按键键值
- {
- k1_doublepress_happen = 0;
- k1_value.double_press = 1;
- }
- }
- }
- else
- if(k1_doublepress_happen == 1) //第一次短按后,等待500ms,如未再发生短按,跟新按键短按键值
- {
- if(key1_doublepress_timing > 500)
- {
- k1_doublepress_happen = 0;
- k1_value.short_press = 1;
- }
- }
- else
- if(k1_longpress_happen==1)
- k1_longpress_happen = 0;
- }
- }
{
KeyDown,
KeyUp,
KeyShort,
KeyLong
}KEYSTATE;
KEYSTATE KeyState;
void PollingKey(void)
{
static u8 KeyStep;
switch (KeyStep)
{
case 0:
{
if (!KeyPin)//有键按下
{
//printf("\r\n按下");
KeyState = KeyDown;
if (KeyDoubleTimes > 0)
{
KeyStep = 4;//双击
}
else
{
KeyStep = 2;//不是双击
}
}
else if(KeyDoubleTimes > 0)
{
KeyDoubleTimes--;
if ((KeyDoubleTimes == 0)&&(KeyState == KeyShort))
{
printf("\r\n短按处理");
KeyState = KeyUp;
}
}
}
break;
case 1://按下
{
if (!KeyPin)
{
KeyDownTimes++;
if (KeyDownTimes < 2800)
{
KeyState = KeyShort;
}
else if(KeyState != KeyLong)
{
KeyState = KeyLong;
printf("\r\n长按处理");
}
else if (KeyDownTimes >= 2800)//防止加满溢出
{
KeyDownTimes = 2800;
}
}
else
{
KeyStep = 2;
}
}
break;
case 2://
{
if (KeyPin)//弹起
{
KeyStep = 3;
}
else//按下
{
KeyStep = 1;
}
}
break;
case 3://弹起
{
if (KeyPin)//弹起
{
if (KeyDownTimes < 2800)
{
KeyDoubleTimes = 500;
}
KeyDownTimes = 0;
KeyStep = 0;
}
else
{
KeyStep = 2;
}
}
break;
case 4:
{
if (KeyPin)//如果弹起的话就执行
{
KeyState = KeyUp;
printf("\r\n双击处理");
KeyStep = 0;
}
}
break;
default:
KeyStep = 0;
break;
}
delay_us(100);
}
(3)
题目:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。 在正常0.5s内无按键操作为启始按键扫描条件下,扫描按键将产生以下3种按键事件: 特别操作情况定义: 对按键操作者的建议: 对软件设计者的要求: /*============= #define key_input PIND.7 // 按键输入口 #define N_key 0 //无键 #define key_state_0 0 unsigned char key_driver(void) key_press = key_input; // 读按键I/O电平 switch (key_state) case key_state_3: // 等待按键释放状态,此状态只返回无按键事件 /*============= unsigned char key_read(void) case key_state_1: 下面,根据程序分析按键事件的反映时间: 当然,上面两段可以合在一起。我这样做的目的,是为了可以方便的扩展为N击(当然,需要做修改)。可是最底层的就是最基本的操作处理短按和长按,不用改动的。至于双击,还是N击,在中间层处理。这就是程序设计中分层结构的优点。 测试代码环境如下: interrupt [TIM0_COMP] void timer0_comp_isr(void) // 定时器10ms中断服务 main(viod) while (4)https://blog.csdn.net/su_fei_ma_su/article/details/105091193?utm_medium=distribute.pc_relevant.none-task-blog-title-11&spm=1001.2101.3001.4242 (5)51单片机学习笔记:基于状态机的按键对时程序(短按,长按,连发)4个独立按键中用到3个, keys5用于切换对时分秒等状态,keys2是减小数值,keys3是增加数值 同时可以判断按键的"短按,长按,连发"等功能 小于2秒视为短按, 大于2秒视为长按, 在长按状态下每0.2秒自动连发一次, 这样对时的时候就不用按N次了 欢迎一起交流,qq 102351263 验证码 iteye 程序分很多个文件 ,Keil uVision4 打包 #include "MY51.H" #include "keyScan.h" #include "smg.h" #include "myClock.h"void show(); //数码管显示extern s8 shi; extern s8 fen; extern s8 miao; extern u8 changeTimeFlag; extern u8 timeMultipleFlag;void main() {startT0(10,100); //开T0启定时器 10毫秒*100=1秒while(1){show(); } }void T0_Work() //T0定时器调用的工作函数 {u8 key_stateValue;u8* pKeyValue;*pKeyValue=0;key_stateValue=read_key(pKeyValue);if(timeMultipleFlag) //到1秒了{timeMultipleFlag=0; //标志清零clock(); //走时,秒++}if( (return_keyPressed==key_stateValue)&&(*pKeyValue==KEYS5_VALUE) ){ //短按keyS5时改变对时状态changeTimeState(); //改变changeTimeFlag的3种状态,分别修改时或分或秒}if((return_keyPressed==key_stateValue)||(key_stateValue&return_keyAuto) ){ //短按s2或s3可加减响应数值,长按keyS2或keyS3时每0.1秒加减一次数值if(changeTimeFlag) //changeTimeFlag不为0时,允许修改{if(KEYS2_VALUE == *pKeyValue){changeTime(TRUE); //KEYS2,秒++}if(KEYS3_VALUE == *pKeyValue){changeTime(FALSE); //KEYS3,秒--}}} }void show() //显示时钟 {u8 oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela; //oneWela是最左边的数码管sixWela =miao%10;fiveWela=miao/10; foreWela=fen%10;threeWela=fen/10;twoWela=shi%10;oneWela=shi/10;displaySMG(oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela,0xf5); //0xf5是小数点的位置 } #ifndef _MY51_H #define _MY51_H #include <reg52.h> #include <math.h> #include <intrins.h> #include "mytype.h"#define high 1 //高电平 #define low 0 //低电平#define led P1 //灯总线控制 sbit led0=P1^0; //8个led灯,阴极送低电平点亮 sbit led1=P1^1; sbit led2=P1^2; sbit led3=P1^3; sbit led4=P1^4; sbit led5=P1^5; sbit led6=P1^6; sbit led7=P1^7;sbit lcdEN=P3^4; //液晶通讯使能端en,高脉冲有效 sbit lcdRS=P3^5; //液晶第4脚,RS,低电平是指令模式,高电平是数据模式 //sbit lcdR/W //液晶第5脚,低电平是写入模式,因为我们只写不读,所以接地sbit csda=P3^2; //DAC0832模数转换cs口 sbit adwr=P3^6; //ADC0804这个同DAC0832 sbit dawr=P3^6; sbit adrd=P3^7; //ADC0804 sbit beep=P2^3; //蜂鸣器void delayms(u16 ms); void T0_Work(); void startT0(u32 ms,u16 t_multiple); ////#endif #include "MY51.h"u8 TH0Cout=0 ; //初值 u8 TL0Cout=0 ; u16 T0IntCout=0; //中断计数 u16 timeMultiple=0; //中断复用时间的倍数 u8 timeMultipleFlag=0; //中断时间复用置位标志void delayms(u16 ms) //软延时函数 {u16 i,j;for(i=ms;i>0;i--){for(j=113;j>0;j--){}} }//开启定时器,定时完成后需要手动关闭TR0,否则将循环定时 //参数一是定时的毫秒数,参数二是定时的倍率数(定时复用) void startT0(u32 ms,u16 t_multiple) //定时器初始化设定 { u32 N=11059.2*ms/12; //定时器总计数值TH0Cout =(65536-N)/256; //装入计时值零头计数初值TL0Cout =(65536-N)%256;timeMultiple=t_multiple;TMOD=TMOD | 0x01; //设置定时器0的工作方式为1EA =OPEN; //打开总中断ET0=OPEN; //打开定时器中断TH0=TH0Cout; //定时器装入初值TL0=TL0Cout;TR0=START; //启动定时器 }/* 方法二,此方法用于长时间的定时,以利于减少中断次数,减小误差 void startT0(u32 one_ms,u16 two_multiple) { u32 N=11059.2*one_ms/12; //定时器总计数值TH0Cout =(65536-N%65536)/256; //装入计时值零头计数初值TL0Cout =(65536-N%65536)%256;T0IntCountAll=(N-1)/65536+1; //总中断次数T0IntCountAll2=T0IntCountAll*two_multiple;TMOD=TMOD | 0x01; //设置定时器0的工作方式为1EA =OPEN; //打开总中断ET0=OPEN; //打开定时器中断TH0=TH0Cout; //定时器装入初值TL0=TL0Cout;TR0=START; //启动定时器 }*/void T0_times() interrupt 1 //T0定时器中断函数 {TH0=TH0Cout; TL0=TL0Cout;T0IntCout++;if(T0IntCout==timeMultiple) //复用定时器{ T0IntCout=0; //中断次数清零,重新计时timeMultipleFlag=1;}T0_Work(); //调用工作函数 } #ifndef _MYTYPE_H #define _MYTYPE_H/typedef float f32 ; typedef double d64 ; typedef float const fc32 ; typedef double const dc64 ; typedef volatile float vf32 ; typedef volatile double vd64 ; //typedef volatile float const vfc32 ; //typedef volatile double const vdc64 ; //typedef signed long s32; typedef signed short s16; typedef signed char s8;typedef signed long const sc32; /* Read Only */ typedef signed short const sc16; /* Read Only */ typedef signed char const sc8; /* Read Only */typedef volatile signed long vs32; typedef volatile signed short vs16; typedef volatile signed char vs8;//typedef volatile signed long const vsc32; /* Read Only */ //typedef volatile signed short const vsc16; /* Read Only */ //typedef volatile signed char const vsc8; /* Read Only */typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8;typedef unsigned long const uc32; /* Read Only */ typedef unsigned short const uc16; /* Read Only */ typedef unsigned char const uc8; /* Read Only */typedef volatile unsigned long vu32; typedef volatile unsigned short vu16; typedef volatile unsigned char vu8;//typedef volatile unsigned long const vuc32; /* Read Only */ //typedef volatile unsigned short const vuc16; /* Read Only */ //typedef volatile unsigned char const vuc8; /* Read Only */typedef enum {FALSE = 0, TRUE = !FALSE} bool;typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;typedef enum {CLOSE = 0, OPEN = !CLOSE} OPEN_CLOSE; typedef enum {GND = 0, VCC = !GND} GND_VCC; typedef enum {NO = 0, YES = !NO} YES_NO; typedef enum {STOP = 0, START = !STOP} START_STOP;#define U8_MAX ((u8)255) #define S8_MAX ((s8)127) #define S8_MIN ((s8)-128) #define U16_MAX ((u16)65535u) #define S16_MAX ((s16)32767) #define S16_MIN ((s16)-32768) #define U32_MAX ((u32)4294967295uL) #define S32_MAX ((s32)2147483647) #define S32_MIN ((s32)-2147483648)#endif #ifndef _KEYSACN_H #define _KEYSACN_H #include <reg52.h> #include "mytype.h"#define state_keyUp 0 //初始状态,未按键 #define state_keyDown 1 //键被按下 #define state_keyLong 2 //长按 #define state_keyTime 3 //按键计时态#define return_keyUp 0x00 //初始状态 #define return_keyPressed 0x01 //键被按过,普通按键 #define return_keyLong 0x02 //长按 #define return_keyAuto 0x04 //自动连发#define key_down 0 //按下 #define key_up 0xf0 //未按时的key有效位键值 #define key_longTimes 200 //10ms一次,200次即2秒,定义长按的判定时间 #define key_autoTimes 20 //连发时间定义,20*10=200,200毫秒发一次sbit keyS2=P3^4; //4个独立按键 sbit keyS3=P3^5; sbit keyS4=P3^6; sbit keyS5=P3^7;#define KEYS2_VALUE 0xe0 //keyS2 按下 #define KEYS3_VALUE 0xd0 //keyS3 按下 #define KEYS4_VALUE 0xb0 //keyS4 按下 #define KEYS5_VALUE 0x70 //keyS5 按下//void KeyInit(void); //初始化,io口未复用时可省略此步 static u8 getKey(void); //获取P口的连接key的io值,其他io位屏蔽为0 u8 read_key(u8* pKeyValue); //返回按键的各种状态,pKeyValue保存键值#endif #include "keyScan.h" #include <reg52.h>/*按键初始化,若io没有复用的话可以省略此步骤 void KeyInit(void) { keyS2 = 1 ; keyS3 = 1 ; keyS4 = 1 ; keyS5 = 1 ;//即P3|=0xf0; }*/static u8 getKey(void) //获取P3口值 { if(key_down == keyS2){return KEYS2_VALUE ; }if(key_down == keyS3 ){return KEYS3_VALUE ; }if(key_down == keyS4 ){return KEYS4_VALUE ;}if(key_down == keyS5 ){return KEYS5_VALUE ; }return key_up ; //0xf0 没有任何按键 }//函数每10ms被调用一次,而我们弹性按键过程时一般都20ms以上 //所以每次按键至少调用本函数2次 u8 read_key(u8* pKeyValue) {static u8 s_u8keyState=0; //未按,普通短按,长按,连发等状态static u16 s_u16keyTimeCounts=0; //在计时状态的计数器static u8 s_u8LastKey = key_up ; //保存按键释放时的P3口数据u8 keyTemp=0; //键对应io口的电平s8 key_return=0; //函数返回值keyTemp=key_up & getKey(); //提取所有的key对应的io口switch(s_u8keyState) //这里检测到的是先前的状态{case state_keyUp: //如果先前是初始态,即无动作{if(key_up!=keyTemp) //如果键被按下{s_u8keyState=state_keyDown; //更新键的状态,普通被按下 }}break;case state_keyDown: //如果先前是被按着的{if(key_up!=keyTemp) //如果现在还被按着{s_u8keyState=state_keyTime; //转换到计时态s_u16keyTimeCounts=0;s_u8LastKey = keyTemp; //保存键值}else{s_u8keyState=state_keyUp; //键没被按着,回初始态,说明是干扰}}break;case state_keyTime: //如果先前已经转换到计时态(值为3){ //如果真的是手动按键,必然进入本代码块,并且会多次进入if(key_up==keyTemp) //如果未按键{s_u8keyState=state_keyUp; key_return=return_keyPressed; //返回1,一次完整的普通按键//程序进入这个语句块,说明已经有2次以上10ms的中断,等于已经消抖//那么此时检测到按键被释放,说明是一次普通短按}else //在计时态,检测到键还被按着{if(++s_u16keyTimeCounts>key_longTimes) //时间达到2秒{s_u8keyState=state_keyLong; //进入长按状态s_u16keyTimeCounts=0; //计数器清空,便于进入连发重新计数key_return=return_keyLong; //返回state_keyLong}//代码中,在2秒内如果我们一直按着key的话,返回值只会是0,不会识别为短按或长按的}}break;case state_keyLong: //在长按状态检测连发 ,每0.2秒发一次{if(key_up==keyTemp) {s_u8keyState=state_keyUp; }else //按键时间超过2秒时{if(++s_u16keyTimeCounts>key_autoTimes)//10*20=200ms{s_u16keyTimeCounts=0;key_return=return_keyAuto; //每0.2秒返回值的第2位置位(1<<2)}//连发的时候,肯定也伴随着长按}key_return |= return_keyLong; //0x02是肯定的,0x04|0x02是可能的}break;default:break;}*pKeyValue = s_u8LastKey ; //返回键值return key_return; } #ifndef _51SMG_H_ #define _51SMG_H_#include <reg52.h> #include "mytype.h" sbit dula =P2^6; //段选锁存器控制 控制笔段 sbit wela =P2^7; //位选锁存器控制 控制位置#define dark 0x11 //在段中,0x11是第17号元素,为0是低电平,数码管不亮 #define dotDark 0xff //小数点全暗时void displaySMG(u8 one,u8 two,u8 three,u8 four,u8 five,u8 six,u8 dot); //数码管显示函数#endif #include "smg.h" #include "my51.h"u8 code table[]= { //0~F外加小数点和空输出的数码管编码0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 30x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 70x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B0x39 , 0x5e , 0x79 , 0x71 , // C D E F0x80 , 0x00 ,0x40 // . 空 负号 空时是第0x11号也就是第17号元素};u8 code dotTable[]={ //小数点位置0xff , //全暗0xfe , 0xfd , 0xfb , //1 2 30xf7 , 0xef , 0xdf //4 5 6 };//数码管显示 void displaySMG(u8 oneWela,u8 twoWela,u8 threeWela,u8 fourWela,u8 fiveWela,u8 sixWela,u8 dot) { //控制6位数码管显示函数,不显示的位用参数dark,保留ADC0804的片选信号u8 csadState=0x80&P0; //提取最高位,即ADC0804的片选信号u8 tempP0=((csadState==0)?0x7f:0xff); //数码管位选初始信号,阴极全置高电平P0=tempP0; //0x7f表示数码管不亮,同时ADC0804片选有效wela=1; //注:wela和dula上电默认为1P0=tempP0;wela=0;P0=0; //由于数码管是共阴极的,阳极送低电平,灯不亮,防止灯误亮dula=1;P0=0;dula=0; //段选数据清空并锁定 //oneWela{ //消除叠影,数码管阴极置高电平,并锁存P0=tempP0;wela=1; P0=tempP0;wela=0;}P0=0; //低电平送到数码管阳极,避免数码管误亮dula=1;P0=table[oneWela]|((0x01&dot)?0x00:0x80); //送段数据,叠加小数点的显示dula=0;P0=tempP0; //送位数据前关闭所有显示,并保持csad信号wela=1;P0=tempP0 & 0xfe; //0111 1110最高位是AD片选,低6位是数码管位选,低电平有效wela=0;delayms(1);/twoWela{ //消除叠影P0=tempP0;wela=1; P0=tempP0;wela=0;}P0=0;dula=1;P0=table[twoWela]|((0x02&dot)?0x00:0x80);dula=0;P0=tempP0;wela=1;P0=tempP0 & 0xfd; //0111 1101wela=0;delayms(1);/threeWela{ //消除叠影P0=tempP0;wela=1; P0=tempP0;wela=0;}P0=0;dula=1;P0=table[threeWela]|((0x04&dot)?0x00:0x80);dula=0;P0=tempP0;wela=1;P0=tempP0 & 0xfb; //0111 1011wela=0;delayms(1);/fourWela{ //消除叠影P0=tempP0;wela=1; P0=tempP0;wela=0;}P0=0;dula=1;P0=table[fourWela]|((0x08&dot)?0x00:0x80);dula=0;P0=tempP0;wela=1;P0=tempP0 & 0xf7; //0111 0111wela=0;delayms(1);/fiveWela{ //消除叠影P0=tempP0;wela=1; P0=tempP0;wela=0;}P0=0;dula=1;P0=table[fiveWela]|((0x10&dot)?0x00:0x80);dula=0;P0=tempP0;wela=1;P0=tempP0 & 0xef; //0110 1111wela=0;delayms(1);/sixWela{ //消除叠影P0=tempP0;wela=1; P0=tempP0;wela=0;}P0=0;dula=1;P0=table[sixWela]|((0x20&dot)?0x00:0x80);dula=0;P0=tempP0;wela=1;P0=tempP0 & 0xdf; //0101 1111wela=0;delayms(1); } #ifndef _MYCLOCK_H #define _MYCLOCK_H #include "mytype.h" #include "my51.h"void clock(void); //走时 void changeTimeState(void); //改变对时状态 void changeTime(bool add_or_sub); //修改时间,true为增加,false为减少 #endif #include "myClock.h"u8 changeTimeFlag=0; s8 shi=22; //对时 s8 fen=45; s8 miao=0; void clock(void) {if(!changeTimeFlag) //不在对时状态{miao++;if(miao>59){miao=0;fen++;}if(fen>59){fen=0;shi++;} if(shi>23){shi=0;}} }void changeTimeState(void) //在满足条件时改变对时状态,时或分或秒,同时改变指示灯 {changeTimeFlag=(++changeTimeFlag)%4;switch(changeTimeFlag){case 0:{led=0xff; }break;case 1:{led=0xff;led7=0;}break;case 2:{led=0xff;led5=0;}break;case 3:{led=0xff;led3=0;}break;default:break;} }void changeTime(bool add_or_sub) //修改时分秒 {if(add_or_sub){switch(changeTimeFlag){case 1:{shi++;if(shi>23){shi=0;} }break;case 2:{fen++;if(fen>59){fen=0;}}break;case 3:{miao++;if(miao>59){miao=0;}}break;default:break;}}else{switch(changeTimeFlag){case 1:{shi--;if(shi<0) {shi=23;} }break;case 2:{fen--;if(fen<0){fen=59;}}break;case 3:{miao--;if(miao<0){miao=59;}}break;default:break;} } } |
按键短按、长按,双击相关推荐
- 按键短按长按连发双击
功能:实现按键 长按 短按 连发 双击 处理 平台:GD32 用到的外设:GPIO.定时器 作者:霍宏鹏 交流:1045338804@qq.com /************************* ...
- STM32超级简便的按键代码 只需三行 可实现短按+长按
[蓝桥杯]STM32三行按键详解 长按 短按 用的是国信长天的嵌入式方向的开发板,使用的芯片是STM32F103RBT6,基于stm32f1的固件库编程. 当初写下这篇博客的本意也是让自己的知识更加巩 ...
- STM32-蓝桥杯嵌入式之三行按键检测(按键的长、短,单击、双击)
STM32-蓝桥杯嵌入式之三行按键检测(按键的长.短,单击.双击) 目录 STM32-蓝桥杯嵌入式之三行按键检测(按键的长.短,单击.双击) 一.检测按键下降沿分析 二.检测按键上升沿分析 三.按键检 ...
- 51单片机——矩阵按键逐行扫描短按长按一直按方案1.2
1.删减了<51单片机--独立按键.矩阵按键多种方案1.1>里的一些不怎么用的代码. 2.添加了逐行扫描按键(需要定时器20毫秒配合使用). 3.支持按键短按.长按.一直按,代码里只做了短 ...
- stm32f407zgt6的KEY实例:长按键+短按键(查询方法,非中断)+LCD显示
1.实验目的 按键key.h 按键key.c 的理解和使用,修改 使用查询方式进行判断按键 返回按键长按的数值,和短按的数值 2.实验理论 短按和长按 按下- 判断是不是等于0 ----延时去抖动 - ...
- 51单片机学习笔记:基于状态机的按键对时程序(短按,长按,连发)
之前的电子钟程序中,用的按键消抖处理方法是10ms的延时,这种方法效率比较低 所以现在利用状态机原理重写一下,效率很高啊 4个独立按键中用到3个, keys5用于切换对时分秒等状态,keys2是减小数 ...
- 单片机按键检测程序c语言,单片机检测按键短击,连击c程序
/****************************************************************************/ //文 件 名:key.c //功 能:短 ...
- [Android开发] 从后台恢复前台界面需要输入密码的demo|监听Home短按长按锁屏
一.效果图 二.实现原理 通过接收系统广播来判断home按键,广播Application全局,在接收到广播的时候在BaseActivity的onStop里面打开输入密码的对话框,再次回到界面就已经是显 ...
- 【按键】[独立按键] - 1: 单击,双击,三击以及N击
此按键程序的实现的功能是单个独立按键的[单击],[长按],[双击],[三击]以及[多击].本文分为三个部分, 第一个部分是说[单击],[长按]的程序: 第二部分是讲[双击]: 第三部分是讲[三击],[ ...
- LeetCode简单题之按键持续时间最长的键
题目 LeetCode 设计了一款新式键盘,正在测试其可用性.测试人员将会点击一系列键(总计 n 个),每次一个. 给你一个长度为 n 的字符串 keysPressed ,其中 keysPressed ...
最新文章
- Spring集成Redis方案(spring-data-redis)(基于Jedis的单机模式)(待实践)
- Class.forName 和 ClassLoader 到底有啥区别?
- 一起玩树莓派3+手把手带您入门树莓派(3000字+超详细图解版)
- Windows下配置IDEA开发环境
- RandomizedSearchCV 和GridSearchCV
- [詹兴致矩阵论习题参考解答]习题1.3
- SQL ROW_NUMBER() OVER函数的基本用法用法
- java 子类必须实现_Java学习之接口的子类必须实现接口的全部方法吗?
- python 选择文件对话框插件_[ PyQt入门教程 ] PyQt5基本控件使用:消息弹出、用户输入、文件/目录选择对话框...
- java报错信息怎么看_AE-E3D插件无效或提示OPENGL E3D Debug等错误报错信息怎么办?...
- Python学习——编码转换
- java可选参数_Java可选
- invocation, 作者 Medwyn Goodall,女巫医 [搜索 invocation Medwyn Goodall]
- 多元统计分析matlab,matlab与应用多元统计分析..doc
- 【找规律】求123456789的第几个全排列
- Centos Linux破解开机密码
- 4484: [Jsoi2015]最小表示(拓扑序+bitset维护连通性)
- 微信小程序刷新当前页面
- EasyCVR出现只有HLS协议可播放,其他协议均无法播放是什么原因?
- Sql Server 时间格式转换
热门文章
- Django基础(16): 模板标签(tags)的介绍及如何自定义模板标签
- mysql查看cpu使用率_MySQL高CPU使用率
- 12306崩了,90%的人都用过这三款抢票工具
- 山重水复疑无路 柳暗花明又一村
- 如何让Bing快速收录你的网站?
- 【线性代数(6)】范德蒙德行列式及克莱姆法则
- 情境领导者的三体思维
- 将文件夹压缩成zip文件的php代码、实现批量下载
- unbuntu 安装vscode
- xampp运行不成功或者安装过程中提示找不到文件“-n”,没有安装vcredist_x86的解决方法