没人回答 不知道是程序问题还是我电路问题,就是设置不了时间这是在网上找的,也不知道是哪位大神之作。麻烦帮我修改下, 不求多么准!只求能正常运行和调整 !(我仿真时4个按键无用)
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define DispOFF 10; //显示关
- #define POINT 21; //显示小点
- #define F 22;
- #define H 23;
- #define M 24;
- #define N 25;
- #define O 26;
- sbit buzzer=P3^7; //蜂鸣器控制脚
- uchar T2Count;
- uint T0Count;
- uchar key,key_new,key_old,KeyPressTime;
- uchar status;
- uchar month,day,hour,min,sec,AlarmHr,AlarmMin;
- uchar LastDay;
- uchar AlmTime,AlmCount,DispTime;
- uchar CountHr,CountMin,CountSec,CountSetSta=0;
- uint year;
- bit TimeAdj,AlarmAdj,AlarmSta;
- bit adjust,DigiBit;
- //数码管显示代码
- uchar code LedCode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,
- 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x7f,
- 0x8e,0x89,0xc8,0xab,0xa3
- };
- uchar Disp[4];
- void LedScan(void);
- void KeyScan(void);
- void years(void);
- void date(void);
- void timer(void);
- void alarmClock(void);
- void CountDown(void);
- void ring(void);
- uchar DaysCount(void);
- void Init(void)
- {
- TH2=0x3c;TL2=0xb0;
- RCAP2H=0x3c;RCAP2L=0xb0;
- EA=1;ET2=1;
- TR2=1;
- TMOD=0x01;
- //TH0=0x3c;
- //TL0=0xb0;
- ET0=1;
- P1=0xff;
- year=2011;
- month=1;
- day=1;
- hour=0;
- min=0;
- status=2;
- buzzer=1;
- }
- /************主函数*************/
- void main(void)
- {
- Init();
- while(1)
- {
- KeyScan();
- LastDay=DaysCount();
- switch(status) //显示状态
- {
- case 0:years();break; //显示年
- case 1:date();break; //显示日期
- case 2:timer();break; //显示时间
- case 3:alarmClock();break; //显示闹钟时间
- case 4:CountDown();break; //显示倒计时
- }
- LedScan();
- ring();
- }
- }
- /***************定时器T0中断函数,用于倒计时**************/
- void timer0(void) interrupt 1 using 2
- {TH0=0x3c;
- TL0=0xb0;
- T0Count++;
- if(CountHr||CountMin||CountSec)
- {if(T0Count==20)
- {CountSec--;T0Count=0;}
- if(CountSec>=60)
- {CountSec=59;CountMin--;}
- if(CountMin>=60)
- {CountMin=59;CountHr--;}
- }
- if(T0Count==1200)
- {TR0=0;
- T0Count=0;
- }
- }
- /**************定时器T2中断函数,用于计时**************/
- void timer2(void) interrupt 5 using 1
- {
- TF2=0;
- if(++T2Count==20)
- {sec++;T2Count=0;}
- if(!TimeAdj) //时间调整时,暂停计时
- {if(sec==60)
- {min++;sec=0;}
- if(min==60)
- {hour++;min=0;}
- if(hour==24)
- {day++;hour=0;}
- if(day>LastDay)
- {month++;day=1;}
- if(month>12)
- {year++;month=1;}
- }
- }
- void delay(uchar x)
- {
- uchar k;
- while(x--)
- for(k=0;k<123;k++);
- }
- /***********数码管扫描显示函数***************/
- void LedScan(void)
- {
- uchar i;
- uchar temp=0x08;
- for(i=0;i<4;i++)
- {
- P0=LedCode[Disp[i]]; //送段码
- P2=~temp;temp>>=1; //LED显示位控制
- delay(3); //延时
- P2=0xff; //关显示
- }
- }
- /**********按键扫描程序***************/
- void KeyScan(void)
- {
- if((P1&0x0f)!=0x0f) //如果按下按键
- {if(KeyPressTime>0) //延时
- {
- switch(~(P1|0xf0)) //判断键值
- {
- case 0x01:key_new=1;break;
- case 0x02:key_new=2;break;
- case 0x04:key_new=3;break;
- case 0x08:key_new=4;break;
- }
- }
- KeyPressTime++; //按键时间加1
- }
- else //如果没有按键按下
- {key_new=0; //键值清零
- KeyPressTime=0; //按键时间清零
- }
- if(key_new!=key_old) //如果前后两次键值不同
- {key=key_new; //键值等于本次键值
- }
- else //如果前后两次键值相同(按住按键未释放)
- {key=0; //键值清零
- if(KeyPressTime>100) //按键时间大于100,差不多1秒(作长按键处理)
- {KeyPressTime-=30; //按键时间减30,当累加到100再次动作,相当于300毫秒按键一次,
- key=key_new; //得到本次键值
- }
- }
- key_old=key_new; //记住本次键值
- }
- /***********计算本月有多少天**************/
- uchar DaysCount(void)
- {
- if(month==4||month==6||month==9||month==11) //4、6、9、11月为30天
- return 30;
- else if(month!=2) //1、3、5、7、8、10、12月为31天
- return 31;
- if(month==2)
- {if((year%4==0&&year%100!=0)||(year%400==0))
- return 29; //闰年2月为29天
- else
- return 28; //非闰年2月为28天
- }
- }
- /**************年函数**************/
- void years(void)
- {
- if(adjust) //设置,调整年
- {
- switch(key) //处理按键
- {case 1:{
- year++; //年加1
- break;
- }
- case 2:{
- year--; //年减1
- break;
- }
- case 3:{
- adjust=0; //退出设置
- DispTime=0;
- break;
- }
- }
- }
- else
- {
- if(key==2) status++; //显示状态加1,进入日期显示
- if(key==3) adjust=1; //进入设置
- if(++DispTime==200) //显示时间加1,系统默认显示时间,通过按键切换其他显示一段时间后自动返回时间显示
- {status=2; //利用程序循环执行一次的时间作延时,每循环一次DispTime+1,加到200后退出返回时间显示
- DispTime=0; //DispTime清零
- }
- }
- Disp[0]=year/1000; //年份千位
- Disp[1]=year/100%10; //年份百位
- Disp[2]=year/10%10; //年份十位
- Disp[3]=year%10; //年份个位
- if(T2Count<=10)
- {if(adjust) //如果调整年份,显示闪烁
- Disp[0]=Disp[1]=Disp[2]=Disp[3]=DispOFF;
- }
- }
- /***********日期函数***************/
- void date(void)
- {
- if(adjust) //调整日期
- {
- switch(key)
- {case 1:{
- if(DigiBit==0) month++; //月加1
- else day++; //日加1
- if(month>12) month=1; //月大于12,月份等于1
- if(day>LastDay) day=1; //日大于本月最后一日,日等于1
- break;
- }
- case 2:{
- if(DigiBit==0) month--; //月减1
- else day--; //日减1
- if(month==0) month=12; //月=0,月份=12
- if(day==0) day=LastDay; //日=0,日等于本月最后一天
- break;
- }
- case 3:{
- DigiBit=~DigiBit; //月、日设置选择切换
- if(DigiBit==0) //DigiBit=0 选择月 DigiBit=1 选择日
- {adjust=0;
- DispTime=0;
- }
- break;
- }
- }
- }
- else
- {
- if(key==1) {status--;DispTime=0;} //显示年,显示时间清零重新计算
- if(key==2) status++; //显示时间
- if(key==3) adjust=1; //进入设置
- if(++DispTime==200) //显示时间到,返回时间显示
- {status=2;
- DispTime=0;
- }
- }
- Disp[0]=month/10;
- Disp[1]=month%10;
- Disp[2]=day/10;
- Disp[3]=day%10+11;
- if(T2Count<=10)
- {if(adjust)
- {
- if(!DigiBit) //如果调整日,日显示闪烁
- {
- Disp[0]=DispOFF;
- Disp[1]=DispOFF;
- }
- else //如果调整月,月显示闪烁
- {
- Disp[2]=DispOFF;
- Disp[3]=POINT;
- }
- }
- }
- }
- /**************时间函数****************/
- void timer(void)
- {
- if(TimeAdj) //调整时间
- {
- switch(key)
- {case 1:{ //up/加 按键
- if(DigiBit==0) hour++; //根据按键选择时间、分钟加调整
- else min++;
- if(hour==24) hour=0;
- if(min==60) min=0;
- break;
- }
- case 2:{ //down 减 按键
- if(DigiBit==0) hour--; //时间、分钟减调整
- else min--;
- if(hour>=24) hour=23;
- if(min>=60) min=59;
- break;
- }
- case 3:{
- DigiBit=~DigiBit; //DigiBit=0 小时,DigiBit=1 分钟
- if(DigiBit==0) //时间设置完后,秒清零,定时器重新计时
- {sec=0;
- TR2=0;
- TH2=0x3c;TL2=0xb0;
- T2Count=0;
- TR2=1;
- TimeAdj=0;
- }
- break;
- }
- }
- }
- else
- {
- if(key==1) {status--;DispTime=0;}
- if(key==2) {status++;DispTime=80;}//进入闹钟显示,显示时间初始值为80
- if(key==3) TimeAdj=1;
- }
- Disp[0]=hour/10;
- Disp[1]=hour%10;
- Disp[2]=min/10+11;
- Disp[3]=min%10+11;
- if(T2Count<=10)
- {if(TimeAdj)
- {
- if(!DigiBit)
- {
- Disp[0]=DispOFF;
- Disp[1]=DispOFF;
- }
- else
- {
- Disp[2]=POINT;
- Disp[3]=POINT;
- }
- }
- else
- {
- Disp[2]=min/10;
- Disp[3]=min%10;
- }
- }
- }
- /*************闹钟函数***************/
- void alarmClock(void)
- {Disp[0]=AlarmHr/10;
- Disp[1]=AlarmHr%10;
- Disp[2]=AlarmMin/10+11;
- Disp[3]=AlarmMin%10+11;
- if(DispTime<80)//显示时间<80,显示闹钟开关状态,显示时间>=80,显示闹钟时间
- {if(AlarmSta)
- {Disp[0]=DispOFF;
- Disp[1]=DispOFF;
- Disp[2]=O;
- Disp[3]=N;
- }
- else
- {Disp[0]=DispOFF;
- Disp[1]=O;
- Disp[2]=F;
- Disp[3]=F;
- }
- }
- if(AlarmAdj)//设置闹钟时间
- {
- switch(key)
- {case 1:{
- if(DigiBit==0) AlarmHr++;
- else AlarmMin++;
- if(AlarmHr==24) AlarmHr=0;
- if(AlarmMin==60) AlarmMin=0;
- break;
- }
- case 2:{
- if(DigiBit==0) AlarmHr--;
- else AlarmMin--;
- if(AlarmHr>=24) AlarmHr=23;
- if(AlarmMin>=60) AlarmMin=59;
- break;
- }
- case 3:{
- DigiBit=~DigiBit;
- if(DigiBit==0)
- {AlarmAdj=0;
- DispTime=80;
- }
- break;
- }
- }
- if(T2Count<=10)
- {
- if(!DigiBit)
- {
- Disp[0]=DispOFF;
- Disp[1]=DispOFF;
- }
- else
- {
- Disp[2]=POINT;
- Disp[3]=POINT;
- }
- }
- }
- else
- {
- if(key==1) status--;
- if(key==2)
- {status++;
- DispTime=0;
- }
- if(key==3) AlarmAdj=1;
- if(key==4)//闹钟开关按键
- {if(DispTime<80) //初次按下,显示上次设置状态
- AlarmSta=~AlarmSta; //再按可改变设置
- DispTime=0;//每按一次,显示时间清零,显示闹钟开关状态
- }
- DispTime++;
- if(DispTime==255)
- {status=2;
- DispTime=0;
- }
- }
- }
- /**************倒计时函数*****************/
- void CountDown(void)
- {
- if(adjust)//设置倒数时间
- {
- switch(CountSetSta)
- {case 0:{//设置倒数小时
- if(key==1) CountHr++;
- if(key==2) CountHr--;
- if(key==3) CountSetSta++;
- if(CountHr==100) CountHr=0;
- if(CountHr>100) CountHr=99;
- Disp[0]=H;
- Disp[1]=DispOFF;
- Disp[2]=CountHr/10;
- Disp[3]=CountHr%10;
- break;
- }
- case 1:{//设置倒数分钟
- if(key==1) CountMin++;
- if(key==2) CountMin--;
- if(key==3) CountSetSta++;
- if(CountMin==60) CountMin=0;
- if(CountMin>60) CountMin=59;
- Disp[0]=M;
- Disp[1]=DispOFF;
- Disp[2]=CountMin/10;
- Disp[3]=CountMin%10;
- break;
- }
- case 2:{//设置倒数秒
- if(key==1) CountSec++;
- if(key==2) CountSec--;
- if(key==3) //设置键
- {if(CountHr||CountMin||CountSec)//设置完成后,若倒数的时、分、秒不为零,倒计时开始
- {TH0=0x3c; TL0=0xb0;
- T0Count=0;
- TR0=1;
- }
- CountSetSta=0;
- adjust=0;
- DispTime=0;
- }
- if(CountSec==60) CountSec=0;
- if(CountSec>60) CountSec=59;
- Disp[0]=5;
- Disp[1]=DispOFF;
- Disp[2]=CountSec/10;
- Disp[3]=CountSec%10;
- break;
- }
- }
- }
- else
- {
- if(key==1) //进入闹钟显示
- {status--;
- DispTime=80;
- }
- if(key==3) //设置倒数时间
- {
- TR0=0;
- CountHr=CountMin=CountSec=0;
- adjust=1;
- }
- if(key==4) //停止倒计时
- {TR0=0;
- CountHr=CountMin=CountSec=0;
- }
- if(CountHr==0) //若倒数时间小于1小时,倒计时显示分钟、秒
- {Disp[0]=CountMin/10;
- Disp[1]=CountMin%10;
- Disp[2]=CountSec/10+11;
- Disp[3]=CountSec%10+11;
- }
- else //若倒数时间大于1小时,倒计时显示小时、分钟
- {Disp[0]=CountHr/10;
- Disp[1]=CountHr%10;
- Disp[2]=CountMin/10+11;
- Disp[3]=CountMin%10+11;
- }
- if(T2Count<=10)//倒计时显示闪烁
- Disp[0]=Disp[1]=Disp[2]=Disp[3]=DispOFF;
- if(!TR0) //倒计时完成后,显示一段时间后退出
- {if(++DispTime==200)
- {status=2;
- DispTime=0;
- }
-
- }
- }
- }
- /*****************闹铃控制********************/
- void ring(void)
- {bit StopFlag;
- if((hour==AlarmHr&&min==AlarmMin&&AlarmSta)||(CountHr==0&&CountMin==0&&CountSec==0)&TR0)//闹钟时间到或倒数时间到,闹铃响
- {
- if(key==4&status!=3)
- StopFlag=~StopFlag;
- if(!AlarmAdj&&!StopFlag)
- {AlmTime++; //计时,程序循环一次加1
- if(AlmTime<=8) //时间0-8
- buzzer=0; //蜂鸣器响(有源蜂鸣器,接通就响,断开就停)
- if(AlmTime>8) //时间8-16
- buzzer=1; //蜂鸣器停
- if(AlmTime==16)
- {if(++AlmCount!=4)//循环4次
- AlmTime=0;
- }
- if(AlmTime==30)//延时一定时间重复上述动作,使蜂鸣器发出嘀、嘀、嘀、嘀的报警声。
- {AlmTime=0;
- AlmCount=0;
- }
- }
- else
- {buzzer=1;
-
- }
- }
- else
- {buzzer=1;
- StopFlag=0;
- AlmTime=0;
- AlmCount=0;
- }
- }
复制代码
|