电路参考
传送门
/*
*******************************************************************************
对矩阵按键进行扫描,
数码管对按键的键值进行显示
*******************************************************************************
*/
#include <reg52.h> //包含特殊功能寄存器定义的头文件
//数码管相关
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
//按键相关
sbit key1=P2^4;
sbit key2=P2^5;
sbit key3=P2^6;
sbit key4=P2^7;
unsigned char key[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char old[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char code ledchar[]={0XC0,0XF9,0XA4,0XB0,
0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E};
void main()
{
unsigned char i,j;
//打开数码管
ADDR3=1;
ENLED=0;
ADDR0=0;
ADDR1=0;
ADDR2=0;
//打开定时器 1ms
TMOD=0X01;
TH0=0XFC;
TL0=0X67;
TR0=1;
//打开中断
EA=1;
ET0=1;
while(1)
{
for(i=0;i<4;i++)
for (j=0;j<4;j++)
if(key[i][j]!=old[i][j])//检测到按键被按下
{
if (old[i][j]==0) //按键弹起,输出数码管
P0=ledchar[i*4+j];
old[i][j]=key[i][j];
}
}
}
void InterruptTimer0() interrupt 1 //对按键进行扫描
{
static unsigned char keyout=0;
unsigned char z=0;
static unsigned char keyy[4][4]={{0xff,0xff,0xff,0xff},
{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
//对一排按键进行扫描
//重新定义定时器
TH0=0XFC;
TL0=0X67;
keyy[keyout][0]=(keyy[keyout][0]<<1)|key1;
keyy[keyout][1]=(keyy[keyout][1]<<1)|key2;
keyy[keyout][2]=(keyy[keyout][2]<<1)|key3;
keyy[keyout][3]=(keyy[keyout][3]<<1)|key4;
//连续四次扫描判断按键状态
for(;z<4;z++)
{
if(keyy[keyout][z]==0xff)
key[keyout][z]=1;
else if (keyy[keyout][z]==0x00)
key[keyout][z]=0;
else ;
}
//改变排数
keyout++;
if(keyout>=4)keyout=0;
switch (keyout)
{
case 0:P2=0XF7;break;
case 1:P2=0XFB;break;
case 2:P2=0XFD;break;
case 3:P2=0XFE;break;
default:break;
}
}