关键词:独立按键的基本操作和扩展应用;按键操作;独立按键扫描;状态机;小蜜蜂
一、实验
实验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站小蜜蜂老师的教程,本笔记资料及代码均来自教程,仅作为个人复习、整理和学习交流用,欢迎批评指正