找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3822|回复: 9
打印 上一主题 下一主题
收起左侧

DS1302单片机时钟仿真电路与程序

  [复制链接]
跳转到指定楼层
楼主
这是一个采用实时时钟芯片DS1302和AT89C51单片机的LED时钟,使用C语言编写的程序,可以实现以24小时计时,格式为23-59-59,能够显示和调整年月日和星期,并且能够进行整点报时和设定闹钟。文件内含keil程序源码和proteus仿真电路。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. /*--------------------------------------
  2. Real-Time Clock DS1302 program V9.1
  3. MCU STC89C52RC  XAL 12MHz
  4. --------------------------------------*/
  5. #include <reg51.h>
  6. //
  7. #define uchar unsigned char
  8. #define uint unsigned int
  9. #define ulong unsigned long
  10. sbit BUZZ=P3^7;  
  11. sbit KEY1=P1^0;//调整
  12. sbit KEY2=P1^1;//加1
  13. sbit KEY3=P1^2;//减1
  14. sbit KEY4=P1^3;//显示转换
  15. sbit CE   = P3^2;
  16. sbit SCLK = P3^4;
  17. sbit IO   = P3^3;
  18. uchar hour_reg, minute_reg, second_reg,day_reg,month_reg,year_reg,week_reg,NZ_hour=0,NZ_minute=0;
  19. uint display_flag=0,bs_flag=0,NZ_flag=0;

  20. /***************************************************************************/
  21. /* Prototypes                                                              */
  22. /***************************************************************************/
  23. uchar        rbyte_3w();
  24. void        reset_3w();
  25. void        wbyte_3w(uchar);
  26. void read_time();
  27. void delay(uint);
  28. void display(uchar*);
  29. void time2str(uchar*);
  30. void time_set(void);

  31. /*--------------------------------------
  32.   main function
  33. --------------------------------------*/
  34. void main(void)
  35. {
  36. uchar dispram[32];
  37. uchar s;
  38. uint bs_flag=0;
  39. reset_3w();
  40. wbyte_3w(0x8E);                 //开启寄存器写模式
  41. wbyte_3w(0x00);
  42. reset_3w();
  43. wbyte_3w(0x90);                 //开启涓流充电
  44. wbyte_3w(0xAB);
  45. reset_3w();
  46. wbyte_3w(0x81);
  47. s = rbyte_3w();
  48. reset_3w();
  49. if (s&0x80)
  50.     {
  51.     wbyte_3w(0x80);
  52.     wbyte_3w(s&0x7f);
  53.     reset_3w();
  54.     }
  55. wbyte_3w(0x85);
  56. s = rbyte_3w();
  57. reset_3w();
  58. if (s&0x80)
  59.     {
  60.     wbyte_3w(0x84);
  61.     wbyte_3w(s&0x7f);
  62.     reset_3w();
  63.     }

  64. while (1)
  65.     {         
  66.         if(KEY4==0)
  67.             {
  68.               do {  switch(display_flag)
  69.                         {
  70.                           case 0 : {display(dispram); break;  }
  71.                       case 1 : {display(dispram+8); break; }
  72.                           case 2 : {display(dispram+16); break; }
  73.                       case 3 : {display(dispram+24); break; }
  74.                           default : break;
  75.                                         }
  76.                  }         while (KEY4==0);
  77.               display_flag++;
  78.              }   
  79.     if(display_flag>3) display_flag=0;                           
  80.     read_time();
  81.         if(NZ_flag==1&&hour_reg==NZ_hour&&minute_reg==NZ_minute&&second_reg==0)
  82.           {
  83.                bs_flag=1;   //关整点报时
  84.                    BUZZ=0;
  85.                    delay(2);
  86.                    BUZZ=1;
  87.           }
  88.         if(bs_flag==0&&minute_reg==0&&second_reg==0)  {BUZZ=0;delay(20); BUZZ=1; delay(2);}
  89.     time2str(dispram);   
  90.         switch(display_flag)
  91.             {
  92.                   case 0 : {display(dispram); break;  }
  93.               case 1 : {display(dispram+8); break; }
  94.                   case 2 : {display(dispram+16); break; }
  95.               case 3 : {display(dispram+24); break; }
  96.                   default : break;
  97.               }

  98.     if (KEY1==0) time_set();
  99.         bs_flag=0;
  100.     }
  101. }

  102. /*--------------------------------------
  103.   Time data to display string function
  104.   Parameter:pointer of string
  105. --------------------------------------*/
  106. void time2str(uchar*ch)
  107. {
  108. //时分秒
  109. ch[0]=hour_reg>>4;
  110. ch[1]=hour_reg&0x0f;
  111. ch[2]=16;
  112. ch[3]=minute_reg>>4;
  113. ch[4]=minute_reg&0x0f;
  114. ch[5]=16;
  115. ch[6]=second_reg>>4;
  116. ch[7]=second_reg&0x0f;

  117. //年月日
  118. ch[8]=year_reg>>4;
  119. ch[9]=year_reg&0x0f;
  120. ch[10]=16;
  121. ch[11]=month_reg>>4;
  122. ch[12]=month_reg&0x0f;
  123. ch[13]=16;
  124. ch[14]=day_reg>>4;
  125. ch[15]=day_reg&0x0f;

  126. //星期
  127. ch[16]=16;
  128. ch[17]=16;
  129. ch[18]=16;
  130. ch[19]=16;
  131. ch[20]=16;
  132. ch[21]=16;
  133. ch[22]=16;
  134. ch[23]=week_reg&0x0f;

  135. //闹钟
  136. ch[24]=NZ_hour>>4;
  137. ch[25]=NZ_hour&0x0f;
  138. ch[26]=16;
  139. ch[27]=NZ_minute>>4;
  140. ch[28]=NZ_minute&0x0f;
  141. ch[29]=16;
  142. ch[30]=16;
  143. ch[31]=NZ_flag&0x0f;

  144. }

  145. /*--------------------------------------
  146.   Set time function
  147. --------------------------------------*/
  148. void time_set(void)
  149. {      
  150. uchar ch[32];
  151. uchar i, change_flag=9;
  152. reset_3w();
  153. wbyte_3w(0x80);
  154. wbyte_3w(0x80);
  155. reset_3w();
  156. second_reg=0;
  157. time2str(ch);
  158. bs_flag=1;
  159. do {
  160.     display(ch);
  161.     } while (KEY1==0);
  162. while (change_flag)
  163.   {
  164.     time2str(ch);
  165.         switch (change_flag)  
  166.           {
  167.               case 9: {ch[0]|=0x80;ch[1]|=0x80;break;}           //时
  168.                   case 8: {ch[3]|=0x80;ch[4]|=0x80;break;}           //分
  169.                     case 7: {ch[8]|=0x80;ch[9]|=0x80;break;}           //年
  170.                     case 6: {ch[11]|=0x80;ch[12]|=0x80;break;}   //月
  171.                   case 5: {ch[14]|=0x80;ch[15]|=0x80;break;}   //日
  172.           case 4: {ch[23]|=0x80;break;}                                   //星期
  173.                   case 3: {ch[24]|=0x80;ch[25]|=0x80;break;}   //闹钟时
  174.                   case 2: {ch[27]|=0x80;ch[28]|=0x80;break;}   //闹钟分
  175.                   case 1: {ch[31]|=0x80;break;}                                   //闹钟标志
  176.                   default : break;
  177.           }  
  178.          switch(change_flag)
  179.             {
  180.                   case 9 :                             
  181.               case 8 : {display(ch); break; }
  182.                           case 7 :  
  183.                           case 6 :
  184.                   case 5 : {display(ch+8); break; }
  185.               case 4 : {display(ch+16); break; }
  186.                           case 3 :  
  187.                           case 2 :
  188.                   case 1 : {display(ch+24); break; }
  189.                   default : break;
  190.               }
  191.          if (KEY1==0)          //按键按下
  192.         {
  193.         change_flag--;
  194.         do {
  195.             switch(change_flag)
  196.                    {
  197.                       case 9 :                             
  198.                   case 8 : {display(ch); break; }
  199.                               case 7 :  
  200.                               case 6 :
  201.                       case 5 : {display(ch+8); break; }
  202.                   case 4 : {display(ch+16); break; }
  203.                               case 3 :  
  204.                               case 2 :
  205.                       case 1 : {display(ch+24); break; }
  206.                      default : break;
  207.                      }
  208.            } while (KEY1==0);
  209.         }
  210. /*-----------------------------
  211.          加1功能
  212. ----------------------------*/
  213.           if(KEY2==0)
  214.              {
  215.                      switch (change_flag)  
  216.                       {
  217.                           case 9:
  218.                                              {
  219.                                                    hour_reg++;
  220.                                                    if ((hour_reg&0x0f)>9) hour_reg=(hour_reg&0xf0)+0x10;
  221.                                                    if (hour_reg>0x23) hour_reg=0;
  222.                                                    break;
  223.                                                  }
  224.                               case 8:
  225.                                              {
  226.                                                    minute_reg++;
  227.                            if ((minute_reg&0x0f)>9) minute_reg=(minute_reg&0xf0)+0x10;
  228.                            if (minute_reg>0x59) minute_reg=0;
  229.                                                    break;
  230.                                                  }
  231.                                 case 7:
  232.                                              {
  233.                                                    year_reg++;
  234.                            if ((year_reg&0x0f)>9) year_reg=(year_reg&0xf0)+0x10;
  235.                            if (year_reg>0x99) year_reg=0;
  236.                                                    break;
  237.                                                  }
  238.                                 case 6:
  239.                                              {
  240.                                                    month_reg++;
  241.                            if ((month_reg&0x0f)>9) month_reg=(month_reg&0xf0)+0x10;
  242.                            if (month_reg>0x12) month_reg=0;
  243.                                                    break;
  244.                                                  }
  245.                               case 5:
  246.                                              {
  247.                                                    day_reg++;
  248.                            if ((day_reg&0x0f)>9) day_reg=(day_reg&0xf0)+0x10;
  249.                            if (day_reg>0x31) day_reg=0;
  250.                                                    break;
  251.                                                  }
  252.                       case 4:
  253.                                              {
  254.                                                week_reg++;
  255.                            if (week_reg>0x07) week_reg=1;
  256.                                                    break;
  257.                                              }
  258.                                          case 3:
  259.                                              {
  260.                                                    NZ_hour++;
  261.                                                    if ((NZ_hour&0x0f)>9) NZ_hour=(NZ_hour&0xf0)+0x10;
  262.                                                    if (NZ_hour>0x23) NZ_hour=0;
  263.                                                    break;
  264.                                                  }
  265.                               case 2:
  266.                                              {
  267.                                                    NZ_minute++;
  268.                            if ((NZ_minute&0x0f)>9) NZ_minute=(NZ_minute&0xf0)+0x10;
  269.                            if (NZ_minute>0x59) NZ_minute=0;
  270.                                                    break;
  271.                                                  }
  272.                                           case 1:
  273.                                              {
  274.                                                    NZ_flag++;
  275.                            if (NZ_flag>1) NZ_flag=0;
  276.                                                    break;
  277.                                                  }
  278.                               default : break;
  279.                       }  
  280.                 for (i=0;i<50;i++)                  
  281.                     switch(change_flag)
  282.                    {
  283.                   case 9 :                             
  284.               case 8 : {display(ch); break; }
  285.                           case 7 :  
  286.                           case 6 :
  287.                   case 5 : {display(ch+8); break; }
  288.               case 4 : {display(ch+16); break; }
  289.                           case 3 :  
  290.                           case 2 :
  291.                   case 1 : {display(ch+24); break; }
  292.                   default : break;
  293.                     }   
  294.                  
  295.                  }
  296. /*---------------------------------------------------
  297.          减1功能
  298. -----------------------------------------------------*/
  299.           if(KEY3==0)
  300.              {
  301.                      switch (change_flag)  
  302.                       {
  303.                           case 9:
  304.                                              {
  305.                                                    hour_reg--;
  306.                                                    if ((hour_reg&0x0f)==0x0f) hour_reg=hour_reg&0xf9;
  307.                                                    if (hour_reg==0xf9) hour_reg=0x23;
  308.                                                    break;
  309.                                                  }
  310.                               case 8:
  311.                                              {
  312.                                                    minute_reg--;
  313.                            if ((minute_reg&0x0f)==0x0f) minute_reg=minute_reg&0xf9;
  314.                            if (minute_reg==0xf9) minute_reg=0x59;
  315.                                                    break;
  316.                                                  }
  317.                                 case 7:
  318.                                              {
  319.                                                    year_reg--;
  320.                            if ((year_reg&0x0f)==0x0f) year_reg=year_reg&0xf9;
  321.                            if (year_reg==0xf9) year_reg=0x99;
  322.                                                    break;
  323.                                                  }
  324.                                 case 6:
  325.                                              {
  326.                                                    month_reg--;
  327.                            if ((month_reg&0x0f)==0x0f) month_reg=month_reg&0xf9;
  328.                            if (month_reg==0xf9) month_reg=0x12;
  329.                                                    break;
  330.                                                  }
  331.                               case 5:
  332.                                              {
  333.                                                    day_reg--;
  334.                            if ((day_reg&0x0f)==0x0f) day_reg=day_reg&0xf9;
  335.                            if (day_reg==0xf9) day_reg=0x31;
  336.                                                    break;
  337.                                                  }
  338.                       case 4:
  339.                                              {
  340.                                                week_reg--;
  341.                            if (week_reg==0x00) week_reg=0x07;
  342.                                                    break;
  343.                                              }
  344.                                          case 3:
  345.                                              {
  346.                                                    NZ_hour--;
  347.                                                    if ((NZ_hour&0x0f)==0x0f) NZ_hour=NZ_hour&0xf9;
  348.                                                    if (NZ_hour==0xf9) NZ_hour=0x23;
  349.                                                    break;
  350.                                                  }
  351.                               case 2:
  352.                                              {
  353.                                                    NZ_minute--;
  354.                            if ((NZ_minute&0x0f)==0x0f) NZ_minute=NZ_minute&0xf9;
  355.                            if (NZ_minute==0xf9) NZ_minute=0x59;
  356.                                                    break;
  357.                                                  }
  358.                                           case 1:
  359.                                              {
  360.                                                    NZ_flag--;
  361.                            if (NZ_flag==0xff) NZ_flag=1;
  362.                                                    break;
  363.                                                  }
  364.                               default : break;
  365.                       }  
  366.                 for (i=0;i<50;i++)                  
  367.                     switch(change_flag)
  368.                    {
  369.                       case 9 :                             
  370.               case 8 : {display(ch); break; }
  371.                           case 7 :  
  372.                           case 6 :
  373.                   case 5 : {display(ch+8); break; }
  374.               case 4 : {display(ch+16); break; }
  375.                           case 3 :  
  376.                           case 2 :
  377.                   case 1 : {display(ch+24); break; }
  378.                   default : break;
  379.                     }   
  380.                  
  381.                  }
  382.   }

  383. /*---------------------------------
  384. 将改好的数据写进1302中
  385. -----------------------------*/
  386. reset_3w();
  387. wbyte_3w(0x8C);
  388. wbyte_3w(year_reg);
  389. reset_3w();
  390. wbyte_3w(0x8A);
  391. wbyte_3w(week_reg);
  392. reset_3w();
  393. wbyte_3w(0x88);
  394. wbyte_3w(month_reg);
  395. reset_3w();
  396. wbyte_3w(0x86);
  397. wbyte_3w(day_reg);
  398. reset_3w();
  399. wbyte_3w(0x84);
  400. wbyte_3w(hour_reg);
  401. reset_3w();
  402. wbyte_3w(0x82);
  403. wbyte_3w(minute_reg);
  404. reset_3w();
  405. wbyte_3w(0x80);
  406. wbyte_3w(second_reg);
  407. reset_3w();

  408. }
  409. /*--------------------------------------
  410.   Delay function
  411.   Parameter: unsigned int dt
  412.   Delay time=dt(ms)
  413. --------------------------------------*/
  414. void delay(unsigned int dt)
  415. {
  416. register unsigned char bt,ct;
  417. for (; dt; dt--)
  418.     for (ct=2;ct;ct--)
  419.         for (bt=248; --bt; );
  420. }

  421. /*--------------------------------------
  422.   8 LED digital tubes display function
  423.   Parameter: sting pointer to display
  424. --------------------------------------*/
  425. void display(uchar*disp_ram)
  426. {
  427. static uchar disp_count;
  428. unsigned char i,j;
  429. unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};
  430. disp_count=(disp_count+1)&0x7f;
  431. for (i=0;i<8;i++)
  432.     {
  433.     j =disp_ram[i];
  434.     if (j&0x80) P0 =(disp_count>32)?table[j&0x7f]:0xff;
  435.         else P0 =table[j];
  436.     P2 =0x01<<i;
  437.     delay(1);
  438.     P0 =0xff;
  439.     P2 =0;
  440.     }
  441. }

  442. /*--------------------------------------
  443.   Read time function
  444. ……………………

  445. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
ds1302时钟.rar (63.96 KB, 下载次数: 113)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:320306 发表于 2019-3-26 00:06 | 只看该作者
感谢楼主无私奉献,看见有11个下载却没人回复,让人心寒!楼主好样的 ,加油!!!!
回复

使用道具 举报

板凳
ID:140183 发表于 2019-3-26 06:59 | 只看该作者
多谢分享!喜欢收集单片机程序,平时没事做时打开看看.
回复

使用道具 举报

地板
ID:608007 发表于 2019-11-1 18:46 | 只看该作者
数码管亮度不够怎么回事  请楼主
回复

使用道具 举报

5#
ID:258520 发表于 2019-12-8 23:14 | 只看该作者
数码管亮度不够怎么解决呢 楼主
回复

使用道具 举报

6#
ID:657553 发表于 2019-12-11 08:48 | 只看该作者
很好 谢谢楼主
回复

使用道具 举报

7#
ID:668725 发表于 2019-12-20 15:34 | 只看该作者
蜂鸣器闹钟不响
回复

使用道具 举报

8#
ID:694728 发表于 2020-2-25 07:13 | 只看该作者
多谢分享!学习了
回复

使用道具 举报

9#
ID:315554 发表于 2020-3-2 17:02 | 只看该作者
谢谢楼主分享,我来试试,
回复

使用道具 举报

10#
ID:746591 发表于 2020-5-12 12:22 | 只看该作者
这个下载机制也太奇葩了吧,还没下就扣了我黑币,再点一次居然又要重新扣了?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表