小蜜蜂51单片机之独立按键的基本操作和扩展应用

关键词:独立按键的基本操作和扩展应用;按键操作;独立按键扫描;状态机;小蜜蜂

一、实验

实验1:

实验目的:

实验步骤:

S1:对4个按键和L1-L6进行位声明
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;
S2:573锁存器信道选择函数
void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 4:P2=(P2&0x1F)|0x80;break;//1001 1111  //100->8
		case 5:P2=(P2&0x1F)|0xA0;break;//1011 1111  //101->A
		case 6:P2=(P2&0x1F)|0xC0;break;//1101 1111  //110->C
		case 7:P2=(P2&0x1F)|0xE0;break;//1111 1111  //高三位清零&,|将高三位置值
	}
}
S3:编写扫描独立按键函数(先编写一个按键,再重复使用)
void ScanKeys_Alone()
{
	if(S7==0)
	{
		DelayKey(100);//消抖
		if(S7==0)//如果S7被按下
		{
			L1=0;//L1被点亮
			while(S7==0);//S7一直被按下没有松,执行空循环
			L1=1;	//当松下S7按键后,L1熄灭
		}
	}
}

 实现按下按键(不松),LED亮,松下按键LED灭的完整代码:

#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;

void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 4:P2=(P2&0x1F)|0x80;break;//1001 1111  //100->8
		case 5:P2=(P2&0x1F)|0xA0;break;//1011 1111  //101->A
		case 6:P2=(P2&0x1F)|0xC0;break;//1101 1111  //110->C
		case 7:P2=(P2&0x1F)|0xE0;break;//1111 1111  //高三位清零&,|将高三位置值
	}
}

void DelayKey(unsigned char t)//char型数据,短延时
{
	while(t--);
}

void ScanKeys_Alone()
{
	if(S7==0)
	{
		DelayKey(100);
		if(S7==0)
		{
			L1=0;
			while(S7==0);
			L1=1;
		}
	}
	if(S6==0)
	{
		DelayKey(100);
		if(S6==0)
		{
			L2=0;
			while(S6==0);
			L2=1;
		}
	}
	if(S5==0)
	{
		DelayKey(100);
		if(S5==0)
		{
			L3=0;
			while(S5==0);
			L3=1;
		}
	}
	if(S4==0)
	{
		DelayKey(100);
		if(S4==0)
		{
			L4=0;
			while(S4==0);
			L4=1;
		}
	}
}
void main()
{
	SelectHC573(4);//控制LED的锁存器打开
	while(1)
	{
		ScanKeys_Alone();
	}
}

实验2:

实验目的:

实验步骤:

S1:沿用实验1代码
S2:设置状态机
unsigned char stat_k=0;//状态机
S3:修改ScanKeys_Alone()//扫描独立按键函数中的功能
S4:运用状态机,修改控制键S7和S6

!!最后while(S7==0);的使用防止闪烁

    if(S7==0)//如果S7被按下
	{
		if(stat_k==0)//stat_k==0时,说明当前状态没有被占用
		{
			L1=0;//点亮L1
			stat_k=1;//状态机改变状态,表明S7已经被按下过
		}
		else if(stat_k==1)//当前状态被S7占用
		{
			L1=1;
			stat_k=0;
		}
		while(S7==0);//未松下,执行空循环,直到松下才去识别别的键,防止按下多个键,多次闪
	}
	if(S6==0)
	{
		DelayKey(100);
		if(S6==0)
		{
			L2=0;
			stat_k=2;
		}
		else if(stat_k==2)
		{
			L2=1;
			stat_k=0;
		}
		while(S6==0);
	}
S5:修改S5和S4,使其根据状态机控制不同的LED的亮灭
if(S5==0)
	{
		DelayKey(100);
		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)
	{
		DelayKey(100);
		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;
			}
		}
	}

完整代码:

#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;

unsigned char stat_k=0;//状态机
void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 4:P2=(P2&0x1F)|0x80;break;//1001 1111  //100->8
		case 5:P2=(P2&0x1F)|0xA0;break;//1011 1111  //101->A
		case 6:P2=(P2&0x1F)|0xC0;break;//1101 1111  //110->C
		case 7:P2=(P2&0x1F)|0xE0;break;//1111 1111  //高三位清零&,|将高三位置值
	}
}

void DelayKey(unsigned char t)//char型数据,短延时
{
	while(t--);
}

void ScanKeys_Alone()//扫描独立按键函数
{
	if(S7==0)//如果S7被按下
	{
		if(stat_k==0)//stat_k==0时,说明当前状态没有被占用
		{
			L1=0;//点亮L1
			stat_k=1;//状态机改变状态,表明S7已经被按下过
		}
		else if(stat_k==1)//当前状态被S7占用
		{
			L1=1;
			stat_k=0;
		}
		while(S7==0);//未松下,执行空循环,直到松下才去识别别的键,防止按下多个键,多次闪
	}
	if(S6==0)
	{
		DelayKey(100);
		if(S6==0)
		{
			L2=0;
			stat_k=2;
		}
		else if(stat_k==2)
		{
			L2=1;
			stat_k=0;
		}
		while(S6==0);
	}
	if(S5==0)
	{
		DelayKey(100);
		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)
	{
		DelayKey(100);
		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()
{
	SelectHC573(4);//控制LED的锁存器打开
	while(1)
	{
		ScanKeys_Alone();
	}
}

感谢B站小蜜蜂老师的教程,本笔记资料及代码均来自教程,仅作为个人复习、整理和学习交流用,欢迎批评指正

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值