|
單鍵控制9分59秒倒計(jì)時(shí)
- #include <reg51.H>
- #include <intrins.H>
- #define uint unsigned int
- #define uchar unsigned char
- sbit bai=P3^0;
- sbit shi=P3^1;
- sbit ge=P3^2;
- sbit key=P3^6;
-
- //定義需要顯示的數(shù)字
- //反序共陰極數(shù)碼管段碼表,段碼a-h順序接PX7-PX0
- unsigned char code dis[]={//共陰數(shù)碼管段碼"0~f-."
- 0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,
- 0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x02,0x01};
- uchar data buf[3];
- char sec=0,sec_1=0,min=1,min_1=1; //秒、分
- uchar Key_value; //鍵值
- uchar set=0; //設(shè)置標(biāo)志
- uint cnt=0,cnt1=0; //中斷計(jì)數(shù)
- uint count=0; //長(zhǎng)/短按計(jì)數(shù)
- uint rst=0; //復(fù)位計(jì)數(shù)
- bit flag_ms=0; //1ms中斷標(biāo)志
- bit flicker=0; //閃爍標(biāo)志
- bit start=0; //開(kāi)始標(biāo)志
- bit On_Off=1; //開(kāi)關(guān)標(biāo)志
- void Timer0Init(void) //1毫秒@12.000MHz
- {
- TMOD |= 0x01; //設(shè)置定時(shí)器模式
- TL0 = 0x18; //設(shè)置定時(shí)初始值
- TH0 = 0xFC; //設(shè)置定時(shí)初始值
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
- EA = 1;
- ET0 = 1;
- }
- //數(shù)碼管顯示函數(shù)
- void display()
- {
- static uchar i;
- if(On_Off)
- {
- P1=0x00;
- if(set==0)
- {
- switch(i)
- {
- case 0: bai=0;shi=1;ge=1;P1=dis[min]|0x01; break;
- case 1: bai=1;shi=0;ge=1;P1=dis[sec/10]; break;
- case 2: bai=1;shi=1;ge=0;P1=dis[sec%10]; break;
- }
- }
- if(set==1)
- {
- switch(i)
- {
- case 0: bai=0;shi=1;ge=1;
- if(flicker)P1=dis[min]|0x01; else P1=0x01; break;
- case 1: bai=1;shi=0;ge=1;P1=dis[sec/10]; break;
- case 2: bai=1;shi=1;ge=0;P1=dis[sec%10]; break;
- }
- }
- if(set==2)
- {
- switch(i)
- {
- case 0: bai=0;shi=1;ge=1;P1=dis[min]|0x01; break;
- case 1: bai=1;shi=0;ge=1;
- if(flicker)P1=dis[sec/10];else P1=0x00; break;
- case 2: bai=1;shi=1;ge=0;P1=dis[sec%10]; break;
- }
- }
- if(set==3)
- {
- switch(i)
- {
- case 0: bai=0;shi=1;ge=1;P1=dis[min]|0x01; break;
- case 1: bai=1;shi=0;ge=1;P1=dis[sec/10]; break;
- case 2: bai=1;shi=1;ge=0;
- if(flicker)P1=dis[sec%10];else P1=0x00; break;
- }
- }
- }
- else
- {
- P1=0xff;
- bai=1;
- shi=1;
- ge=1;
- }
- i=++i%4;
- }
- //按鍵掃描
- void key_scan()
- {
- if(!key)
- {
- count++;
- if(count>1000) //長(zhǎng)按時(shí)長(zhǎng)
- count=1001;
- if(count==10) //大于10ms小于500ms算短按
- {
- Key_value=0x01;
- }
- if(count==1000) //達(dá)到1s算長(zhǎng)按
- {
- Key_value|=0x10;
- }
- }
- else //按鍵松手
- {
- if(count>0)rst=5000;//復(fù)位計(jì)數(shù)賦值
- count=0;//長(zhǎng)/短按計(jì)數(shù)清0
- }
- }
- //按鍵服務(wù)程序
- void key_service()
- {
- //短按等待松手后響應(yīng),長(zhǎng)按達(dá)1s不論是否松手立即響應(yīng)
- if((count==0||count==1000) && Key_value!=0x00)
- {
- switch(Key_value)
- {
- case 0x01://短按1任務(wù)
- if(On_Off==0 && !start && set==0)On_Off=1;//開(kāi)機(jī)
- else if(On_Off && !start && set==0){min=min_1;sec=sec_1;start=1;}//啟動(dòng)倒計(jì)時(shí)
- else if(On_Off && !start && set>0)//設(shè)置時(shí)間
- {
- switch(set)
- {
- case 1: min++; if(min>9)min=0; break;//設(shè)置分
- case 2: sec+=10;if(sec>=60)sec%=10; break;//設(shè)置秒十位
- case 3: sec++; if(sec%10==0)sec-=10; break;//設(shè)置秒個(gè)位
- }
- min_1=min;//緩存分
- sec_1=sec;//緩存秒
- }
- break;
- case 0x11:
- if(On_Off && !start)
- {
- if(++set==4)set=0;//操作設(shè)置狀態(tài)
- rst=5000;
- }
- break;
- }
- Key_value=0x00;//鍵值清0
- }
- }
- //復(fù)位/關(guān)機(jī)函數(shù)
- void reset()
- {
- if(rst>0)
- {
- rst--;
- if(rst==0)
- {
- if(count==0)//按鍵已松手
- set=0;//設(shè)置狀態(tài)復(fù)位
- else if(!start)//長(zhǎng)按5秒不松手關(guān)機(jī)(倒計(jì)時(shí)運(yùn)行中不可關(guān)機(jī))
- {
- set=0;//設(shè)置狀態(tài)復(fù)位
- On_Off=0;//關(guān)機(jī)
- }
- }
- }
- }
- //主函數(shù)
- void main()
- {
- Timer0Init();
- while(1)
- {
- if(flag_ms)
- {
- flag_ms=0;//1ms標(biāo)志清0
- display();//數(shù)碼管顯示函數(shù)
- key_scan();//按鍵掃描函數(shù)
- key_service();//按鍵服務(wù)函數(shù)
- reset();//復(fù)位/關(guān)機(jī)函數(shù)
- }
- }
- }
- //T0中斷服務(wù)函數(shù)
- void InterruptTimer0() interrupt 1
- {
- TL0 = 0x18; //設(shè)置定時(shí)初始值
- TH0 = 0xFC; //設(shè)置定時(shí)初始值
- if(start)
- {
- if(++cnt>=1000)//1s
- {
- cnt=0;
- sec--;
- if(sec==0 && min==0)//倒計(jì)時(shí)結(jié)束
- {
- start=0; //開(kāi)始標(biāo)志清0
- }
- else if(sec<0)
- {
- sec=59;
- min --;
- }
- }
- }
- if(++cnt1>=200) //200ms 5Hz閃爍,可以任意調(diào)整閃爍頻率
- {
- cnt1=0;
- flicker=~flicker; //閃爍標(biāo)志取反
- }
- flag_ms=1;//1ms中斷標(biāo)志賦值
- }
復(fù)制代碼 |
|