05-独立按键的基本操作与扩展应用

05-独立按键的基本操作与扩展应用

在写代码前需做如下,否则独立按键无响应:

微信图片_20231004093700

由电路图可知:独立按键默认为高电平,当按键按下时为低电平

即S7(P30)、S6(P31)、S5(P32)、S4(P33)

当按下按键时,P3口对应低电平,松开后对应高电平,判断是否一直按下此时需要使用while(1) 死循环,由于是按下点亮,松开熄灭,所以当一直按下时,点亮且进入死循环,否则熄灭

20231003212924

代码如下:

#include <REGX52.H>
sbit s7 = P3^0;
sbit s6 = P3^1;
sbit s5 = P3^2;
sbit s4 = P3^3;


sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;

void _74HC138(unsigned char n) {
	switch(n) {
		case 4:
			P2 = (P2&0x1f) | 0x80; // LED
			break;
		case 5:
			P2 = (P2&0x1f) | 0xa0; //蜂鸣器和继电器
			break;
		case 6:
			P2 = (P2&0x1f) | 0xa0; // 数码管位选
			break;
		case 7:
			P2 = (P2&0x1f) | 0xc0; // 数码管段选
			break;
		case 0:
			P2 = (P2&0x1f) | 0x00; //
			break;
	
	}

}

void DelayK(unsigned char t) {
	while(t--);
}

void ScanKeys_Alone() {
	if(s7 == 0) {       //检测是否按下
		 DelayK(100);   
		 if(s7 == 0) {
			 L1 = 0;
			 while(s7==0);  // 如果为低电平就一直循环 检测是否松开
			 L1 = 1;
		 }
	}
	
	
	if(s6 == 0) {       //检测是否按下
		 DelayK(100);   
		 if(s6 == 0) {
			 L2 = 0;
			 while(s6==0);  // 如果为低电平就一直循环 检测是否松开
			 L2 = 1;
		 }
	}
	
	if(s5 == 0) {       //检测是否按下
		 DelayK(100);   
		 if(s5 == 0) {
			 L3 = 0;
			 while(s5==0);  // 如果为低电平就一直循环 检测是否松开
			 L3 = 1;
		 }
	}
	
	if(s4 == 0) {       //检测是否按下
		 DelayK(100);   
		 if(s4 == 0) {
			 L4 = 0;
			 while(s4==0);  // 如果为低电平就一直循环 检测是否松开
			 L4 = 1;
		 }
	}
	

}
void main(void) {
	_74HC138(4);
	while(1) {
		ScanKeys_Alone();
	
	}
	

}

20231003223716

由上可知:该题目意思为S7与S6为状态选择键,且L1与L2分别为S7、S6的状态指示灯,且L1与L2不可同时点亮. 当L1点亮时,S5、S4分别控制L3,L4,当L2点亮时,S5、S4分别控制L5,L6,且按键S5、S4按下后点亮,松开后熄灭

所以此时生声明一个变量stat.且默认stat=0,当S7按下时,将stat赋值为1,且点亮L1,当S6按下时,将stat赋值为2,且点亮L2,再次按下时,熄灭LED灯

当L1点亮时,stat=1,且S5按下时,L3点亮,S4按下时,L4点亮

当L2点亮时,stat=2,且S5按下时,L5点亮,S4按下时,L6点亮

#include <REGX52.H>
sbit s7 = P3^0;
sbit s6 = P3^1;
sbit s5 = P3^2;
sbit s4 = P3^3;

sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;
sbit L6 = P0^5;
sbit L7 = P0^6;
sbit L8 = P0^7;

void _74HC138(unsigned char n) {
	switch(n) {
		case 4:   // LED
			P2 = (P2 & 0x1f) | 0x80;
			break;
		case 5: //蜂鸣器和继电器
			P2 = (P2 & 0x1f) | 0xa0;
			break;
		case 6: // 数码管位选
			P2 = (P2 & 0x1f) | 0xc0;
			break;
		case 7: // 数码管段选
			P2 = (P2 & 0x1f) | 0xe0;
			break;
		case 0: 
			P2 = (P2 & 0x1f) | 0x00;
			break;
	}

}

void DelayK(unsigned int t) {
	while(t--);

}
void SystemInit(void) {
	_74HC138(5);
	P0 = 0x00;  // 关闭蜂鸣器和继电器
	_74HC138(4);
	P0 = 0xff;  // 关闭所有LED
	
}
unsigned char stat_k = 0;  
// stat_k = 0    
void ScanKey_Alone(void) {
	// 当stat_k == 1的时候为s7的控制源
	// 当stat_k == 2的时候为s6的控制源
	if(s7 == 0) {
		DelayK(300);
		if(s7== 0) {
			if(stat_k == 0) {
				DelayK(100);
				while(s7==0) {
					stat_k = 1;
				}
				L1 = 0;
				DelayK(100);
			
			}else if(stat_k == 1) {
				DelayK(100);
				while(s7 ==0) {
					stat_k = 0;
				}
				L1 = 1;
				
				
			}
		
		}
	
	}
	
	if(s6 == 0) {
		DelayK(300);
		if(s6 == 0) {
			if(stat_k == 0) {
				DelayK(100);
				while(s6 == 0){
					stat_k = 2;
				}
				L2 = 0;
				DelayK(100);
				
			}else if(stat_k == 2) {
				DelayK(100);
				while(s6 == 0) {
					stat_k = 0;
				}
				L2 = 1;
				
			}
		
		
		}
	}
	
	if(s5 == 0) {
		DelayK(300);
		if(s5==0) {
			if(stat_k == 1) {
				L3 = 0;
				while(s5 == 0);
				L3 = 1;
			
			}else if(stat_k == 2) {
				L5 = 0;
				while(s5 == 0);
				L5 = 1;
			}
		
		}
	
	
	}
	
	if(s4 == 0) {
		DelayK(300);
		if(s4 == 0) {
			if(stat_k == 1) {
				L4 = 0;
				while(s4 == 0);
				L4 = 1;
			}else if(stat_k == 2) {
				L6 = 0;
				while(s4 == 0);
				L6 = 1;
			}
		}
	}
}

void main(void) {
	// 初始化
	SystemInit();
	// 先让LED使能
	_74HC138(4);
	while(1) {
		ScanKey_Alone();
	
	}
	

}
posted @ 2023-10-04 10:43  夏日清凉~  阅读(75)  评论(0编辑  收藏  举报