过客与10年10月12日 #include #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; } } 因篇幅问题不能全部显示,请点此查看更多更全内容