51长短按键

/*
设计一个按键
按住向上键加一
按住向下键减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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值