設置范圍00分01秒~99分59秒倒計時
99:59倒計時+仿真.zip
(117.12 KB, 下載次數: 14)
2019-11-19 14:35 上傳
點擊文件名下載附件
無標題.jpg (368.62 KB, 下載次數: 24)
下載附件
2019-11-19 14:35 上傳
- #include <reg51.h>
- #include <intrins.h>
- //宏定義
- #define uchar unsigned char
- #define uint unsigned int
- #define key_S 20 //宏定義短按(20ms)
- #define key_L 500 //宏定義長按(0.5s)
- #define key_M 300 //宏定義連按間隔(0.2s)
- sbit P_HC595_SER = P2^0;
- sbit P_HC595_SRCLK = P2^1;
- sbit P_HC595_RCLK = P2^2;
- sbit k1=P1^0;
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit k4=P1^3;
- sbit OUT=P3^7;
- sbit buzz=P3^5;
- unsigned char code SEG7[]={//共陰數碼管段碼"0~f-."
- 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,
- 0x39,0x5e,0x79,0x71,0x40,0x80};
- uchar num[]={1,2,3,4};
- uint Cnt_1ms=0,flash=0,count=0;
- uchar Choice,Cnt250us=0;
- uchar set=0;
- char Cnt_sec=0,Cnt_min=0,sec=0,min=0;
- bit sign=0,buzzer=0;
- bit flag=0;
- void Timer0Init()//250微秒@12.000MHz
- {
- TMOD |= 0x02; //設置定時器模式
- TL0 = 0x06; //設置定時初值
- TH0 = 0x06; //設置定時重載值
- TR0 = 1; //定時器0開始計時
- EA = 1;
- ET0 = 1;
- }
- //顯示控制
- void dispaly()
- {
- if(set==0)//正常顯示
- {
- num[3]=SEG7[min/10%10];//顯示分十位
- num[2]=SEG7[min%10]|0x80;//顯示分個位加點
- num[1]=SEG7[sec/10%10];//顯示秒十位
- num[0]=SEG7[sec%10];//顯示秒個位
- }
- else //設置顯示
- {
- num[3]=SEG7[Cnt_min/10%10];//顯示分十位
- if(flag==1 && set==1)
- num[2]=SEG7[Cnt_min%10]|0x80;//顯示分個位加點
- else
- num[2]=SEG7[Cnt_min%10];//顯示分個位
- num[1]=SEG7[Cnt_sec/10%10];//顯示秒十位
- if(flag==1 && set==2)
- num[0]=SEG7[Cnt_sec%10]|0x80;//顯示秒個位加點
- else
- num[0]=SEG7[Cnt_sec%10];//顯示秒個位
- }
- }
- /**************** 向HC595發送一個字節函數 ******************/
- void Send_595(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- dat <<= 1;
- P_HC595_SER = CY; //溢出位賦值數據輸出端
- P_HC595_SRCLK = 1; //移位時鐘
- P_HC595_SRCLK = 0;
- }
- }
- /**************** 向HC595發送四個字節函數 ******************/
- void DisplayScan()
- {
- uchar j;
- for(j=0;j<4;j++)
- {
- Send_595(num[j]);//向HC595發送一個字節
- }
- P_HC595_RCLK = 1;//鎖存輸出數據
- P_HC595_RCLK = 0;
- }
- //按鍵掃描
- void key_scan()
- {
- static bit key1_sign,key4_sign; //按鍵自鎖標志變量
- static uint count1,count2,count3=0,count4=0;//消抖計數變量
- if(k1==0 && Choice==0) //檢測按鍵1按下與K4互鎖
- {
- count1++; //消抖計數1自+1
- if((count1>=key_S)&&(key1_sign==0))//檢測消抖計數與按鍵1自鎖標志
- {
- key1_sign=1; //按鍵1自鎖標志置1
- set++;
- if(set==3) //0:正常倒計時 1:設置分鐘 2:設置秒鐘
- {
- set=0;
- Cnt250us=0;
- Cnt_1ms=0;
- sec=Cnt_sec;
- min=Cnt_min;
- }
- }
- }
- else
- {
- key1_sign=0; //按鍵1自鎖標志清0
- count1=0; //消抖計數count1清0
- }
- if(set!=0) //調整時間
- {
- if(!k2) //檢測按鍵2按下
- {
- count2++;
- if(count2>=key_L) //長按快調
- {
- if(set==1)
- {
- if(Cnt_min<99)
- Cnt_min++;
- }
- if(set==2)
- {
- if(Cnt_sec<59)
- Cnt_sec++;
- }
- count2=key_M;
- }
- }
- else //按鍵抬起
- {
- if(count2>key_S && count2<key_L)//短按
- {
- if(set==1)
- {
- if(Cnt_min<99)
- Cnt_min++;
- }
- if(set==2)
- {
- if(Cnt_sec<59)
- Cnt_sec++;
- }
- }
- count2=0; //count2清0
- }
- if(!k3) //檢測按鍵3按下
- {
- count3++;
- if(count3>=key_L) //長按快調
- {
- if(set==1)
- {
- if(Cnt_min>0)
- Cnt_min--;
- }
- if(set==2)
- {
- if(Cnt_sec>0)
- Cnt_sec--;
- }
- count3=key_M;
- }
- }
- else //按鍵抬起
- {
- if(count3>key_S && count3<key_L)//短按
- {
- if(set==1)
- {
- if(Cnt_min>0)
- Cnt_min--;
- }
- if(set==2)
- {
- if(Cnt_sec>0)
- Cnt_sec--;
- }
- }
- count3=0; //count3清0
- }
- }
- if(k4==0 && set==0) //檢測按鍵4按下與k1互鎖
- {
- count4++; //消抖計數4自+1
- if((count4>=key_S)&&(key4_sign==0))//檢測消抖計數與按鍵4自鎖標志
- {
- key4_sign=1; //按鍵4自鎖標志置1
- if(sec|min!=0) //設置的時間必須大于0秒,否則不啟動
- {
- Choice++;
- if(Choice==1) //開始
- {
- OUT=0;
- Cnt_1ms=0;
- }
- if(Choice==2) //停止
- OUT=1;
- if(Choice>=3) //復位
- {
- Choice=0;
- Cnt250us=0;
- Cnt_1ms=0;
- sec=Cnt_sec;
- min=Cnt_min;
- }
- }
- }
- }
- else
- {
- key4_sign=0; //按鍵4自鎖標志清0
- count4=0; //消抖計數count4清0
- }
- }
- void Alarm()//報警
- {
- if(sign==1 && min==0 && sec==0)
- {
- sign=0;
- OUT=1;//停止輸出
- Choice=0;
- buzzer=1;
- }
- if(buzzer)
- {
- buzz=~buzz;//蜂鳴器取反
- count++;
- if(count>=3000)
- {
- count=0;
- buzzer=0;
- buzz=1;
- Cnt_1ms=0;
- sec=Cnt_sec;
- min=Cnt_min;
- }
- }
- }
- //-----------------------
- void main()
- {
- Timer0Init();
- sec=Cnt_sec;
- min=Cnt_min;
- OUT=1;
- buzz=1;
- while(1)
- {
- dispaly();//顯示控制
- DisplayScan();//顯示刷新
- }
- }
- void Timer0Interrupt(void) interrupt 1
- {
- Alarm();//報警
- if(++flash>=1000)
- {
- flash=0;
- flag=~flag;//閃爍標志取反
- }
- if(++Cnt250us>=4)//1ms
- {
- Cnt250us=0;
- key_scan(); //按鍵掃描
- if(Choice==1)//啟動倒計時
- {
- Cnt_1ms++;
- if(Cnt_1ms>=1000)
- {
- Cnt_1ms=0;
- sec--;
- if(sec<0)
- {
- min--;
- sec=59;
- }
- if(min==0)
- sign=1;
- }
- }
- }
- }
復制代碼
|