蓝桥杯单片机组-06独立按键的基本操作与扩展应用

要求

    在单片机综合训练平台上,首先将J5处的跳帽接到2~3引脚,使按键S4-S7四个按键的另一端接地,从而成为4个独立键盘。在扫描按键的过程中,发现有按键触发信号后,做去抖动操作,当确认为按键按下的时候,才进行相应的功能处理。

1.按下S7,点亮L1,松开后熄灭。

2.按下S6,点亮L2,松开后熄灭。

3.按下S5,点亮L3,松开后熄灭。

4.按下S4,点亮L4,松开后熄灭。按键均做去抖。

电路图:

 

 

独立键盘:

    将J5处的跳帽接到2~3引脚,使按键S4-S7四个按键的另一端接地,从而成为4个独立键盘。当按键按下的时候,为低电平。要想知道哪个键被按下了,即读引脚,若为低电平,即为按下了。

    一般要进行去抖动处理,以免出现干扰信号。有多种处理方法,最简单的是做延时处理,当读到S7为低电平的时候,过段时间再去读,若还为低电平,则为按下了。否则为干扰信号。

代码

当看到电路图的时候,可以先把38译码器的代码放上去。

1.38译码器

void SelectHC138(unsigned char channel)     //通过38译码器对P2口写,控制锁存器
{
	switch(channel)
	{
		case 4:
			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;
	}
}

2.独立键盘的定义

由于是对独立键盘的操作,需要先提前定义

sbit S7 = P3^0;     //需要对独立键盘定义
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

 3.LED灯的定义 

同样,由于是对LED灯的操作,需要先提前定义。 

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;

4.完成题目

按下按键,点亮对应的灯,松开后熄灭。

void ScanKeys_Alone()
{
	if(S7 == 0)        //S7按键
	{
		DelayK(100);     //去抖操作
		if(S7 == 0)
		{
			L1 = 0;		   	 //L1灯点亮
			while(S7 == 0);
			L1 = 1;        //按键松开后,熄灭
		}
	}
	if(S6 == 0)        //S6按键
	{
		DelayK(100);    
		if(S6 == 0)
		{
			L2 = 0;		   	 //点亮L2
			while(S6 == 0);
			L2 = 1;        
		}
	}
	if(S5 == 0)        //S5按键
	{
		DelayK(100);     
		if(S5 == 0)
		{
			L3 = 0;		   	 //点亮L3
			while(S5 == 0);
			L3 = 1;       
		}	
	}
	if(S4 == 0)        //S4按键
	{
		DelayK(100);     
		if(S4 == 0)
		{
			L4 = 0;		   	 //点亮L4
			while(S4 == 0);
			L4 = 1;        
		}
	}
}

完整代码

#include"reg52.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 SelectHC138(unsigned char channel)     //通过38译码器对P2口写,控制锁存器
{
	switch(channel)
	{
		case 4:
			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;
	}
}

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

void ScanKeys_Alone()
{
	if(S7 == 0)        //S7按键
	{
		DelayK(100);     //去抖操作
		if(S7 == 0)
		{
			L1 = 0;		   	 //L1灯点亮
			while(S7 == 0);
			L1 = 1;        //按键松开后,熄灭
		}
	}
	if(S6 == 0)        //S6按键
	{
		DelayK(100);    
		if(S6 == 0)
		{
			L2 = 0;		   	 //点亮L2
			while(S6 == 0);
			L2 = 1;        
		}
	}
	if(S5 == 0)        //S5按键
	{
		DelayK(100);     
		if(S5 == 0)
		{
			L3 = 0;		   	 //点亮L3
			while(S5 == 0);
			L3 = 1;       
		}	
	}
	if(S4 == 0)        //S4按键
	{
		DelayK(100);     
		if(S4 == 0)
		{
			L4 = 0;		   	 //点亮L4
			while(S4 == 0);
			L4 = 1;        
		}
	}
}
	

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

总结

1.对于独立按键、LED灯,需要提前定义引脚。

2.独立按键,按下为低电平,要先进行去抖操作,再看是否为低电平,再对灯操作  

3.注意主函数里面38译码器代码的位置。

4.代码中,按键松开:while(S5==0) ;

 要求2

1.按下S7点亮L1,L1亮后,S6不响应操作,S5控制L3,S4控制L4,再次按下S7,L1熄灭,S6可以响应操作。

2.按下S6点亮L2,L2亮后,S7不响应操作,S5控制L5,S4控制L6,再次按下S6,L2熄灭,S7可以响应操作。

3.当S7、S6未按下时,S5、S4不响应操作

代码2

#include"reg52.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 SelectHC138(unsigned char channel)     //通过38译码器对P2口写,控制锁存器
{
	switch(channel)
	{
		case 4:
			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;
	}
}


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

unsigned char stat_k = 0;    //状态锁定

void ScanKeys_Alone()
{
	if(S7 == 0)               //S7按键
	{
		DelayK(100);     
		if(S7 == 0)
		{
			if(stat_k == 0)       //状态为0
			{
				L1 = 0;
				stat_k = 1;
			}
			else if(stat_k == 1)   //状态为1
			{
				L1 = 1;
				stat_k = 0;
			}
		}
	}
	if(S6 == 0)        //S6按键
	{
		DelayK(100);    
		if(S6 == 0)
		{
            if(stat_k == 0)       //状态为0
			{
				L2 = 0;
				stat_k = 2;
			}
			else if(stat_k == 2)  //状态为2
			{
				L2 = 1;
				stat_k = 0;
			}        
		}
	}
	if(S5 == 0)        //S5按键
	{
		DelayK(100);     
		if(S5 == 0)
		{
            if(stat_k == 1)       //若为状态1
			{
				L3 = 0;
				while(S5==0);
				L3 = 1;
			}
			else if(stat_k == 2)  //状态为2
			{
				L5 = 0;
				while(S5==0);
				L5 = 1;
		}	
	}
}
	if(S4 == 0)        //S4按键
	{
		DelayK(100);     
		if(S4 == 0)
		{
			
            if(stat_k == 1)       //若为状态1
			{
				L4 = 0;
				while(S5==0);
				L4 = 1;
			}
			else if(stat_k == 2)  //状态为2
			{
				L6 = 0;
				while(S5==0);
				L6 = 1;
		  }        
		}
	}
}
	

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

总结2

要定义一个状态锁定值,通过状态控制按键。 

 

 

 

 

 

 

 

 

 

 

 

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值