下面是电子钟的主要程序:
void fz(void)
{    int i;
if(alarm_on==1)
{
    if(strncmp(CurrentTime.TimeString,stralarm,7)==0)
    {    
        for(i=0;i<20;i++)
        {    bz(    100,1,1);
            mdelay(200);
            bz(100,1,1);
            mdelay(200);
            mdelay(1000);
            LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
            GotoXY(0, 0);
            Print("..Alarm.........");
            GotoXY(0, 1);
            Print(stralarm);
            stopwatch_flag=1;
            if(out==0)
            {    while(out==0);
                alarm_on=0;
                break;
                }
             gettime();
        }
    }
}
if((CurrentTime.TimeString[6]=='5')&&(CurrentTime.TimeString[7]=='9'))    
    alarm_on=alarm_flag_sto[0];
}
void disp_strstowatch(void)
{     LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
        GotoXY(0, 0);
    Print("---Stopwatch----");
    GotoXY(1, 1);
    Print(stop_watch_value);
    stopwatch_flag=1;
     Delay1ms(200);
}
void outkey()                    //跳出调整模式,返回默认显示
{ uchar Second;
  if(out==0)         
  { mdelay(8); 
    count=0;
    hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;
    Second=Read1302(DS1302_SECOND);
    Write1302(0x8e,0x00); //写入允许
    Write1302(0x80,Second&0x7f);
    Write1302(0x8E,0x80);          //禁止写入
    done=0;           
    while(out==0);
      settime_flag=0;
  }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Upkey()//升序按键
{       
        Up=1;
        if(Up==0)
                  {
                   mdelay(8);
                       switch(count)
                          {case 1:
                                  temp=Read1302(DS1302_SECOND);  //读取秒数
                                  temp=temp+1;  //秒数加1
                                  up_flag=1;    //数据调整后更新标志
                                  if((temp&0x7f)>0x59)   //超过59秒,清零
                                  temp=0;                                  
                                  break;
                           case 2:
                                  temp=Read1302(DS1302_MINUTE);  //读取分数
                                  temp=temp+1;  //分数加1
                                  up_flag=1;
                                  if(temp>0x59)          //超过59分,清零
                                  temp=0;
                                  break;
                           case 3:
                                  temp=Read1302(DS1302_HOUR);  //读取小时数
                                  temp=temp+1;  //小时数加1
                                  up_flag=1;
                                  if(temp>0x23)   //超过23小时,清零
                                  temp=0;
                                  break;
                           case 4:
                                  temp=Read1302(DS1302_WEEK);  //读取星期数
                                  temp=temp+1;  //星期数加1
                                  up_flag=1;
                                  if(temp>0x7)  
                                  temp=1;
                                  break;
                           case 5:
                                  temp=Read1302(DS1302_DAY);  //读取日数
                                  temp=temp+1;  //日数加1
                                  up_flag=1;
                                  if(temp>0x31)
                                  temp=1;
                                  break;
                           case 6:
                                  temp=Read1302(DS1302_MONTH);  //读取月数
                                  temp=temp+1;  //月数加1
                                  up_flag=1;
                                  if(temp>0x12)
                                  temp=1;
                                  break;
                           case 7:
                                  temp=Read1302(DS1302_YEAR);  //读取年数
                                  temp=temp+1;  //年数加1
                                  up_flag=1;
                                  if(temp>0x85)
                                  temp=0;
                                  break;
                           default:break;
                          }
                      
                   while(Up==0);
                  }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Downkey()//降序按键
{        
        Down=1;
        if(Down==0)
                  {
                   mdelay(8);
                     switch(count)
                          {case 1:
                                  temp=Read1302(DS1302_SECOND);  //读取秒数
                                  temp=temp-1;                            //秒数减1
                                  down_flag=1;       //数据调整后更新标志
                                  if(temp==0x7f)     //小于0秒,返回59秒
                                  temp=0x59;
                                  break;
                           case 2:
                                  temp=Read1302(DS1302_MINUTE);  //读取分数
                                  temp=temp-1;  //分数减1
                                  down_flag=1;
                                  if(temp==-1)
                                  temp=0x59;      //小于0秒,返回59秒
                                  break;
                           case 3:
                                  temp=Read1302(DS1302_HOUR);  //读取小时数
                                  temp=temp-1;  //小时数减1
                                  down_flag=1;
                                  if(temp==-1)
                                  temp=0x23;
                                  break;
                           case 4:
                                  temp=Read1302(DS1302_WEEK);  //读取星期数
                                  temp=temp-1;  //星期数减1
                                  down_flag=1;
                                  if(temp==0)
                                  temp=0x7;;
                                  break;
                           case 5:
                                  temp=Read1302(DS1302_DAY);  //读取日数
                                  temp=temp-1;  //日数减1
                                  down_flag=1;
                                  if(temp==0)
                                  temp=31;
                                  break;
                           case 6:
                                  temp=Read1302(DS1302_MONTH);  //读取月数
                                  temp=temp-1;  //月数减1
                                  down_flag=1;
                                  if(temp==0)
                                  temp=12;
                                  break;
                           case 7:
                                  temp=Read1302(DS1302_YEAR);  //读取年数
                                  temp=temp-1;  //年数减1
                                  down_flag=1;
                                  if(temp==-1)
                                  temp=0x85;
                                  break;
                          default:break;
                         }
                     
                   while(Down==0);
                  }
}
void Setkey()//模式选择按键
{
        Set=1;
        out=1;
        stop_watch=1;
        if(Set==0)
        {
           mdelay(2);
           count=count+1;     //Setkey按一次,count就加1
           done=1;             //进入调整模式
           while(Set==0);
  
         }
         if(stop_watch==0)
            {
           mdelay(8);
             done=1;
           stopwatch_flag=1;
             
           while(stop_watch==0);
                                  
        while(stopwatch_flag){    
               if(Set==0)
                   {    while(Set==0);
                    TR0=1;    
                 }
            if(Up==0){
                    while(Up==0);
                    TR0=0;}
            if(Down==0)
                {     while(Down==0);
                    minite=0;
                     second=0;
                    count_stop=0;
                    trasfer();
                    }
            if(out==0)
            {     while(out==0);
                stopwatch_flag=0;
                done=0;
            
                goto kip;
            }
                trasfer();
             disp_strstowatch();
            }
         }
kip:  LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏    
    
}
void alarm(void)
{    uchar alarm_tmph,alarm_tmpm,alarm_tmps;    
    while(1){    
               if(Set==0)
                   {    while(Set==0);
                    alarm_tmph++;
                    if(alarm_tmph>=24)
                    alarm_tmph=0;
                     stralarm[0]=alarm_tmph/10+0x30;
                     stralarm[1]=alarm_tmph%10+0x30;
                 }
                 
            if(Up==0){
                    while(Up==0);
                    alarm_tmpm++;
                    if(alarm_tmpm>=60)
                    alarm_tmpm=0;
                     stralarm[3]=alarm_tmpm/10+0x30;
                     stralarm[4]=alarm_tmpm%10+0x30;
                    
                    }
                    
            if(Down==0)
                {     while(Down==0);
                    alarm_tmps++;
                    if(alarm_tmps>=60)
                    alarm_tmps=0;
                     stralarm[6]=alarm_tmps/10+0x30;
                     stralarm[7]=alarm_tmps%10+0x30;
                    }
            if(out==0)
            {     while(out==0);
                stopwatch_flag=0;
                done=0;
                stop_watch=1;
                
                goto kip2;
            }
        disp_alarm();
            }
kip2: LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏    
    
            stralarm[2]=':';
            stralarm[5]=':';
            Write1302(0x8e,0x00); //写入允许          
            WriteRAM(0,stralarm,9);
         Write1302(0x8e,0x80); //禁止写入    */
}
void keydone()//按键功能执行
{        uchar Second;
    if(flag==0)    //关闭时钟,停止计时
         { Write1302(0x8e,0x00); //写入允许
           temp=Read1302(0x80);
           Write1302(0x80,temp|0x80);
           Write1302(0x8e,0x80); //禁止写入
           flag=1;
         }
         Setkey();                            //扫描模式切换按键
         switch(count)
         {case 1:do                            //count=1,调整秒
                  {
                   outkey();               //扫描跳出按钮
                   Upkey();                //扫描加按钮
                   Downkey();              //扫描减按钮
                   if(up_flag==1||down_flag==1)  //数据更新,重新写入新的数据
                   {
                   Write1302(0x8e,0x00); //写入允许
                   Write1302(0x80,temp|0x80); //写入新的秒数
                   Write1302(0x8e,0x80); //禁止写入
                   up_flag=0;
                   down_flag=0;
                   }
                   hide_sec++;          //位闪计数
                   if(hide_sec>3)
                     hide_sec=0;
                               show_time();         //液晶显示数据
                  }while(count==2);
                  break;  
          case 2:do                            //count=2,调整分
                  {
                   hide_sec=0;
                   outkey();
                   Upkey();
                   Downkey();
                   if(temp>0x60)
                     temp=0;
                   if(up_flag==1||down_flag==1)
                   {
                   Write1302(0x8e,0x00); //写入允许
                   Write1302(0x82,temp); //写入新的分数
                   Write1302(0x8e,0x80); //禁止写入
                   up_flag=0;
                   down_flag=0;
                   }
                   hide_min++;
                   if(hide_min>3)
                     hide_min=0;
                   show_time();
                  }while(count==3);break;
          case 3:do                            //count=3,调整小时
                  {
                   hide_min=0; 
                   outkey();
                   Upkey();
                   Downkey();
                   if(up_flag==1||down_flag==1)
                   {
                   Write1302(0x8e,0x00); //写入允许
                   Write1302(0x84,temp); //写入新的小时数
                   Write1302(0x8e,0x80); //禁止写入
                   up_flag=0;
                   down_flag=0;
                   }
                   hide_hour++;
                   if(hide_hour>3)
                     hide_hour=0;
                   show_time();
                  }while(count==4);break;
          case 4:do                            //count=4,调整星期
                  {
                   hide_hour=0; 
                   outkey();
                   Upkey();
                   Downkey();
                   if(up_flag==1||down_flag==1)
                   {
                   Write1302(0x8e,0x00); //写入允许
                   Write1302(0x8a,temp); //写入新的星期数
                   Write1302(0x8e,0x80); //禁止写入
                   up_flag=0;
                   down_flag=0;
                   }
                   hide_week++;
                   if(hide_week>3)
                     hide_week=0;
                   show_time();
                  }while(count==5);break;
          case 5:do                            //count=5,调整日
                  {
                   hide_week=0; 
                   outkey();
                   Upkey();
                   Downkey();
                   if(up_flag==1||down_flag==1)
                   {
                   Write1302(0x8e,0x00); //写入允许
                   Write1302(0x86,temp); //写入新的日数
                   Write1302(0x8e,0x80); //禁止写入
                   up_flag=0;
                   down_flag=0;
                   }
                   hide_day++;
                   if(hide_day>3)
                     hide_day=0;
                   show_time();
                  }while(count==6);break;
          case 6:do                            //count=6,调整月
                  {
                   hide_day=0; 
                   outkey();
                   Upkey();
                   Downkey();
                   if(up_flag==1||down_flag==1)
                   {
                   Write1302(0x8e,0x00); //写入允许
                   Write1302(0x88,temp); //写入新的月数
                   Write1302(0x8e,0x80); //禁止写入
                   up_flag=0;
                   down_flag=0;
                   }
                   hide_month++;
                   if(hide_month>3)
                     hide_month=0;
                   show_time();
                  }while(count==7);break;
          case 7:do                            //count=7,调整年
                  {
                   hide_month=0; 
                   outkey();
                   Upkey();
                   Downkey();
                   if(up_flag==1||down_flag==1)
                   {
                   Write1302(0x8e,0x00); //写入允许
                   Write1302(0x8c,temp); //写入新的年数
                   Write1302(0x8e,0x80); //禁止写入
                   up_flag=0;
                   down_flag=0;
                   }
                   hide_year++;
                   if(hide_year>3)
                     hide_year=0;
                   show_time();
                  }while(count==8);break;
          case 8: count=0;hide_year=0;  //count8, 跳出调整模式,返回默认显示状态
                  Second=Read1302(DS1302_SECOND);
                  Write1302(0x8e,0x00); //写入允许
                  Write1302(0x80,Second&0x7f);
                  Write1302(0x8E,0x80);          //禁止写入
                  done=0;
          case 9:alarm(); break;
          break; //count=7,开启中断,标志位置0并退出
          default:break;
         }
}
void gettime(void)
{    DS1302_GetTime(&CurrentTime);  //获取时钟芯片的时钟数据到自定义的结构型数组
    DateToStr(&CurrentTime);    //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
    TimeToStr(&CurrentTime);  //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];
    if(hide_day<2)
    {    DateStr[0]=(CurrentTime.Day)/10+0x30;
        DateStr[1]=(CurrentTime.Day)%10+0x30;
        }
      else
      {
        DateStr[0] = ' ';
        DateStr[1] = ' ';        
      }
}
void show_time()   //液晶显示程序
{
    gettime();
  GotoXY(0,1);
  Print(CurrentTime.TimeString); //显示时间
  if(!settime_flag)        //显示乱码,可能需要去掉
  {    
      GotoXY(0,0);
Print(CurrentTime.DateString); //显示日期
    
    GotoXY(8,0);
Print(DateStr); //显示日
  GotoXY(15,0);
  Print(week_value);             //显示星期
  GotoXY(11,0);
  Print("Week");    //在液晶上显示 字母 week
  }
  if(alarm_on==1)
  {     GotoXY(11,1);
  Print("alarm");
  }
  Delay1ms(300);                 //扫描延时
}
void time_init(void)
{    IE=0x82;
    TCON=0x00;
    EA=1;
    TMOD=0X01;
    TH0=(56636-1500)/256;
    TL0=(56636-1500)%256;
    TR0=0;
}
void alarm_chage(void)
{
    if(Down==0)
            {     
                while(Down==0);
                iii++;
                if(iii==1)
                {    alarm_on=1;
                alarm_flag[0]='*';
                
                }
                if(iii==2) 
                 {
                 alarm_flag[0]='.';
                     alarm_on=0;
                    }
                 if(iii==3)
                 iii=0; 
            alarm_flag_sto[0]=alarm_on;
            Write1302(0x8e,0x00); //写入允许          
            WriteRAM(12,alarm_flag_sto,1);
         Write1302(0x8e,0x80); //禁止写入    */
                    
                
            }
}
main()
{
        flag=1;           //时钟停止标志
    LCD_Initial();    //液晶初始化
    
    Initial_DS1302(); //时钟芯片初始化
    up_flag=0;
    down_flag=0;
    done=0;           //进入默认液晶显示
    b=1;
    P3=0xff;
    time_init();               
    ReadRAM(0,stralarm,9);
    ReadRAM(12,alarm_flag_sto,1);    
    alarm_on=alarm_flag_sto[0];
    
    while(1)
    {   
           while(done==1)
          { keydone();    //进入调整模式
          fz();
          }
        while(done==0)
         {  
            show_time();                //液晶显示数据
            flag=0;                  
              Setkey();     //扫描各功能键
            fz();
            alarm_chage();
         }
    }
}
void clok(void) interrupt 1
{    TH0=(56636-1500)/256;
    TL0=(56636-1500)%256;
    while(++count_stop==100)
    {    count_stop=0;
        second++;
        if(second>=60)
        {    second=0;
            minite++;
            if(minite>=60)
            {    minite=0;
                
            }
        }
    }
}