一,元件介绍
? ? ? ? 使用独立键盘时,需要使跳帽在2-3,引脚在按下时,P30—P33相应的引脚为低电平,通过检测哪个引脚为低电平,来判断哪个按键按下,从而实现什么功能。
二,代码部分
#include <reg52.h>
sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;
sbit L4=P0^3;
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
void Delay(unsigned char t)
{
while(t--);
}
void HC138(unsigned char n)
{
switch(n)
{
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 ScanKeys_Alone()
{
HC138(4);
if(S7==0)
{
Delay(100);
if(S7==0)
{
L1=0;
while(S7==0);
L1=1;
}
}
if(S6==0)
{
Delay(100);
if(S6==0)
{
L2=0;
while(S6==0);
L2=1;
}
}
if(S5==0)
{
Delay(100);
if(S5==0)
{
L3=0;
while(S5==0);
L3=1;
}
}
if(S4==0)
{
Delay(100);
if(S4==0)
{
L4=0;
while(S4==0);
L4=1;
}
}
}
void main()
{
HC138(4);
while(1)
{
ScanKeys_Alone();
}
}
? ? 首先使用sbit来确定哪个LED连接在哪个引脚,哪个按键连接在哪个引脚。关键函数为ScanKeys_Alone(),首先打开Y4C对应的寄存器,使用if函数判断如何S7按下,则S7=0,然后实现一个延时函数,再使用if(S7==0)再确认一次,这一步的作用为消抖,防止有干扰信号。L1=0,实现LED1亮起,while()函数保证S7按下时能使LED1一直亮着,松开后L1=0,LED1灭。其他LED原理相同。
三,代码部分?
?
#include <reg52.h>
#include <intrins.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 Delay100ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 5;
j = 144;
k = 71;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void HC138(unsigned char i)
{
switch(i)
{
case 4:
P2=(P2&0x1f) | 0x80;
break;
case 5:
P2=(P2&0x1f) | 0xa0;
break;
}
}
void Inisystem()
{
HC138(5);
P0=0x00;
HC138(4);
P0=0xff;
}
unsigned char State=0;
void LED_kbd()
{
HC138(4);
if(S7==0)
{
Delay100ms();
if(S7==0)
{
if(State==0)
{
State=1;
L1=0;
}
else if(State==1)
{
L1=1;
State=0;
}
while(S7==0);
}
}
if(S6==0)
{
Delay100ms();
if(S6==0)
{
if(State==0)
{
State=2;
L2=0;
}
else if(State==2)
{
L2=1;
State=0;
}
while(S6==0);
}
}
if(S5==0)
{
Delay100ms();
if(S5==0)
{
if(State==1)
{
L3=0;
while(S5==0);
L3=1;
}
if(State==2)
{
L5=0;
while(S5==0);
L5=1;
}
}
}
if(S4==0)
{
Delay100ms();
if(S4==0)
{
if(State==1)
{
L4=0;
while(S4==0);
L4=1;
}
if(State==2)
{
L6=0;
while(S4==0);
L6=1;
}
}
}
}
void main()
{
Inisystem();
while(1)
{
LED_kbd();
}
}
相对上面的题目这题会复杂一点,?思路是建立一个变量State作为状态量,初始值为0,在S7按下后变化为1,为了满足题目要求,在下次按下S7是要释放状态,所以多了一个else if。当State为1时,使State回到初始的0。还需要补充的是一开始按S7或者S6时,有时候会闪烁,因为单片机并不清楚你按了几下,所以在else if下面还需要补充一个while(S7==0);,来除颤。
|