| 本帖最后由 songzhige 于 2010-12-20 10:06 编辑 
 功能描述:产品可以显示时间和日期,时间格式为 hh mm ss  日期格式为 yy.mm.dd
 时间和日期轮流显示。 时间显示5S 日期显示3S。
 可以设置5个闹铃,闹铃音乐可以设置两种:毛驴和童年。
 三个按键对时间和闹铃进行设置,六个LED进行显示。
 计时采用DS1307。继电时间不丢失,设置过的闹铃也不丢失。
 闹铃音乐由单片机的两个定时器去产生频率实现。
 
 部分程序如下:
 //*************************************************
 //************************************************
 //***********************************************
 //程序名:DS1307 时钟程序
 //功能描述:用六个八段LED 轮流显示时间
 //          和日期。有6个闹钟。上电时从DS1307中读出
 //          当前时间、日期、闹钟。
 //
 //
 //
 //
 //
 #include <reg52.h>
 #include <intrins.h>
 #define uchar unsigned char
 #define uint  unsigned int
 #define LED P2
 #define LEDBit P0
 #define nop  _nop_()
 #define LightCount  40
 #define LightMax    80
 sbit SCL=P3^1;
 sbit SDA=P3^0;
 sbit ModeKey=P1^0;
 sbit UpKey=P1^1;
 sbit DownKey=P1^2;
 sbit Speak=P3^6;
 code uchar LCD_NUM[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //0x25,
 //uchar  Clock[]={0x88,0x88,0x88};
 code uint    Music_Sound_Long1[]={4,8,4,8,8,4,8,4,4,4,                     /*童年*/
 8,4,8,4,4,4,4,4,16,4,
 4,8,4,4,4,4,4,8,4,4,
 4,8,4,4,4,4,4,4,16,4,
 4,8,4,4,4,4,4,8,4,4,
 4,8,4,4,4,4,4,4,16,4,
 8,4,8,4,4,4,8,8,4,4,
 4,4,4,4,4,4,4,4,4,16,
 4,8,4,8,8,4,8,4,4,4,
 8,4,8,4,4,4,4,4,16,4,
 8,4,8,8,4,8,4,4,4,8,
 4,8,4,4,4,4,4,16,0},
 Music_Sound_Long2[]={4,4,4,4,4,4,4,4,4,4,           /*小毛驴*/
 4,4,16,4,4,4,4,4,4,4,
 4,4,4,4,4,8,4,4,4,4,
 4,4,4,4,4,4,4,4,4,16,
 4,4,4,4,2,2,2,2,4,4,
 4,4,4,4,16,0},
 Music_Sound_Tone1[]={379,379,379,379,425,477,477,477,425,477,
 568,637,637,637,568,637,425,379,477,719,
 637,637,719,637,568,568,506,568,568,568,
 637,477,477,477,477,568,477,568,637,719,
 637,637,719,637,568,568,506,568,568,568,
 637,477,477,477,477,568,568,477,851,318,
 318,318,318,379,425,477,477,568,477,568,
 477,425,425,425,425,425,477,379,425,425,
 379,379,379,379,425,477,477,477,425,477,
 568,637,637,637,568,637,425,379,477,379,
 379,379,379,425,477,477,477,425,477,568,
 637,637,637,568,637,425,379,477,0},         /*童年*/
 Music_Sound_Tone2[]={956,956,956,719,637,637,637,637,568,568,     /*小毛驴*/
 568,477,637,716,716,716,568,719,719,719,
 719,851,851,851,851,637,637,956,956,956,
 719,637,637,637,637,568,568,568,477,637,
 716,716,716,568,719,719,719,719,719,719,
 851,851,851,719,956,0};
 
 uchar  DS1307[27]={0};
 //00 为秒,01为分,02为时
 //10 为日,11为月,12为年
 //20 为闹钟控制,21为分,22为时。
 //30 为闹钟控制,31为分,32为时。
 //40 为闹钟控制,41为分,42为时。
 // 同上
 // 同上
 //闹钟控制十位为闹钟数
 //闹钟控制个位为选择闹钟声音程序
 //个位为零关闭闹钟
 uchar  DisplayArr[8][3]={0};
 
 //*********************************
 void Beep(void);
 void DiplayClock(uchar *);
 //void UsuaDisPlay(uchar *);
 void Delay(uint Count);
 void DiplayDelay(void);
 
 void Start(void);
 void Stop(void);
 void ack(bit);
 bit cack(void);
 
 void Send8bit(unsigned char);  // 高字节位先传 字节最低位1为读,0为写
 unsigned char Read8bit(void);
 void SendWord(unsigned char,unsigned char);
 unsigned char ReadWord(unsigned char);
 void ReadDS1307(uchar);
 //**************************
 void ModeButten(void);
 void UpButten(void);
 void DownButten(void);
 //********************
 //函数名:INC
 //功能:加1函数
 void INC(void);
 unsigned char Inc(uchar);
 unsigned char Dec(uchar);
 void Ring(void);
 //*********************************
 uchar Mode=0;    //Mode=0 轻按UP、Down为查看时间、日期、闹钟
 //Mode=1
 uchar Read=0;    //Read==1为读DS1307
 uchar Juge=0;      //闪烁位数
 uchar DisplyMode;
 uchar Light;
 uchar Black;
 uchar DisplayLoop;
 uchar RingFlag;
 uchar  Sound_Long_Count;
 uint Period;
 /*********************  音乐频率中断  ******************************************/
 void Music_Tone()interrupt 3 using 2
 {
 
 Speak=!Speak;
 TL1=(65536-Period)&0xff;
 TH1=(65536-Period)>>8;
 TF1=0;
 }
 /**********************  10ms中断变量  ***************************************/
 void Music_Long()interrupt 1  using 3
 {
 
 if(Sound_Long_Count!=0)Sound_Long_Count--;
 TL0=(65536-10000)&0xff;
 TH0=(65536-10000)>>8;
 TF0=0;
 /* TL2=(65536-10000)&0xff;
 TH2=(65536-10000)>>8;
 TF2=0;
 */
 }
 //***********************************
 main()
 {
 uchar i,j,Loop;
 uchar  RingMinBuffer;
 uchar  RingHouBuffer;
 uchar  RingMinBufferOld=0xff;
 uchar RingTimeLong;
 TMOD=0x11;         /*开定时器0,工作在方式3模式下*/
 // TH0=TL0=0x6;      /*置定时器初值*/
 TL0=(65536-10000)&0xff;
 TH0=(65536-10000)>>8;
 IE=0xca;          /*允许定时器中断*/
 // ET2=1;
 //**************************************************88
 //**************************************************
 
 /*
 for(i=0;i<6;i++)
 {
 Stop();
 Start();
 Send8bit(0xD0);
 if(cack()==1)continue;
 Send8bit(0x08+i*0x03);
 if(cack()==1)continue;
 Send8bit(i*0x10+0x10);
 if(cack()==1)continue;
 
 Stop();
 }
 */
 ReadDS1307(26);
 for(DisplyMode=0;DisplyMode<8;DisplyMode++)
 {
 INC();
 }
 DisplyMode=0;
 ReadDS1307(26);
 for(i=0,Loop=0;i<8;i++)
 for(j=0;j<3;j++,Loop++)
 {
 if(Loop==3)Loop++;
 if(Loop==7)Loop++;
 DisplayArr[j]=DS1307[Loop];
 }
 for(i=2;i<8;i++)
 for(j=0;j<3;j++)
 {
 switch(j)
 {
 case 0:  DisplayArr[j]&=0x73;break;   //开关闹钟
 case 1:  DisplayArr[j]&=0x7F;break;    //分钟
 case 2:  DisplayArr[j]&=0x3F;break;
 }
 }
 
 DisplayArr[1][0]&=0x3F;     //日期
 DisplayArr[1][1]&=0x1F;  //月份
 
 Speak=0;
 while(1)
 {
 //DisplayClock(6,Clock);
 
 //DiplayClock(Clock);
 //  DiplayClock(DisplayArr[DisplyMode]);
 //Juge=1;
 
 DiplayClock(DisplayArr[DisplyMode]);
 //*****************************************************************111
 //读出的数存入单片机中,
 if(Read==1)
 {
 ReadDS1307(26);
 Read=0;
 }
 else  ReadDS1307(6);
 
 DiplayClock(DisplayArr[DisplyMode]);
 for(i=0,Loop=0;i<8;i++)
 for(j=0;j<3;j++,Loop++)
 {
 if(Loop==3)Loop++;
 if(Loop==7)Loop++;
 DisplayArr[j]=DS1307[Loop];
 DiplayClock(DisplayArr[DisplyMode]);
 }
 //******************************************************************111
 //******************************************************************222
 //读出的数格式化
 for(i=2;i<8;i++)
 for(j=0;j<3;j++)
 {
 switch(j)
 {
 case 0:  DisplayArr[j]&=0x73;break;   //开关闹钟
 case 1:  DisplayArr[j]&=0x7F;break;    //分钟
 case 2:  DisplayArr[j]&=0x3F;break;
 default :
 
 DiplayClock(DisplayArr[DisplyMode]);
 }
 DiplayClock(DisplayArr[DisplyMode]);
 }
 
 DisplayArr[1][0]&=0x3F;     //日期
 DisplayArr[1][1]&=0x1F;  //月份
 //********************************************************************222
 
 DiplayClock(DisplayArr[DisplyMode]);
 //  Beep();
 ModeButten();
 DownButten();
 UpButten();
 
 DiplayClock(DisplayArr[DisplyMode]);
 //**********************************************333
 //日期时间交替显示程序
 if(Juge==0)
 DisplayLoop++;
 if(DisplayLoop>10)DisplyMode=0;
 if(DisplayLoop>60)
 {
 DisplyMode=1;
 DisplayLoop=0;
 }
 //***********************************************333
 
 
 //************************************************444
 //闹钟程序比较
 if(Juge==0)
 {
 for(i=2;i<8;i++)
 {
 DiplayClock(DisplayArr[DisplyMode]);
 
 if(DisplayArr[0]&0x0F==0)continue;
 if(DisplayArr[1]!=DisplayArr[0][1])continue;
 RingMinBuffer=DisplayArr[1];
 if(RingMinBufferOld==RingMinBuffer)continue;
 if(DisplayArr[2]!=DisplayArr[0][2])continue;
 
 if(RingFlag==0)RingMinBufferOld=0xff;
 RingFlag=DisplayArr[0]&0x0F;
 
 }
 }
 //************************************************444
 ModeButten();
 DownButten();
 UpButten();
 DiplayClock(DisplayArr[DisplyMode]);
 RingTimeLong=0;
 switch (RingFlag)
 {
 case 1:
 {
 DisplyMode=0;
 i=0;
 while(DisplayArr[0][1]==RingMinBuffer)        /*是否响闹铃1程序*/
 {
 /*  if(DisplayArr[0][1]!=RingMinBuffer)
 {
 RingMinBuffer=DisplayArr[0][1];
 RingTimeLong++;
 }
 */
 RingMinBufferOld=RingMinBuffer;
 if(Music_Sound_Long1==0)
 {
 DiplayClock(DisplayArr[DisplyMode]);
 i=0;
 }
 Sound_Long_Count=Music_Sound_Long1;/*****/
 Period=Music_Sound_Tone1;
 TL1=(65536-Period)&0xff;
 TH1=(65536-Period)>>8;
 
 DiplayClock(DisplayArr[DisplyMode]);
 i++;
 
 if(RingFlag==1)
 {
 TR1=1;
 TR0=1;
 }
 while(Sound_Long_Count!=0)
 {
 DiplayClock(DisplayArr[DisplyMode]);
 ModeButten();
 
 
 DownButten();
 UpButten();
 DiplayClock(DisplayArr[DisplyMode]);
 if(RingFlag==0)
 {
 
 Sound_Long_Count=0;
 }
 
 }
 TR1=0;
 TR0=0;
 
 }
 RingMinBufferOld=0xff;
 }
 break;
 case 2:
 {
 i=0;
 DisplyMode=0;
 while(DisplayArr[0][1]==RingMinBuffer)             /*是否响闹铃2程序*/
 {
 /*  if(DisplayArr[0][1]!=RingMinBuffer)
 {
 RingMinBuffer=DisplayArr[0][1];
 RingTimeLong++;
 }
 */
 RingMinBufferOld=RingMinBuffer;
 if(Music_Sound_Long2==0)
 {
 DiplayClock(DisplayArr[DisplyMode]);
 i=0;
 }
 Sound_Long_Count=Music_Sound_Long2;
 Period=Music_Sound_Tone2;
 TL1=(65536-Period)&0xff;
 TH1=(65536-Period)>>8;
 //           Display();
 i++;
 if(RingFlag==2)
 {
 TR1=1;
 TR0=1;
 }
 while(Sound_Long_Count!=0)
 {
 DiplayClock(DisplayArr[DisplyMode]);
 ModeButten();
 
 
 DownButten();
 UpButten();
 DiplayClock(DisplayArr[DisplyMode]);
 if(RingFlag==0)
 {
 Sound_Long_Count=0;
 
 }
 }
 TR1=0;
 TR0=0;
 }
 RingMinBufferOld=0xff;
 }
 break;
 default: break;
 }
 /**/
 }
 
 }
 //*******************************
 //void Ring(void)
 //{
 //   uchar i,j;
 //}
 //*******************************
 //void Beep(void)
 //{
 //       uchar j,k;
 //  for(j=0;j<17;j++)
 //    {
 //      Speak=1;
 //   for(k=0;k<200;k++);
 //   Speak=0;
 //   for(k=0;k<200;k++);
 
 //       }
 //}
 //********************************
 void DownButten(void)
 {
 bit Flag;
 //DiplayClock(Clock);
 uchar Buffer;
 DiplayClock(DisplayArr[DisplyMode]);
 DownKey=1;
 Flag=DownKey;
 if(Flag==0)
 {
 //DiplayClock(Clock);
 //DiplayClock(Clock);
 //DiplayClock(Clock);
 
 DiplayClock(DisplayArr[DisplyMode]);
 DisplayLoop=0;
 DownKey=1;
 Flag=DownKey;
 while(Flag==0)
 {
 TR0=0;
 TR1=0;
 if( RingFlag!=0) RingFlag=0;
 //DiplayClock(Clock);
 //DiplayClock(Clock);
 DiplayClock(DisplayArr[DisplyMode]);
 if(Mode==1)
 {
 Read=1;
 switch (DisplyMode)
 {
 case  0 :             //时间
 {
 转载http://www.songzhige.com/post/265.html
 |