(八)矩阵按键

发布时间:2024年01月05日

本章学习类比独立按键

矩阵按键原理图

在这里插入图片描述

三行代码法

简单概述

同上篇文章(七)独立按键

代码书写

//矩阵按键——三行代码
u8 GetIoThree()
{
	u8 keyio = 0xff;
	P3 = 0xf0;P4 =0xff;
	if(P44==0){keyio = 0x70;}
	if(P42==0){keyio = 0xb0;}
	if(P35==0){keyio = 0xd0;}
	if(P34==0){keyio = 0xe0;}
	P3 = 0x0f;P4 =0x00;
	if(P33==0){keyio |= 0x07;}
	if(P32==0){keyio |= 0x0b;}
	if(P31==0){keyio |= 0x0d;}
	if(P30==0){keyio |= 0x0e;}	
	
	return keyio;	
}

u8 KTrg =0;
u8 KCont =0;
void BbdThree()
{
	u8 readdata = GetIoThree()^0xff;
	KTrg = readdata&(readdata^KCont);
	KCont = readdata;
}

键码推算

口诀“从左下到右上依次 8421 列在前 行在后”
在这里插入图片描述

比如:
S4 先看列 对应8 再看行 对应8 则 键码就是 0x88
S6 列对应8 行对应2 则 键码就是 0x82
s9 列对应4 行对应4 则 键码就是0x44
s15 列对应2 行对应1 则 键码就是0x21
s19 列对应1 行对应1 则键码就是0x11

如何使用

短按键

功能描述:S4,S9,S14,S19,数码管刷新界面的切换

u8 kbd_cnt =0 ;
void KbdTask()
{
	if(kbd_cnt>=10){
		kbd_cnt = 0;
		KbdThree();
		if(Ktrg==0x88){//s4
			mode = 1;
		}
		if(Ktrg==0x44){//s9
			mode = 2;
		}
		if(Ktrg==0x22){//s14
			mode = 3;
		}
		if(Ktrg==0x11){//s19
			mode = 4;
		}		
	}	
}
void SmgTask()
{
	if(mode==0){
		smgbuf[0] = smgcode[10];
	}else if(mode==1){
		smgbuf[0] = smgcode[1];
	}else if(mode==2){
		smgbuf[0] = smgcode[2];
	}else if(mode==3){
		smgbuf[0] = smgcode[3];
	}else if(mode==4){
		smgbuf[0] = smgcode[4];
	}
	smgbuf[1] = smgcode[10];
	smgbuf[2] = smgcode[10];
	smgbuf[3] = smgcode[10];
	smgbuf[4] = smgcode[10];
	smgbuf[5] = smgcode[10];
	smgbuf[6] = smgcode[10];
	smgbuf[7] = smgcode[10];
}

长按键

不松手长按键

功能描述:
S4按下不松开数码管亮‘5’
松开则熄灭

u8 kbd_cnt =0 ;
void KbdTask()
{
	if(kbd_cnt>=10){
		kbd_cnt = 0;
		KbdThree();
		if(Ktrg==0x88){//s4按下不松手
			mode =5;
		}
		if((Ktrg==0x00)&&(Kcont==0x00)){	//松手
			mode = 0;
		}
	}	
}
松手长按键

功能描述:S4按下长达2秒松开,数码管亮‘5’,不足2秒(也就是短按键)则熄灭‘5’

u8 kbd_cnt =0 ;
u32 sec = 0;
void KbdTask()
{
	if(kbd_cnt>=10){
		kbd_cnt = 0;
//松手长按键---S4长按
		KbdThree();
		if(Kcont==0x88){
			sec++;
		}
		if((Ktrg==0x00)&&(Kcont==0x00)){
			if(sec>=200){
				sec = 0;
				mode = 5;
			}else if(sec!=0 ){
				sec = 0;
				mode = 0;
			}else{
				sec = 0;
			}
		}
	}	
}

状态机法

简单概述

同上篇文章(七)独立按键

代码书写

u8 GetIoState()
{
	u8 io = 0;
	P3 = 0xf0;P4 =0xff;//列扫描
	if(P44==0){io = 4;}
	if(P42==0){io = 8;}
	if(P35==0){io = 12;}
	if(P34==0){io = 16;}
	P3 = 0x0f;P4 =0x00;//行扫描
	if(P33==0){io += 0;}
	if(P32==0){io += 1;}
	if(P31==0){io += 2;}
	if(P30==0){io += 3;}	
	
	return io;
}

u8 KbdState()
{
	static u8 keystate = 0;
	u8 keyreturn = 0;
	u8 keypress = 0 ;
	
	keypress = GetIoState();
	
	switch(keystate){
		case 0:if(keypress!=0){keystate = 1;}break;
		case 1:if(keypress!=0){
							if(keypress!=0){keyreturn =GetIoState();break; }//break;
							keystate = 2;
						}else{
							keystate= 0;
						}break;
		case 2:if(keypress==0){keystate = 0;}break;
		
	}
	return keyreturn;
}

键码推算

完全不要推算,因为函数GetIoState(),已经将返回的值,对应成编号了,只需直接判断编码为几即可!

如何使用

短按键

功能描述:S4,S9,S14,S19,数码管刷新界面的切换

u8 kbd_cnt =0 ;
u8 kbd_val = 0;
void KbdTask()
{
	if(kbd_cnt>=10){
		kbd_cnt = 0;
		//短按键
		kbd_val = KbdState();
		if(kbd_val==4){//s4
			mode = 1;
		}
		if(kbd_val==9){//s9
			mode = 2;
		}
		if(kbd_val==14){//s14
			mode = 3;
		}
		if(kbd_val==19){//s19
			mode = 4;
		}
	}	
}

长按键

不松手长按键

功能描述:
S4按下不松开数码管亮‘5’
松开则熄灭

u8 kbd_cnt =0 ;
u8 kbd_val = 0;
void KbdTask()
{
	if(kbd_cnt>=10){
		kbd_cnt = 0;
		//不松手长按键
		kbd_val = KbdState();
		if(kbd_val==4){//s4
			mode = 5;
		}else{
			mode = 0;
		}	
	}	
}
松手长按键

功能描述:S4按下长达2秒松开,数码管亮‘5’,不足2秒(也就是短按键)则熄灭‘5’

u8 kbd_cnt =0 ;
u8 kbd_val = 0;
u32 sec = 0;//用来记录长按键时间
void KbdTask()
{
	if(kbd_cnt>=10){
		kbd_cnt = 0;
	//松手长按键--S4 2秒
		kbd_val = KbdState();
		if(kbd_val==4){//s4
			sec++;
		}
		if(kbd_val==0){
			if(sec>=200){	//2s长按键
				sec = 0;
				mode = 5;
			}else if(sec!=0){	//短按键
				sec = 0;
				mode = 0;	
			}else{//没有按键按下
				sec = 0;
			}
		}
	}	
}

部分代码展示

//按键函数
u8 kbd_cnt =0 ;
u8 kbd_val = 0;
u32 sec = 0;//用来记录长按键时间
void KbdTask()
{
	if(kbd_cnt>=10){
		kbd_cnt = 0;
//三行代码法--矩阵按键******************************
//		//短按键
//		KbdThree();
//		if(Ktrg==0x88){//s4
//			mode = 1;
//		}
//		if(Ktrg==0x44){//s9
//			mode = 2;
//		}
//		if(Ktrg==0x22){//s14
//			mode = 3;
//		}
//		if(Ktrg==0x11){//s19
//			mode = 4;
//		}		

不松手长按键		
//		KbdThree();
//		if(Ktrg==0x88){//s4按下不松手
//			mode =5;
//		}
//		if((Ktrg==0x00)&&(Kcont==0x00)){	//松手
//			mode = 0;
//		}

松手长按键---S4长按
//		KbdThree();
//		if(Kcont==0x88){
//			sec++;
//		}
//		if((Ktrg==0x00)&&(Kcont==0x00)){
//			if(sec>=200){
//				sec = 0;
//				mode = 5;
//			}else if(sec!=0 ){
//				sec = 0;
//				mode = 0;
//			}else{
//				sec = 0;
//			}
//		}


//状态法--矩阵按键******************************

//		//短按键
//		kbd_val = KbdState();
//		if(kbd_val==4){//s4
//			mode = 1;
//		}
//		if(kbd_val==9){//s9
//			mode = 2;
//		}
//		if(kbd_val==14){//s14
//			mode = 3;
//		}
//		if(kbd_val==19){//s19
//			mode = 4;
//		}

//		//不松手长按键--S4
//		kbd_val = KbdState();
//		if(kbd_val==4){//s4
//			mode = 5;
//		}else{
//			mode = 0;
//		}	

	//松手长按键--S4 2秒
		kbd_val = KbdState();
		if(kbd_val==4){//s4
			sec++;
		}
		if(kbd_val==0){
			if(sec>=200){	//2s长按键
				sec = 0;
				mode = 5;
			}else if(sec!=0){	//短按键
				sec = 0;
				mode = 0;	
			}else{//没有按键按下
				sec = 0;
			}
		}
	}	
}

现象演示

(八)矩阵按键



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

文章来源:https://blog.csdn.net/m0_52555663/article/details/135396553
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。