设置范围00分01秒~99分59秒倒计时
99:59倒计时+仿真.zip
(117.12 KB, 下载次数: 14)
- #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;
- }
- }
- }
- }
复制代码
|