#define uint unsigned int #define uchar unsigned char bit dao1S=0; //到1秒标志位
bit dao2MS=0;// 到2毫秒标志位 bit dao10MS;// 到10毫秒标志位 sbit dula=P2^6;// 定义段选 sbit wela=P2^7;//定义位选
#define LED P0 //定义数据口 sbit key1=P3^4; //定义按键 sbit key2=P3^5; sbit key3=P3^6; sbit key4=P3^7;
#define KEY_1 0x0e //定义各按键键值 #define KEY_2 0x0d #define KEY_3 0x0b #define KEY_4 0x07 #define KEY_NULL 0x0f
#define KEY_PRESS 0x80 //定义各按键状态 #define KEY_LONG 0x40
#define KEY_STATE_INIT 0 //定义按键状态 #define KEY_STATE_PRESS 1 #define KEY_STATE_LONG 2 #define KEY_STATE_UP 3
#define KEY_LONG_PERIOD 50 //定义长按键的TICK数,以及连发间隔的TICK数
#define KEY_CONTINUE_PERIOD 25
uchar tab[]={0,0,0,0,0,0};//时间缓冲区
uchar weitable[]={0x01,0x02,0x04,0x08,0x10,0x20};//显示位
uchar tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳极数码管编码0-9 void nint() //中断初始化 { TMOD=0X01; TH0=0XF8; TL0=0XCC; TR0=1; ET0=1; }
uchar KeyScan() //按键扫描函数 {
if(key1==0) return KEY_1; if(key2==0) return KEY_2; if(key3==0) return KEY_3; if(key4==0) return KEY_4; return KEY_NULL; }
uchar GetKey() {
uchar keyRetu=0,keyTemp=KEY_NULL; //返回的按键值,按键情况
static uchar s_keyState=KEY_STATE_INIT,keyTime=0,keyLast=KEY_NULL; //按键状态,按键按下的时间计数器,上次按键值
keyTemp=KeyScan(); switch (s_keyState) {
case KEY_STATE_INIT:
if(keyTemp!=KEY_NULL) //检测到有按键,转到状态1,相当于是消抖过程 {
s_keyState=KEY_STATE_PRESS; }
break;
case KEY_STATE_PRESS:
if(keyTemp!=KEY_NULL) //再次检测到有按键,转到状态2 {
s_keyState=KEY_STATE_LONG; keyTime=0; //清零按键时间计数器
keyLast=keyTemp; //保存键值,以便在释放按键状态返回键值 } else {
s_keyState=KEY_STATE_INIT; //没有检测到按键,说明初始状态检测到是一个抖动,重新转到状态0 }
break;
case KEY_STATE_LONG:
if(keyTemp==KEY_NULL) //检测到按键松开 {
s_keyState=KEY_STATE_INIT; //状态转到初始状态
keyRetu=(keyLast|KEY_PRESS); //输出\"单击\"的按键值 } else {
if(++keyTime>=KEY_LONG_PERIOD) //按下时间>1s {
s_keyState=KEY_STATE_UP; //转到松开状态 keyTime=0; //清零按键时间计数器 } }
break;
case KEY_STATE_UP:
if(keyTemp==KEY_NULL) //检测到按键松开 {
s_keyState=KEY_STATE_INIT; //状态转到初始状态 } else {
if(++keyTime>=KEY_CONTINUE_PERIOD) //按下时间>0.5s {
keyTime=0; //清零按键时间计数器
keyRetu=(keyLast|KEY_LONG); // 输出\"连击\"的按键值 } }
break; }
return keyRetu; }
void updatetime() //更新时间 {
if(dao1S) {dao1S=0;
if(++tab[5]==10) { tab[5]=0; if(++tab[4]==6) {tab[4]=0;
if(++tab[3]==10) { tab[3]=0; if(++tab[2]==6) { tab[2]=0; if(tab[0]<2) { if(++tab[1]==10) { tab[1]=0; tab[0]++; } } else { if(tab[1]==4) { tab[1]=0; tab[0]=0; } } } } } } } } void display()//时间显示 { static uchar k=0;
dula=1;//送段的数据 LED=tab1[tab[k]]; dula=0;
LED=0Xff;
wela=1;//送位的数据 LED=weitable[k]; wela=0;
if(++k>5) k=0; }
void sittime(uchar hour,uchar minute,uchar second )//赋除值 { uchar a1,a2,b1,b2,c1,c2; a1=hour/10; a2=hour%10;
b1=minute/10; b2=minute%10; c1=second/10; c2=second%10; tab[0]=a1; tab[1]=a2; tab[2]=b1; tab[3]=b2; tab[4]=c1; tab[5]=c2; } void main()//主函数 { nint(); EA=1;
sittime(15,20,15); while(1) {
updatetime(); if(dao2MS) {dao2MS=0; display(); } if(dao10MS) //每10ms扫描一次按键 {
dao10MS=0; switch (GetKey()) {
case (KEY_1|KEY_PRESS): if(tab[0]<2)
{ if (++tab[1]==10) { tab[1]=0; tab[0]++; } } else {if(++tab[1]==4) { tab[1]=0; tab[0]=0; } }
break;
case (KEY_1|KEY_LONG): if(tab[0]<2)
{ if (++tab[1]==10) { tab[1]=0; tab[0]++; } } else {if(++tab[1]==4) { tab[1]=0; tab[0]=0; } } break; case (KEY_2|KEY_PRESS): if(++tab[3]==10) { tab[3]=0; tab[2]++; if(tab[2]==6) { tab[2]=0; tab[3]=0; } } break;
case (KEY_2|KEY_LONG): if(++tab[3]==10) { tab[3]=0; tab[2]++; if(tab[2]==6) { tab[2]=0; tab[3]=0; } } break;
case (KEY_3|KEY_PRESS): if(++tab[5]==10) { tab[5]=0; tab[4]++; if(tab[4]==6) { tab[4]=0; tab[5]=0; } } break;
case (KEY_3|KEY_LONG): if(++tab[5]==10) { tab[5]=0; tab[4]++; if(tab[4]==6) { tab[4]=0; tab[5]=0; } } } } } }
void timer() interrupt 1 { static count=0; static count1=0;
TH0=0XF8; TL0=0XCC; dao2MS=1; count++;
if(++count1==10)
{ count1=0; dao10MS=1; }
if(count==500) //产生1S的时标 {
count=0; dao1S=1; } }