/*
设计一个按键
按住向上键加一
按住向下键减1
连续按住1s后,美200ms加1
所需函数
按键驱动函数 在主函数中不断检测按键是否按下
按键动作函数,对按键动作进行判断
按键驱动函数
LED显示函数,
LED驱动函数
*/
#include <reg52.h>
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 code ledchar[]={0XC0,0XF9,0XA4,0XB0,
0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E};//数码管数值取值
unsigned char leddd[6]={0xff,0xff,0xff,0xff,0xff,0xff};
unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
{ 0x31, 0x32, 0x33, 0x26 }, //数字键1、数字键2、数字键3、向上键
{ 0x34, 0x35, 0x36, 0x25 }, //数字键4、数字键5、数字键6、向左键
{ 0x37, 0x38, 0x39, 0x28 }, //数字键7、数字键8、数字键9、向下键
{ 0x30, 0x1B, 0x0D, 0x27 } }; //数字键0、ESC键、 回车键、 向右键
unsigned long pdata keytime[4][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
unsigned char num=0;
unsigned char TORH=0;
unsigned char TORL=0;
void LedShowNumber(unsigned int number);
void KeyScan();
void KeyAction(unsigned char i,unsigned char j);
void KeyDrive();
void config(unsigned int ms);
void main()
{
//打开138
EA=1;
ENLED=0;
ADDR3=1;
LedShowNumber(num);
config(1);
while(1)
{
KeyDrive();
}
}
void KeyAction(unsigned char i,unsigned char j)
{
if(KeyCodeMap[i][j]==0x26)//向上键
{
num++;
LedShowNumber(num);
}
else if(KeyCodeMap[i][j]==0x28)//向下键
{
if(num>0)
num--;
LedShowNumber(num);
}
else if(KeyCodeMap[i][j]==0x1B)
{
num=0;
LedShowNumber(num);
}
}
void KeyDrive()
{
unsigned char i;
unsigned char j;
static unsigned char old[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
static unsigned long pdata timethr[4][4]={{1000,1000,1000,1000},{1000,1000,1000,1000},
{1000,1000,1000,1000},{1000,1000,1000,1000}};
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
if(key[i][j]!=old[i][j])//检测按键状态发生变化
{
if(old[i][j]==1)//按下
{
KeyAction(i,j);
}
old[i][j]=key[i][j];
}
if(keytime[i][j]>0)
{
if(keytime[i][j]>=timethr[i][j])
{
KeyAction(i,j);
timethr[i][j]+=200;
}
}
else
{
timethr[i][j]=1000;
}
}
}
void KeyScan() //按键扫描
{
unsigned char z=0;
static unsigned char keyout=0;
static unsigned char keyy[4][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},
{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
//对这一排的按键进行扫描
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=0;z<4;z++)
{
if((keyy[keyout][z]&0x0f)==0x0f)//判断扫描值
{
key[keyout][z]=1;
keytime[keyout][z]=0;
}
else if ((keyy[keyout][z]&0x0f)==0x00) //按下
{
key[keyout][z]=0;
keytime[keyout][z]+=4;
}
}
//切换不同排数
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;
}
}
void LedShowNumber(unsigned int number)
{
signed char i;
unsigned char ledbuff[6]={0xff,0xff,0xff,0xff,0xff,0xff};
ledbuff[0]=ledchar[number%10];
ledbuff[1]=ledchar[number/10%10];
ledbuff[2]=ledchar[number/100%10];
ledbuff[3]=ledchar[number/1000%10];
ledbuff[4]=ledchar[number/10000%10];
ledbuff[5]=ledchar[number/100000%10];
for(i=5;i>=1;i--)
{
if(ledbuff[i]==ledchar[0])
leddd[i]=0xff;
else
break;
}
for(;i>=0;i--)
{
leddd[i]=ledbuff[i];
}
}
void LedScan()
{
static unsigned char i=0;
P0=0xff;
P1=(P1&0XF8)|i;
P0=leddd[i];
i++;
if(i>5)
i=0;
}
void config(unsigned int ms)
{
unsigned long tmp;
tmp=11059200*ms/12000;
tmp=65536-tmp;
TORH=(unsigned char)(tmp>>8);
TORL=(unsigned char)(tmp);
TMOD&=0XF0;
TMOD|=0X01;
TH0=TORH;
TL0=TORL;
ET0=1;
TR0=1;
}
void InterruptTimer0() interrupt 1
{
TH0=TORH;
TL0=TORL;
LedScan();
KeyScan();
}
51长短按键
最新推荐文章于 2023-11-11 23:30:55 发布