说明
按下的按键值越大点亮的LED越多
Proteus仿真
注意:
K1、K5、K9、K13左边引脚连接的是P1.0
K2、K6、K10、K14左边引脚连接的是P1.1
K3、K7、K11、K15左边引脚连接的是P1.2
K4、K8、K12、K16左边引脚连接的是P1.3
K1、K2、K3、K4右边引脚连接的是P1.4
K5、K6、K7、K8右边引脚连接的是P1.5
K9、K10、K11、K12右边引脚连接的是P1.6
K13、K14、K15、K16右边引脚连接的是P1.7
使用到的元器件:
单片机:AT89C51
电容:CAP
极性电容:CAP-ELEC
电阻:RES
晶振:CRYSTAL
排阻:RX8
按键:BUTTON
条形LED:LED-BARGRAPH-GRN
C51代码
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//矩阵键盘按键特征码表,用于判断哪个按键被按下
uchar code KeyCodeTable[] =
{
0x11,0x12,0x14,0x18,
0x21,0x22,0x24,0x28,
0x41,0x42,0x44,0x48,
0x81,0x82,0x84,0x88
};
//延时
void DelayMs(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
//按键扫面实现,逐行扫描,判断是哪个按键按下,返回按键值
uchar Keys_Scan()
{
uchar sCode,kCode,i,j;
//P1.0-P1.3是输出低电平,P1.4-P1.7是判断是否有按键按下
P1 = 0xf0;
if((P1&0xf0)!=0xf0)//判断是否有按键按下
{
DelayMs(2);
if((P1&0xf0)!=0xf0)//消抖后再次确认
{
sCode = 0xfe;//行扫描初始值(1111 1110)
for(i=0;i<4;i++)//扫面4行
{
P1 = sCode;//设置让某一行置为低电平
if((P1&0xf0)!=0xf0)//判断是否有按键按下
{
//如何判断是哪一个按键按下:
//P1.0-P1.3是输出低电平,循环每行输出低电平
//P1.4-P1.7是判断那一列,当按键按下,那一列就会输出低电平
//当行列都是低电平,交叉判断可以得出某个按键按下的值
kCode = ~P1;//获取按键码,取反是为了得到是哪个按键按下
for(j=0;j<16;j++)//循环匹配按键码
{
if(kCode == KeyCodeTable[j])
{
return j;//返回按键值
}
}
}
else
sCode = _crol_(sCode,1);//扫面下一行
}
}
}
return -1;
}
void main()
{
uchar Key_Num = -1;//表示无按键按下
uchar i,P2_LED,P3_LED;
while(1)
{
Key_Num = Keys_Scan();//获取按键值
if(Key_Num != -1)
{
//熄灭LED
P2_LED = 0xff;
P3_LED = 0xff;
for(i=0;i<=Key_Num;i++)
{
if(i<8)
P3_LED >>= 1;
else
P2_LED >>= 1;
}
//更新LED的状态
P3 = P3_LED;
P2 = P2_LED;
}
}
}