原创 DS1302 万年历的制作

2009-3-9 21:45 5047 3 4 分类: MCU/ 嵌入式
      上次做了简单的数码管数字钟(详情请点击http://www.555diy.com/n_show.asp?nid=66),后来又修改了程序,改成自己想要的按键设置方法(详情请点击http://bbs.555diy.com/dispbbs.asp?boardID=8&ID=298&page=1)。功能是实现了,可是觉得太浪费了89S52,做的也不够好看,拿不出手,于是开始酝酿做个漂亮一点的,至少像个产品,也进一步锻炼自己的编程能力,毕竟我也只能算个初学者。
      为了让万年历的时钟走的更准,在网上了解了一些资料后,决定用DS1302做为时钟芯片(下载DS1302中文资料请点击http://www.555diy.com/s_show.asp?sid=19)。要显示年、月、日、星期、时、分、秒一共需要15个数码管,如果只显示时间的话有点单调,于是又加个3个数码管用来显示温度。一共18个数码管,不能用IO口直接驱动了,那样的话占用的IO口多,也怕到时候扫描下来会出现闪烁。看了其他人的一些方案后,决定将“年”的前2位(20)用一个口驱动,剩下的16个数码管用2个74HC164来输出段码,用P0口来驱动片选。那用什么来检测温度呢?网上查了一下,觉得DS18B20不错,也有一些实例程序可以借鉴,不过价格偏贵。用555和热敏电阻组成测温的话,因为热敏电阻的阻值不是线性的,做的准不容易。考虑来考虑去,决定把这两个都LAY在板子上。另外加个4个按键,几个LED指示灯,还有用来当闹钟的蜂鸣器。另外加了24C01用来存储设定的闹钟时间。

      原理图如下:


2007101191554857.jpg 


       后来才发现控制板的排阻位置放错了,该打PP    ^__^


200710119165129.jpg  


       LAY好的PCB


2007101191627919.jpg


2007101191636656.jpg


       下面是做好的板子,这年头什么都涨价,PCB也涨啊~~~晒晒图先~


2007101191657403.jpg


     再来几张焊上元件的图


2007101191716896.jpg


2007101191726977.jpg


2007101191743615.jpg


      接下来是工作中的万年历,白天拍的,数码管不是很亮,程序还没有完全编好,有些功能还没实现


2007101191753189.jpg


    下面这张是在设定闹钟时的万年历


200710119183383.jpg


     现在一天走下来的话会快3、4秒,看了DS1302的DATASHEET,说是在晶振的两端并一6PF的电容会好点。


     有何问题和建议可以去论坛http://bbs.555diy.com/dispbbs.asp?boardID=8&ID=326&page=1讨论,谢谢!


按键功能描述:


正常显示下:


                按S1:全部数码管闪烁 → 按S3进入时间设定模式


                                               → 按S4进入闹钟设定模式


               按S2:进入睡眠模式,全部数码管熄灭,LED6闪烁 → 按S1恢复显示


               按S3:闹钟关闭


               按S4:闹钟打开,并显示闹钟时间3秒


时间设定模式及闹钟设定模式:


               按S1:不设定时间或闹钟


               按S2:待设定数码管左移


               按S3:待设定数码管+1


               按S4:保存设定


C代码如下:


//*****************************************************//
//           www.555diy.com 三五电子网                                                    //
//作者;ksysl                                                                                         //
//日期:2008-03-04                                                                              //
//PCB型号:calendar001-A  calendar001-B(组合而成)                         //
//软件版本:DS1302 002-A                                                                    //
//*****************************************************//


 


//*****************************************************//               
              
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>


unsigned char year,month,day,week,hour,minute,second;
unsigned char temp_1,temp_2,temp_3;


unsigned char buff1,buff2;
unsigned char disp_data;
unsigned int temp_data;



unsigned char led_flash_flag;                //设定时间时数码管闪烁用
unsigned char tcnt;


unsigned char add_data;                      //设时数据暂放用
unsigned char save_data;                     //保存设时用
unsigned char led_data1,led_data2,led_data3,led_data4,led_data5,led_data6,led_data7;//设定时间数据保存区
unsigned char led_data8,led_data9,led_data10,led_data11,led_data12,led_data13;      //设定时间数据保存区
unsigned char key;
unsigned char key_qu;
unsigned char key_flag;


unsigned char set_flag;   //=0 正常显示时间;=1设定时间;=2设定闹钟时间;=3不显示时间;=4选择设定时间还是闹钟;                        
unsigned char led_select;                   //数码管选择用
unsigned char set_time_over;                //60秒无按键按下自动返回用
unsigned char led_select1,led_select2;      //数码管闪烁选择用
unsigned char sleep;                        //=1关闭数码管显示用
unsigned char clock_set;                    //闹钟设定标志,=1关闭其余数码管
unsigned char clock_set_flag;
unsigned char clock_hour,clock_minute,clock_second;//闹钟时间
unsigned char hour_data,minute_data,second_data;   //正常显示时间暂放区
unsigned char clock_time;                          //闹钟响铃记时
unsigned char clock_come;                          //闹钟时间到标志


unsigned char code disp_code[]={0x3f,0x06,0x5b,0x4f,
                               0x66,0x6d,0x7d,0x07,
                               0x7f,0x6f,0x00};                    //0~9段码    第10位为设定时间时数码管闪烁用


 


sbit s1=P2^0;                             //按键定义
sbit s2=P2^1;
sbit s3=P2^2;
sbit s4=P2^3;


sbit hc164data=P2^7;                      //74HC164数据口
sbit hc164clock=P2^6;                     //74HC164时钟口


sbit clock="P1"^0;                          //闹钟打开显示  LOW----亮
sbit wake_up=P1^1;                        //定时唤醒显示  LOW----亮
sbit led_flash=P1^2;                      //正常显示时LED闪烁控制  LOW----亮
sbit year_20=P1^3;                        //年份前两位显示控制     LOW----亮
sbit buzzer="P1"^4;                         //闹钟时间到响铃用       LOW----响


sbit ds1302_sclk=P1^5;                    //DS1302时钟口
sbit ds1302_rst=P1^6;                     //DS1302复位口
sbit ds1302_data=P1^7;                    //DS1302数据口


sbit DQ="P3"^7;                             //DS18B20数据口



void display(void);
void key_scan(void);
void send_hc164_data(void);
void delay(unsigned char time);


void int_1(void);
void int_0(void);
void time_1(void);


 


//延时函数
void delay_us(unsigned int us)    
{
   for(;us>0;us--);
}
 


//初始化函数
unsigned char RES_DS18B20(void)
{
 unsigned char x;


 DQ = 0;         //DQ复位
 delay_us(29);   //精确延时 大于 480us  
 DQ = 1;        
 delay_us(3);    //稍做延时
 x=DQ;
 delay_us(25);
 return(x);      //稍做延时后 如果x=0则初始化成功 x="1则初始化失败"
}


//读一个字节
unsigned char ReadOneChar(void)
{
 unsigned char i;
 unsigned char dat="0";
 for (i=8;i>0;i--)
 {
  dat>>=1;
  DQ = 0;     // 给脉冲信号 
  DQ = 1;     // 给脉冲信号
  delay_us(1);
  if(DQ==1)
    {
     dat|=0x80; 
 }
  delay_us(6);
 }
 return(dat);
}


//写一个字节
WriteOneChar(unsigned char da)
{
 unsigned char i;
 for (i=8; i>0; i--)
 {
  DQ = 0;
  DQ = da&0x01;


  delay_us(5);
  DQ = 1;
  da="da/2";
 }
delay_us(5);
}


//读取温度
float ReadTemperature(void)
{
 unsigned char a="0";
 unsigned char b="0";
 unsigned char c="0";
 unsigned char d="0";
 unsigned int  t="0";
 float tt="0";


 


 RES_DS18B20();


 WriteOneChar(0xCC); // 跳过读序号列号的操作
 WriteOneChar(0x44); // 启动温度转换
 delay_us(10);
 RES_DS18B20();
 WriteOneChar(0xCC); //跳过读序号列号的操作
 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
 a=ReadOneChar();  //LSB
 b=ReadOneChar();  //MSB


  t="b"*256+a;   //将char转为int型

 tt=t*0.0625;      //实际温度
 
 tt= tt*10+0.5;      //  将实际温度放大10倍输出并四舍五入



 return(tt);
}


 


 


//********DS1302读写程序**********************************************//
/**********************************************************************
函 数 名:input_byte1302()
功    能:实时时钟写入一字节
说    明:往DS1302写入1Byte数据 (内部函数)
入口参数:inputdata 写入的数据
返 回 值:无 
***********************************************************************/
void input_byte1302(unsigned char inputdata)
{
    unsigned char i;
    for(i=8; i>0; i--)
    {
        ds1302_data = (bit)(inputdata&0x01);

        ds1302_sclk = 1;
        ds1302_sclk = 0;

        inputdata = inputdata >>1;
    }
}
/********************************************************************
函 数 名:output_byte1302()
功    能:实时时钟读取一字节
说    明:从DS1302读取1Byte数据 (内部函数)
入口参数:无 
返 回 值:outputdata
设    计:                     日    期:
修    改:                     日    期:
***********************************************************************/
unsigned char output_byte1302(void)
{
    unsigned char i;
    for(i=0; i<8; i++)
    {    
   ACC = ACC >>1;      //相当于汇编中的 RRC        
      ACC7 = ds1302_data;
      ds1302_sclk = 1;
      ds1302_sclk = 0;
    }
    return(ACC);
}
/********************************************************************
函 数 名:write1302()
功    能:往DS1302写入数据
说    明:先写地址,后写命令/数据 (内部函数)
调    用:input_byte1302()
入口参数:addr: DS1302地址, indata: 要写的数据
返 回 值:无
***********************************************************************/
void write1302(unsigned char addr, unsigned char indata)
{
    ds1302_rst = 0;
    ds1302_sclk = 0;
    ds1302_rst = 1;
    input_byte1302(addr);           // 地址,命令
    input_byte1302(indata);         // 写1Byte数据
    ds1302_sclk = 1;
    ds1302_rst = 0;
}
/********************************************************************
函 数 名:read1302()
功    能:读取DS1302某地址的数据
说    明:先写地址,后读命令/数据 (内部函数)
调    用:input_byte1302() , output_byte()
入口参数:addr: DS1302地址
返 回 值:outdata :读取的数据
***********************************************************************/
unsigned char read1302(unsigned char addr)
{
    unsigned char outdata;
    ds1302_rst = 0;
    ds1302_sclk = 0;
    ds1302_rst = 1;
    input_byte1302(addr);                // 地址,命令
    outdata = output_byte1302();         // 读1Byte数据
    ds1302_sclk = 1;
    ds1302_rst = 0;
    return(outdata);
}



void delay(unsigned char time)           //延时
{
  unsigned char m;
  unsigned char n;
  for(m=time;m>0;m--)
  for(n=248;n>0;n--);
}


//********************************************************************//
//                     74hc164发送数据
void send_hc164_data(void)               
{
  unsigned char i;
  disp_data=disp_code[buff2];
  hc164clock=0;
  for(i=0;i<8;i++)
     {  
      hc164data=(bit)(disp_data&0x80);
      hc164clock=1;   
   disp_data<<=1;
      hc164clock=0;
     }
  disp_data=disp_code[buff1];
  for(i=0;i<8;i++)
     {
      hc164data=(bit)(disp_data&0x80);
      hc164clock=1;
      disp_data<<=1;
      hc164clock=0;
     }
  hc164clock=0;
}
//                    74hc164发送数据结素
//**************************************************************************//



//**************************************************************************//                 
//                  数码管显示程序开始


void display()                    
{
  if(sleep==0)
    {
  if(clock_set==0)
    {
        year_20=0;
        delay(3);
        year_20=1;
       }
//************************************************************************// 
     if(((bit)(led_select1&0x01)==1)||(clock_set==1))
       {
        buff1=10;
    }
     else
       {
     buff1=led_data1;
       }


     if((bit)(led_select2&0x01)==1)
       {
        buff2=10;
    }
     else
       {
     buff2=led_data8;
    } 



  send_hc164_data();
     P0=0xfe;
     delay(3);


     P0=0xff;


//***********************************************************************//
     if(((bit)(led_select1&0x02)==1)||(clock_set==1))
       {
        buff1=10;
    }
     else
       {
     buff1=led_data2;
    }
     if((bit)(led_select2&0x02)==1)
       {
        buff2=10;
    }
     else
       {
     buff2=led_data9;
    }


     send_hc164_data();


     P0=0xfd;
     delay(3);


     P0=0xff;


//************************************************************************//
     if(((bit)(led_select1&0x04)==1)||(clock_set==1))
       {
        buff1=10;
    }
     else
       {
     buff1=led_data3;
    }


     if((bit)(led_select2&0x04)==1)
       {
        buff2=10;
    }
     else
       {
     buff2=led_data10;
    }


     send_hc164_data();


     P0=0xfb;
     delay(3);


     P0=0xff;


//***********************************************************************//
     if(((bit)(led_select1&0x08)==1)||(clock_set==1))
       {
        buff1=10;
    }
     else
       {
        buff1=led_data4;
       }


     if((bit)(led_select2&0x08)==1)
       {
        buff2=10;
    }
     else
       {
     buff2=led_data11;
    }


     send_hc164_data();


     P0=0xf7;
     delay(3);


     P0=0xff;


//***********************************************************************//
     if(((bit)(led_select1&0x10)==1)||(clock_set==1))
       {
        buff1=10;
    }
     else
       {
     buff1=led_data5;
      }


     if((bit)(led_select2&0x10)==1)
       {
        buff2=10;
    }
     else
       {
     buff2=led_data12;
    }


     send_hc164_data();


     P0=0xef;
     delay(3);


     P0=0xff;


//**********************************************************************//
     if(((bit)(led_select1&0x20)==1)||(clock_set==1))
       {
        buff1=10;
    }
     else
       {
        buff1=led_data6;
    }
     if((bit)(led_select2&0x20)==1)
       {
        buff2=10;
    }
     else
       {
     buff2=led_data13;
       }


     send_hc164_data();


     P0=0xdf;
     delay(3);


     P0=0xff;


//*************************************************************************//
     if(((bit)(led_select1&0x40)==1)||(clock_set==1))
       {
        buff1=10;
    }
     else
       {
     buff1=led_data7;
      }
     if(clock_set==1)
       {
        buff2=10;
    }
  else
    {
     buff2=temp_1;
    }
     send_hc164_data();
     P0=0xbf;
     delay(3);


     P0=0xff;


//**************************************************************************//
     if(clock_set==0)
       {
        buff1=temp_3;
        buff2=temp_2;


       send_hc164_data();
       P0=0x7f;
       delay(3);


       P0=0xff;
   }
 }
//****************************************************************************//
//                     需设定数码管闪烁,设定时间和闹钟共用
  if((set_flag==1)||(set_flag==2))
    {
     switch(led_select)
       {
      case 1: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select1=0x01;
       }
       break;
   case 2: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select1=0x02;
       }
       break;
      case 3: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select1=0x04;
       }
       break;
   case 4: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select1=0x08;
       }
       break;
      case 5: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select1=0x10;
       }
       break;
   case 6: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select1=0x20;
       }
       break;
      case 7: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select1=0x40;
       }
       break;
   case 8: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select2=0x01;
       }
       break;
   case 9: led_select1=0x00;
           led_select2=0x00;
           if(led_flash_flag==0)
              {
        led_select2=0x02;
       }
       break;
   case 10: led_select1=0x00;
            led_select2=0x00;
            if(led_flash_flag==0)
               {
         led_select2=0x04;
        }
       break;
   case 11: led_select1=0x00;
            led_select2=0x00;
            if(led_flash_flag==0)
               {
         led_select2=0x08;
        }
       break;
   case 12: led_select1=0x00;
            led_select2=0x00;
            if(led_flash_flag==0)
               {
         led_select2=0x10;
        }
       break;
   case 13: led_select1=0x00;
            led_select2=0x00;
            if(led_flash_flag==0)
               {
         led_select2=0x20;
        }
       break;
      default : break;
    }
  }
}
//*****************************************************************************************//
//                             数码管显示程序结束
//********************************************************************************//


//**********************************************************************************//
//                             按键处理程序开始
void key_scan(void)
{
  if(clock_come==1)                              //闹钟响时按S1,关闭闹钟
    {
     if(s1==0)
       {
          clock_come=0;
          clock="0";
          buzzer="1";
    set_flag=0;
       }
    }


  if(set_flag==2)               
    {
     if(s1==0)                                  //闹钟时间设定时按S1,退出闹钟设定时间,不保存闹钟设定时间
       {
        set_time_over=119;
       }


  if(s4==0)                                  //闹钟时间设定时按S4,保存闹钟设定时间
    {    
     clock="0";
//     led_data8=led_data8<<4;  
     clock_hour=(led_data8*10+led_data9);


//      led_data10=led_data10<<4;
     clock_minute=(led_data10*10+led_data11);


//      led_data12=led_data12<<4;
     clock_second=(led_data12*10+led_data13);


        set_time_over=119;
    }
    }


   if(set_flag==4)        
  {
   if(s1==0)          //时间设定选择时按S1退出选择
     {
   set_time_over=119;
  }


   if(s3==0)                                  //时间设定选择时按S3进入时间设定                                
     {
   sleep="0";
   set_flag=1;
   led_flash=1;
   led_select=1;
  }


   if(s4==0)                                  //时间设定选择时按S4进入闹钟设定
  {    
   sleep="0";
      clock_set=1;
   set_flag=2;
   led_select=8;
   led_flash=1;


      led_data8=clock_hour/10;
   led_data9=clock_hour%10;


   led_data10=clock_minute/10;
   led_data11=clock_minute%10;


   led_data12=clock_second/10;
   led_data13=clock_second%10;
     }   
 }



  if(set_flag==1)                                
    {
     if(s1==0)         //设定时间的情况下再按S1,退出设定时间,不保存设定时间
       {
        set_time_over=119;
       }
             
  if(s4==0)                            //设定时间的情况下按S4,保存设定时间
    {    
        write1302(0x8e,0x00);
  led_data12=led_data12<<4;
  save_data=led_data12+led_data13;
        write1302(0x80,save_data);


     led_data10=led_data10<<4;
     save_data=led_data10+led_data11;
     write1302(0x82,save_data);


     led_data8=led_data8<<4;
     save_data=led_data8+led_data9;
  write1302(0x84,save_data);


  led_data5=led_data5<<4;
  save_data=led_data5+led_data6;
  write1302(0x86,save_data);


  led_data3=led_data3<<4;
  save_data=led_data3+led_data4;
  write1302(0x88,save_data);


        save_data=led_data7;
     write1302(0x8a,save_data);


  led_data1=led_data1<<4;
     save_data=led_data1+led_data2;
  write1302(0x8c,save_data);
    
        write1302(0x8e,0x80);


        set_time_over=119;
    }
 }



    



  if(set_flag==1)               //设定时间
    {
  if(s2==0)                  //按S2需设定数码管右移
    {
  set_time_over=0;
  led_select++;
  if(led_select==14)
    {
     led_select=1;
    }
    }
 }
         
  if(set_flag==2)               //闹钟设定时间
    {
     if(s2==0)                  //按S2需设定数码管右移
       {
     set_time_over=0;
        led_select++;
        if(led_select==14)
          {
           led_select=8;
       }
    }
 }


     
     
  if((set_flag==1)||(set_flag==2))  //按S3需设定数码管加1,设定时间和闹钟共用
    {
     if(s3==0)
       {
        set_time_over=0;
  switch(led_select)
        {
         case 1: 
                           led_data1++;
                  if(led_data1==10)
              {
            led_data1=0;
           }


            break;


      case 2: 
               led_data2++;
         if(led_data2==10)
           {
         led_data2=0;
        }
      
         break;


         case 3: 
                           led_data3++;
                  if(led_data3==2)
              {
            led_data3=0;
           }
                       
            break;


      case 4: 
               led_data4++;
         if(led_data4==10)
           {       
          led_data4=0;
           }
     
         break;


         case 5: 
                           led_data5++;
                  if(led_data5==4)
              {
            led_data5=0;
           }
                      
            break;


      case 6: 
               led_data6++;
         if(led_data6==10)
           {     
         led_data6=0;
         }
     
         break;


      case 7: 
               led_data7++;
         if(led_data7==8)
           {     
         led_data7=1;
        }
       
         break;


         case 8: 
                           led_data8++;
                  if(led_data8==3)
              {
            led_data8=0;
           }
                       
            break;


      case 9: 
               led_data9++;
         if(led_data9==10)
           {     
         led_data9=0;
         }
       
         break;


         case 10:
                           led_data10++;
                  if(led_data10==6)
              {
            led_data10=0;
           }
                         
            break;


      case 11:
               led_data11++;
         if(led_data11==10)
           {     
         led_data11=0;
        }
       
         break;


         case 12:
                           led_data12++;
                  if(led_data12==6)
              {
            led_data12=0;
          , ; }
                       
            break;


      case 13:
               led_data13++;
         if(led_data13==10)
           {     
         led_data13=0;
        }
        
         break;


        default : break;
     }
    }
  }



   if((set_flag==0)&&(clock_come==0))
     {    
   if(s1==0)                                  //正常显示下(不闹钟),按S1进入设定选择模式
     {    
   set_time_over=0;
   tcnt="0";
   led_flash=1;
      set_flag=4;
  }


      if(s2==0)                                  //正常显示下(不闹钟),关闭显示
     {
      sleep="1";
      wake_up=0;
      set_flag=3;
      led_flash=1;
     }
            
   if(s3==0)          //正常显示下,按S3关闭闹钟LED,关闭闹钟
     {
   clock="1";
  }


      if(s4==0)                                  //正常显示下,按S4显示闹钟时间,并打开闹钟LED
     {
   buzzer="1";
   clock="0";
   clock_set=1;
   set_time_over=110;
   led_data8=clock_hour/10;
   led_data9=clock_hour%10;


   led_data10=clock_minute/10;
   led_data11=clock_minute%10;


   led_data12=clock_second/10;
   led_data13=clock_second%10;
   set_flag=5;
     }
     }



   if(set_flag==3)                //关闭显示的情况下,再次按S1打开显示
     {
   if(s1==0)
     {
      set_flag=0;
      sleep="0";
      wake_up=1;
     }
  }             
}


//                                    按键处理结束
//************************************************************************//


 



//************************************************************************//
//                                     主程序


void main(void)
{
  TMOD="0x10";
  TH1=(65536-50000)/256;
  TL1=(65536-50000)%256;


  TR1=1;
  ET1=1;
 
  EX1=1;              //外部中断1    按键扫描用
  IT1=1;              //外部中断1 边沿触发 若为0 电平触发
  EA="1";


  set_flag=0;
  led_flash_flag=1;
  led_flash=1;
  key_flag=0;
  clock="0";
  sleep="0";
  led_select=0;
  led_select1=0;
  led_select2=0;
  clock_set_flag=0;
  clock_come=0;
  P0=0xff;
  s1=1;
  s2=1;
  s3=1;
  s4=1;



  clock_hour=12;        //闹钟付初值
  clock_minute=0;
  clock_second=0;


  write1302(0x90,0xa0);//关闭充电二级管,不能对后备电池进行充电,防止发胀,原来的程序是打开的请关闭
  write1302(0x8e,0x80);//写保护,禁止写操作
//set1302(inittime);
//write1302(0x8e,0x00);  
//write1302(0x88,2);
//write1302(0x8e,0x80);


  while(1)
    {
     if((set_flag==0)||(set_flag==3))                                
    {
     EA="0";
     temp_data=ReadTemperature();     //读取温度
     temp_1=temp_data/100;       //显示数据处理
     temp_2=temp_data%100/10;
     temp_3=temp_data%100%10;
  EA=1;
                  
     second="read1302"(0x81);    //读取DS1302数据
  led_data13=second&0x0f;
  second=second >> 4;
  led_data12=second&0x07;


     minute="read1302"(0x83);
  led_data11=minute&0x0f;
  minute=minute >> 4;
  led_data10=minute&0x07;


     hour="read1302"(0x85);
        led_data9=hour&0x0f;
  hour=hour >> 4;
  led_data8=hour&0x03;


     day="read1302"(0x87);
  led_data6=day&0x0f;
  day=day >> 4;
  led_data5=day&0x03;


     month="read1302"(0x89);
  led_data4=month&0x0f;
  month=month >> 4;
  led_data3=month&0x01;


     week="read1302"(0x8b);
  led_data7=week;


     year="read1302"(0x8d);
  led_data2=year&0x0f;
  year=year >> 4;
  led_data1=year&0x0f;
    }


     if(clock==0)          //查询闹钟时间是否到
       {
     if((led_data8==clock_hour/10)&&(led_data9==clock_hour%10)&&(led_data10==clock_minute/10)&&
    (led_data11==clock_minute%10)&&(led_data12==clock_second/10)&&(led_data12==clock_second%10))      
       {
        clock_come=1;
       }
     if(clock_come==1)
       {
     if(set_flag==3)
       {
      set_flag=0;
    }
        if(led_flash==0)
       {
        buzzer="0";
       }
     else
       {
        buzzer="1";
             }
    }
  else
    {
     buzzer="1";
    }
    }
  else
    {
     buzzer="1";
    }
      
     display();
    
    if(key_qu==1)                                  //按键
       { 
        key_qu=0;
        key_flag=1;
        if(INT1==0)
          {    
           key_scan();
       }
        EX1=1;
    } 
    }
}


//**************************************************************//
//                     计数器1
void time_1(void) interrupt 3
{
 
  TH1=(65536-50000)/256;
  TL1=(65536-50000)%256;


  if(key_flag==0)
    {
     key_qu++;
    }



  tcnt++;
  if(set_flag==5)
    {
  if(tcnt==50)
    {
     tcnt="0";
  buzzer=1;
        set_flag=0;
//  clock=1;
  clock_set=0;
  clock_come=0;
    }
 }


  if(set_flag==4)
    {
  if(tcnt==5)
    {
     sleep="1";
    }
  if(tcnt==10)
    {
     tcnt="0";
     sleep="0";
     set_time_over++;
  if(set_time_over==120)
    {
     set_time_over=0;
     led_flash_flag=0;
     led_select1=0x00;
     led_select2=0x00;
     clock_set=0;
     clock_set_flag=0;
     sleep="0";
           set_flag=0;    
       }
       }
 }


  if((set_flag==0)||(set_flag==3))
    {
     if(tcnt==10)
       {
         tcnt="0";
   if(set_flag==0)
     {
         led_flash=~led_flash;
   sleep=0;
     }
   if(set_flag==3)
     {
      wake_up=~wake_up;
     }


   if(clock_come==1)                     //闹钟响记时60S
     {
      clock_time++;
   if(clock_time==120)
     {
      clock="0";
      buzzer="1";
      clock_come=0;
     }
     }
     }
  }



  if((set_flag==1)||(set_flag==2))
    {
     if(tcnt==5)
       {
        led_flash_flag=0;
    }
  if(tcnt==10)
    {
     tcnt="0";
  led_flash_flag=1;
  set_time_over++;
  if(set_time_over==120)
    {
     set_time_over=0;
     led_flash_flag=0;
     led_select1=0x00;
     led_select2=0x00;
     clock_set=0;
     clock_set_flag=0;
     sleep="0";
     clock_come=0;
           set_flag=0;
     if(set_flag==2)                         //设定闹钟时间情况下,60S自动退出闹钟设定,不保存设定数据
       {
     hour="hour"_data;
     minute="minute"_data;
     second="second"_data;
    }
    }
       }
    }
}
//                        计数器1程序结束
//**************************************************************//


 



//*******************************************************************//
//                        外部中断1(按键触发)
void int_1(void) interrupt 2
{
  EX1=0;
  key_flag=0;     
}
//****************************************************************************//

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2011-11-30 21:10

dear sir, pls send me circuit diagram of digital time/date clock and MCU code. thakyou Shahzad Ismail shahzad@brain.net.pk

相关推荐阅读
用户383241 2009-08-31 14:59
lcd1602使用
实际电路测试通过!仿真也有些效果!玩过了数码管和LED点阵后开始玩LCD就从最简单的LCD1602开始烧录IC太麻烦了,改用仿真之前下过好几个版本的PROTEUS,不过没用起来,昨天又下了一个,网上下...
用户383241 2009-06-02 20:59
ADC LTC1865 的PROTEUS仿真
在PROTEUS的库文件中找到了这颗ADC,16BIT,感觉不错https://static.assets-stash.eet-china.com/album/old-resources/2009/4...
用户383241 2009-06-02 20:59
秀一下DIY的0-30V可调电源
0-30V可调...
用户383241 2009-04-05 10:24
盲人探路器(三)
本例介绍的盲人探路器(三)与前两例不同之处是采用廉价的红外线接近反射感测模块制成,这种电子手杖可以在1.5m的范围内感测到前方障碍物的位置,大大有利于盲人的出行。 工作原理盲人探路器(三)的电路如图所...
用户383241 2009-04-05 10:21
LED点阵屏电子钟
 ...
用户383241 2009-03-15 21:24
盲人探路器(二)
本例介绍的盲人探路器与上例不同之处有两点:一是采用全集成化结构;二是它的超声波发射电路以LM567中压控振荡器的振荡输出作为超声波发射器的振荡频率。这不仅省去了专设的振荡电路,而且更有利于电路的调整。...
EE直播间
更多
我要评论
1
3
关闭 站长推荐上一条 /3 下一条