说明
按下的按键值越大点亮的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;//返回按键值}}}elsesCode = _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){//熄灭LEDP2_LED = 0xff;P3_LED = 0xff;for(i=0;i<=Key_Num;i++){if(i<8)P3_LED >>= 1;elseP2_LED >>= 1;}//更新LED的状态P3 = P3_LED;P2 = P2_LED;} }}