(七)独立按键

文章目录

  • 独立按键原理图
  • 三行代码法
    • 简单概述
    • 代码书写
    • 键码推算
    • 如何使用
      • 短按键
      • 长按键
        • 第一种不松手长按键
        • 第二种松手长按键
  • 状态机法
    • 简单概述
    • 代码书写
    • 键码推算
    • 如何使用
      • 短按键
      • 长按键
        • 第一种不松手长按键
        • 第二种松手长按键
  • 部分代码展示
  • 现象演示


独立按键原理图

(七)独立按键_第1张图片

三行代码法

简单概述

(七)独立按键_第2张图片

代码书写

u8 Trg = 0x00;//短按键
u8 Cont = 0x00;//长按键
void BtnThree(void)
{
	u8 readata = P3^0xff;
	Trg = readata&(readata^Cont);
	Cont = readata;
}

键码推算

键码口诀 “ 从下到上 8421”

比如:没有按键按下
readata = 0xff ^ 0xff = 0x00;
Trg = 0x00&(0x00 ^ 0x00) = 0x00;
Cont = 0x00;

比如:S7按下
readata = 0xfe ^ 0xff = 0x01;
Trg = 0x01&(0x01 ^ 0x00) = 0x01;
Cont = 0x01;
第一种情况:接着未松手(下一个10ms来了):
readata = 0xfe ^ 0xff = 0x01;
Trg = 0x01&(0x01 ^ 0x01) = 0x00;
Cont = 0x01;
第二种情况:松手了
readata = 0xff ^ 0xff = 0x00;
Trg = 0x00&(0x00 ^ 0x01) = 0x00;
Cont = 0x00;

因此可以理解:Trg 保存的是短按键状态,Cont保存的是长按键状态

如何使用

短按键

功能:
s7点亮led1
s6熄灭led1
s5点亮led1
s4熄灭led1

u8 btn_cnt =0 ;
void BtnTask()
{
	if(btn_cnt>=10){
		btn_cnt = 0;
		BtnThree();
		if((Trg&0x01)==0x01){//s7
			DeviceCtrl(0x80,0xfe);//open led1
		}
		if((Trg&0x02)==0x02){//s6
			DeviceCtrl(0x80,0xff);//open led1
		}		
		if((Trg&0x04)==0x04){//s5
			DeviceCtrl(0x80,0xfe);//open led1
		}
		if((Trg&0x08)==0x08){//s4
			DeviceCtrl(0x80,0xff);//open led1
		}		
	}
}

长按键

第一种不松手长按键

功能:
按下S7不松手 点亮LED1
松手熄灭LED1

u8 btn_cnt =0 ;
void BtnTask()
{
	if(btn_cnt>=10){
		btn_cnt = 0;
		BtnThree();
		if(Cont==0x01){		//s7为长按键
			DeviceCtrl(0x80,0xfe);//按下不松开 open led1
		}
		if((Trg==0x00)&&(Cont==0x00)){	//松手检测
			DeviceCtrl(0x80,0xff);//松手 close led1
		}	
	}
}
第二种松手长按键

功能:
按下S7达到2秒 松开 点亮LED1
按下S7未达到2秒 松开 熄灭LED1

u8 btn_cnt =0 ;
unsigned long sec =0 ;
void BtnTask()
{
	if(btn_cnt>=10){
		btn_cnt = 0;
		BtnThree();
		if(Cont==0x01){
			sec++;
		}
		if((Trg==0x00)&&(Cont==0x00)){
			if(sec>=100){ //这里计时200*10ms = 2000ms 即 2s
				sec = 0;	
				DeviceCtrl(0x80,0xfe);// 长按键2秒 松开open led1
			}else if(sec != 0){//不足2s 即 为 短按键
				sec = 0;
				DeviceCtrl(0x80,0xff);//短按键 close led1
			}else{	//没有按键按下
				sec = 0;
			}
		}
	}	
}

状态机法

简单概述

(七)独立按键_第3张图片

代码书写

u8 BtnState(void)
{
	static u8 keystate = 0;
	u8 keyreturn =0;
	u8 keypress = 0;
	
	keypress = P3&0x0f;
	
	switch(keystate){
		case 0: if(keypress!=0x0f){keystate=1;}break;
		case 1:	if(keypress!=0x0f){//确实有按键按下
							if(keypress==0x07){keyreturn = 4;break;}	//这里的break一定要写 为了 用 长按键
							if(keypress==0x0b){keyreturn = 5;break;}	//这里的break一定要写 为了 用 长按键
							if(keypress==0x0d){keyreturn = 6;break;}	//这里的break一定要写 为了 用 长按键
							if(keypress==0x0e){keyreturn = 7;break;}	//这里的break一定要写 为了 用 长按键
							keystate=2;
						}else{	//是抖动
							keystate=0;
						}
						break;
		case 2:if(keypress==0x0f){keystate=0;} break;//等待松手	
	}
	return keyreturn;
}

键码推算

键码口诀 “从下到上 7bde”
比如:S7被按下
keypress = 0x0f&0x0e = 0x0e;

如何使用

短按键

功能:
s7点亮led1
s6熄灭led1
s5点亮led1
s4熄灭led1

u8 btn_val;//缓存键码
u8 btn_cnt =0 ;
void BtnTask()
{
	if(btn_cnt>=10){
		btn_cnt = 0;
		btn_val = BtnState();//获取哪个按键被按下的键码
		if(btn_val==4){
			DeviceCtrl(0x80,0xfe);//open led1
		}
		if(btn_val==5){
			DeviceCtrl(0x80,0xff);//close led1
		}
		if(btn_val==6){
			DeviceCtrl(0x80,0xfe);//open led1
		}
		if(btn_val==7){
			DeviceCtrl(0x80,0xff);//close led1
		}
	}
}

长按键

第一种不松手长按键

功能:
按下S7不送手点亮LED1
松手熄灭LED1

u8 btn_cnt =0 ;
void BtnTask()
{
	if(btn_cnt>=10){
		btn_cnt = 0;
		btn_val = BtnState();//获取哪个按键被按下的键码
		if(btn_val==7){		// 按下s7没松手
			DeviceCtrl(0x80,0xfe);//open led1
		}else{						//按下 s7 松手了
			DeviceCtrl(0x80,0xff);//close led1
		}
	}
}
第二种松手长按键

功能:
按下S7达到2秒 松开 点亮LED1
按下S7未达到2秒 松开 熄灭LED1

u8 btn_cnt =0 ;
u32 sec = 0 ;//用来记录长按键时间
u8 btn_val  = 0;
void BtnTask()
{
	if(btn_cnt>=10){
		btn_cnt = 0;
		btn_val = BtnState();
		if(btn_val==7){
			sec++;
		}else{
			if(sec>=200){	//这里计时200*10ms = 2000ms 即 2s
				sec = 0;
				DeviceCtrl(0x80,0xfe);//open led1
			}else if(sec != 0){	
				sec = 0;
				DeviceCtrl(0x80,0xff);//close led1
			}else{
				sec = 0;
			}
		}		
	}	
}

部分代码展示

u8 btn_cnt =0 ;
u32 sec = 0 ;//用来记录长按键时间
u8 btn_val  = 0;
void BtnTask()
{
	if(btn_cnt>=10){
		btn_cnt = 0;
//三行代码法:******************************************************
		
//短按键--S4 - S7控制 LED1的亮灭
		BtnThree();
		if((Trg&0x01)){//s7
			DeviceCtrl(0x80,0xff);//close led1
		}
		if((Trg&0x02)){//s6
			DeviceCtrl(0x80,0xfe);//open led1
		}
		if((Trg&0x04)){//s5
			DeviceCtrl(0x80,0xff);//close led1
		}
		if((Trg&0x08)){//s4
			DeviceCtrl(0x80,0xfe);//open led1
		}	
		
不松手长按键-按下s7不送手点亮led1--松手熄灭led1
//		BtnThree();
//		if(Cont==0x01){		//s7为长按键
//			DeviceCtrl(0x80,0xfe);//按下不松开 open led1
//		}
//		if((Trg==0x00)&&(Cont==0x00)){	//松手检测
//			DeviceCtrl(0x80,0xff);//松手 close led1
//		}		

松手长按键--按下S7达到2秒 松开 点亮LED1 --按下S7未达到2秒 松开 熄灭LED1
//		BtnThree();
//		if(Cont==0x01){
//			sec++;
//		}
//		if((Trg==0x00)&&(Cont==0x00)){
//			if(sec>=100){ //这里计时200*10ms = 2000ms 即 2s
//				sec = 0;	
//				DeviceCtrl(0x80,0xfe);//长按键2秒 松开open led1
//			}else if(sec != 0){//不足2s 即 为 短按键
//				sec = 0;
//				DeviceCtrl(0x80,0xff);//短按键 close led1
//			}else{	//没有按键按下
//				sec = 0;
//			}
//		}

//状态机:**********************************************************	

 短按键功能与三行代码法 一致		
//		btn_val = BtnState();//获取哪个按键被按下的键码
//			if(btn_val==4){
//			DeviceCtrl(0x80,0xfe);//open led1
//		}
//		if(btn_val==5){
//			DeviceCtrl(0x80,0xff);//close led1
//		}
//		if(btn_val==6){
//			DeviceCtrl(0x80,0xfe);//open led1
//		}
//		if(btn_val==7){
//			DeviceCtrl(0x80,0xff);//close led1
//		}

不松手长按键:功能同三行代码法的不松手长按键
//		btn_val = BtnState();//获取哪个按键被按下的键码
//		if(btn_val==7){		// 按下s7没松手
//			DeviceCtrl(0x80,0xfe);//open led1
//		}else{						//按下 s7 松手了
//			DeviceCtrl(0x80,0xff);//close led1
//		}

松手长按键:功能同三行代码法的松手长按键 
//		btn_val = BtnState();
//		if(btn_val==7){
//			sec++;
//		}else{
//			if(sec>=200){	//这里计时200*10ms = 2000ms 即 2s
//				sec = 0;
//				DeviceCtrl(0x80,0xfe);//open led1
//			}else if(sec != 0){	
//				sec = 0;
//				DeviceCtrl(0x80,0xff);//close led1
//			}else{
//				sec = 0;
//			}
//		}
		
	}	
}

现象演示

(七)独立按键



----- 如有错误欢迎大家批评指正!!!

你可能感兴趣的:(蓝桥杯电子类,蓝桥杯,单片机,c语言)