放假下雨,无事做了一个时钟。洞洞焊接,很是费力哟。四位带双点0.56数码管,废微波炉上拆下来的,PCF8563,旧电表的拆下来的。加了一个STC15W104、TM1637及三个按键.做出来的时钟小巧稳定,功能也还可以。上图:
单片机源程序如下:
- #include <STC15.h>
- #include "intrins.h"
- #define uchar unsigned char
- #define uint unsigned int
-
- #include "TM1637.h"
- #include "PCF8563.H"
- uchar keyvalue,xs=0,LD=5,SetFlag=0,re_disp=0;
- uchar keydate; //读键盘参数
- bit Flash; //闪烁标志位
- bit ReadTimeFlag;//定义读时间标志
- void Init_Timer0(void);//定时器初始化
- void Displsy_Time();
- void Scan_Key();
- void Set(uchar sel,uchar selby);
- /*------------------------------------------------
- 主函数
- ------------------------------------------------*/
- void main()
- {
- P3M0=0X00;
- P3M1=0X00;
- Init_Timer0();
- while(1)
- {
- Scan_Key();
- }
- }
- /*------------------------------------------------
- 显示界面设置
- ------------------------------------------------*/
- void Displsy_Time()
- {
- if(ReadTimeFlag==1) //读取时间
- {
- ReadTimeFlag=0;
- Read8563();
- keydate=ScanKey();
- }
- if(SetFlag==0&&xs==0) TM1637_display((time_buf1[4]/10),(time_buf1[4]%10),(time_buf1[5]/10),(time_buf1[5]%10),Flash,(LD)); //非设置状态,正常显示 时:分
- if(SetFlag==0&&xs==1) TM1637_display((2),(0),(time_buf1[1]/10),(time_buf1[1]%10),0,(LD)); //20xx年
- if(SetFlag==0&&xs==2) TM1637_display((time_buf1[2]/10),(time_buf1[2]%10),(time_buf1[3]/10),(time_buf1[3]%10),1,(LD)); //月:日
- if(SetFlag==0&&xs==3) TM1637_display((time_buf1[7]),(21),(time_buf1[6]/10),(time_buf1[6]%10),1,(LD)); //周空秒
-
- switch(SetFlag) //以下是设置状态
- {
- case 1:
- {
- if(Flash) TM1637_display((2),(0),(time_buf1[1]/10),(time_buf1[1]%10),0,(LD));
- else TM1637_display((2),(0),(21),(21),0,(LD));
-
- if(keyvalue==2&&SetFlag==1) //年+
- {
- Set(1,0);
- keyvalue=0;
- }
- if(keyvalue==3&&SetFlag==1) //年-
- {
- Set(1,1);
- keyvalue=0;
- }
- }
- break;
- case 2:
- {
- if(Flash) TM1637_display((11),(21),(time_buf1[2]/10),(time_buf1[2]%10),1,(LD));
- else TM1637_display((11),(21),(21),(21),1,(LD));
-
- if(keyvalue==2&&SetFlag==2) //月+
- {
- Set(2,0);
- keyvalue=0;
- }
- if(keyvalue==3&&SetFlag==2) //月-
- {
- Set(2,1);
- keyvalue=0;
- }
- }
- break;
-
- case 3:
- {
- if(Flash) TM1637_display((13),(21),(time_buf1[3]/10),(time_buf1[3]%10),1,(LD));
- else TM1637_display((13),(21),(21),(21),1,(LD));
-
- if(keyvalue==2&&SetFlag==3) //日+
- {
- Set(3,0);
- keyvalue=0;
- }
- if(keyvalue==3&&SetFlag==3) //日-
- {
- Set(3,1);
- keyvalue=0;
- }
- }
- break;
-
- case 4:
- {
- if(Flash) TM1637_display((16),(21),(time_buf1[4]/10),(time_buf1[4]%10),1,(LD));
- else TM1637_display((16),(21),(21),(21),1,(LD));
-
- if(keyvalue==2&&SetFlag==4) //时+
- {
- Set(4,0);
- keyvalue=0;
- }
- if(keyvalue==3&&SetFlag==4) //时-
- {
- Set(4,1);
- keyvalue=0;
- }
- }
- break;
-
- case 5:
- {
- if(Flash) TM1637_display((15),(21),(time_buf1[5]/10),(time_buf1[5]%10),1,(LD));
- else TM1637_display((15),(21),(21),(21),1,(LD));
-
- if(keyvalue==2&&SetFlag==5) //分+
- {
- Set(5,0);
- keyvalue=0;
- }
- if(keyvalue==3&&SetFlag==5) //分-
- {
- Set(5,1);
- keyvalue=0;
- }
- }
- break;
-
- case 6:
- {
- if(Flash) TM1637_display((5),(21),(time_buf1[6]/10),(time_buf1[6]%10),1,(LD));
- else TM1637_display((5),(21),(21),(21),1,(LD));
-
- if(keyvalue==2&&SetFlag==6) //秒+
- {
- Set(6,0);
- keyvalue=0;
- }
- if(keyvalue==3&&SetFlag==6) //秒-
- {
- Set(6,1);
- keyvalue=0;
- }
- }
- break;
- }
-
- }
- /*------------------------------------------------
- 定时器初始化子程序
- ------------------------------------------------*/
- void Init_Timer0(void)
- {
- TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- EA=1; //总中断打开
- ET0=1; //定时器中断打开
- TR0=1; //定时器开关打开
- }
- /*------------------------------------------------
- 定时器中断子程序
- ------------------------------------------------*/
- void Timer0_isr(void) interrupt 1
- {
- static unsigned int num,a;
- TH0=(65536-50000)/256; //重新赋值 50ms
- TL0=(65536-50000)%256;
- num++;
- re_disp++;
- if(num==2) //大致100ms
- {
- num=0;
- ReadTimeFlag=1; //读标志位置1
- a++;
- }
-
- if(a==5)
- {
- a=0;
- Flash=~Flash;
- }
- if(re_disp==200)
- {
- re_disp=0;
- SetFlag=0;
- }
- }
- /*------------------------------------------------
- 键盘检测函数
- ------------------------------------------------*/
- void Scan_Key(void) //键盘检测函数
- {
- keydate=0xff;
- Displsy_Time(); //程序开头调用显示函数
-
- if(keydate==0xef)
- {
- re_disp=0; //清除记数,重新开始10s定时
- SetFlag++;
- if(SetFlag>6)SetFlag=0;
- }
- if(keydate==0xed)
- {
- re_disp=0; //清除记数,重新开始10s定时
- keyvalue=2; //跳到加减判断函数,下同
-
- if(SetFlag==0)
- {
- xs++;
- if(xs>3)xs=0;
- }
- }
-
- if(keydate==0xee)
- {
- re_disp=0;
- keyvalue=3;
-
- if(SetFlag==0)
- {
- LD++;
- if(LD>7)LD=0;
- }
- }
- }
- /*-------------------------------------------------------
- //根据选择调整相应项目并写入DS3231
- --------------------------------------------------------*/
- void Set(unsigned char sel,unsigned char selby) //执行调整项目的函数
- {
- uchar max,mini;
- if(sel==6) {max=59;mini=0;} //秒
- if(sel==5) {max=59;mini=0;} //分钟
- if(sel==4) {max=23;mini=0;} //小时
- if(time_buf1[2]==2) //日
- {
- if(runnian())
- {
- if(sel==3) {max=29;mini=1;}
- }
- else
- {
- if(sel==3) {max=28;mini=1;}
- }
- }
- if(time_buf1[2]==1|time_buf1[2]==3|time_buf1[2]==5|time_buf1[2]==7|time_buf1[2]==8|time_buf1[2]==10|time_buf1[2]==12)
- {
- if(sel==3) {max=31;mini=1;}
- }
- if(time_buf1[2]==4|time_buf1[2]==6|time_buf1[2]==9|time_buf1[2]==11)
- {
- if(sel==3) {max=30;mini=1;}
- }
-
- if(sel==2) {max=12;mini=1;} //月
- if(sel==1) {max=25;mini=15;} //年
- if (selby==0) time_buf1[sel]++; else time_buf1[sel]--;
- if(time_buf1[sel]>max) time_buf1[sel]=mini;
- if(time_buf1[sel]<mini) time_buf1[sel]=max;
- Write8563();
- autoweek();
- }
复制代码
所有资料51hei提供下载:
TM1637PCF8563四数码管时钟.rar
(55.25 KB, 下载次数: 198)
|