为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

万年历制作

2012-08-16 50页 doc 722KB 27阅读

用户头像

is_314448

暂无简介

举报
万年历制作 标签: DS1302,DS18B20,AT89S52,万年历   DS1302 万年历的制作       上次做了简单的数码管数字钟(详情请点击http://www.555diy.com/n_show.asp?nid=66),后来又修改了程序,改成自己想要的按键设置方法(详情请点击http://bbs.555diy.com/dispbbs.asp?boardID=8&ID=298&page=1)。功能是实现了,可是觉得太浪费了89S52,做的也不够好看,拿不出手,于是开始酝酿做个漂亮一点的,至少像个产品,也进一步锻炼自己的...
万年历制作
标签: DS1302,DS18B20,AT89S52,万年历   DS1302 万年历的制作       上次做了简单的数码管数字钟(详情请点击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用来存储设定的闹钟时间。       原理图如下:        后来才发现控制板的排阻位置放错了,该打PP    ^__^           LAY好的PCB        下面是做好的板子,这年头什么都涨价,PCB也涨啊~~~晒晒图先~      再来几张焊上元件的图       接下来是工作中的万年历,白天拍的,数码管不是很亮,程序还没有完全编好,有些功能还没实现     下面这张是在设定闹钟时的万年历      现在一天走下来的话会快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 #include #include 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=
/
本文档为【万年历制作】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索