找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10858|回复: 30
收起左侧

基于DS1302的电子时钟制作

  [复制链接]
ID:115394 发表于 2016-12-4 18:12 | 显示全部楼层 |阅读模式
QQ截图20161204180939.png QQ截图20161204180952.png
资料下载:
大时钟【原理图】.PDF (119.6 KB, 下载次数: 89)

评分

参与人数 2黑币 +58 收起 理由
slhslhhao + 8 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:104838 发表于 2016-12-5 21:21 | 显示全部楼层
支持下需要,51黑有你更精彩!!!
回复

使用道具 举报

ID:153199 发表于 2017-1-2 13:57 | 显示全部楼层
51黑有你更精彩
回复

使用道具 举报

ID:159748 发表于 2017-1-16 23:59 | 显示全部楼层
下載玩玩感謝你...
回复

使用道具 举报

ID:161488 发表于 2017-1-17 10:42 | 显示全部楼层
好东西,可以做一做,有没有原件和封装库
回复

使用道具 举报

ID:161822 发表于 2017-1-17 13:16 | 显示全部楼层

不错,收下了,谢谢!
回复

使用道具 举报

ID:89286 发表于 2017-1-18 22:47 | 显示全部楼层
thanks for sharing
回复

使用道具 举报

ID:151661 发表于 2017-1-20 23:47 来自手机 | 显示全部楼层
很厉害。
回复

使用道具 举报

ID:162689 发表于 2017-1-22 10:46 | 显示全部楼层
六位更好。。。。
回复

使用道具 举报

ID:143822 发表于 2017-1-27 16:48 | 显示全部楼层
为啥重影
回复

使用道具 举报

ID:158729 发表于 2017-1-28 19:57 | 显示全部楼层
楼主厉害,感谢分享
回复

使用道具 举报

ID:143822 发表于 2017-1-29 13:53 来自手机 | 显示全部楼层
第三段,h一直在闪是怎么回事
回复

使用道具 举报

ID:143822 发表于 2017-1-30 06:44 来自手机 | 显示全部楼层
if((n==2||n==4)&&a<5)         smg_data=0xff;//b是控制小数点闪烁的,需要闪烁的时候他等于a    else if(b>=10)                        smg_data=tab1[f/10]; //显示小点//送显示断码    else                                                smg_data=tab1[f/10];//送显示断码         分    smg3=0;//锁存数据    delay_50us(gm_time);    smg3=1;  
回复

使用道具 举报

ID:141497 发表于 2017-2-1 22:31 | 显示全部楼层
学习一下,看看你的编程思路
回复

使用道具 举报

ID:148496 发表于 2017-3-4 19:40 | 显示全部楼层
开玩笑 stc89C51 能装下11k的程序:?
回复

使用道具 举报

ID:166064 发表于 2017-3-28 20:31 | 显示全部楼层
谢谢分享,正在好一个。
回复

使用道具 举报

ID:258542 发表于 2017-12-7 11:15 | 显示全部楼层
学习了  最近在也正好在仿照这个
回复

使用道具 举报

ID:99341 发表于 2017-12-9 16:34 | 显示全部楼层
楼主这个程序有问题,能不能重新发个能用的烧写文件
回复

使用道具 举报

ID:168148 发表于 2017-12-27 18:58 来自手机 | 显示全部楼层
学习学习!!
回复

使用道具 举报

ID:261637 发表于 2018-1-6 00:49 | 显示全部楼层
编译不过?RAMSIZE(256)
*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?BAOJING?DSZ
    CALLER1: ?C_C51STARTUP
    CALLER2: ?PR?TIMER0?DSZ
*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?_DISPLAY?DSZ
    CALLER1: ?C_C51STARTUP
    CALLER2: ?PR?TIMER0?DSZ
******************************************************************************
* RESTRICTED VERSION WITH 0800H BYTE CODE SIZE LIMIT; USED: 0B63H BYTE (142%) *
******************************************************************************
Program Size: data=100.3 xdata=0 code=3805
LINK/LOCATE RUN COMPLETE.  2 WARNING(S),  0 ERROR(S)
*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?BAOJING?DSZ
    CALLER1: ?C_C51STARTUP
    CALLER2: ?PR?TIMER0?DSZ
*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?_DISPLAY?DSZ
    CALLER1: ?C_C51STARTUP
    CALLER2: ?PR?TIMER0?DSZ
*** FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED
    MODULE:  C:\KEIL\C51\LIB\C51S.LIB (-----)
    LIMIT:   0800H BYTES
Target not created
回复

使用道具 举报

ID:270854 发表于 2018-1-7 15:05 | 显示全部楼层
闹铃不会响
回复

使用道具 举报

ID:270854 发表于 2018-1-7 16:02 | 显示全部楼层
每次断电重启闹钟时间就恢复初始值了,
回复

使用道具 举报

ID:261637 发表于 2018-1-13 23:48 | 显示全部楼层
分的十位g段一直闪,秋楼主解惑。。谢谢
回复

使用道具 举报

ID:231936 发表于 2018-6-21 16:33 | 显示全部楼层
我修改一下,在Professional试过能用。
/*        项目名称:多功能数码管时钟设计
        调试要求:
        1.MCU:STC89C51
        2.晶振:12MHz
        功能:实时时钟+温度计+闹钟+整点报时+正计时器+倒计时器+计数器*/
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define smg_data    P0//定义数码管数据

  6. sbit smg1=P2^4;//位码1声明 时
  7. sbit smg2=P2^5;//位码2声明
  8. sbit smg3=P2^6;//位码3声明 分
  9. sbit smg4=P2^7;//位码4声明
  10. sbit smg5=P1^6;//位码5声明 秒
  11. sbit smg6=P1^7;//位码6声明
  12. sbit gm=P1^3; //黑暗时等于1
  13. sbit k1=P1^2; //按键k1的声明
  14. sbit k2=P1^1; //按键k2的声明
  15. sbit k3=P1^0; //按键k3的声明

  16. sbit bell=P3^7;        //蜂鸣器声明
  17. sbit clk_ds1302=P2^0;//定义控制DS1302的时钟线
  18. sbit io_ds1302=P2^1;//定义控制DS1302的串行数据
  19. sbit rest_ds1302=P2^2;

  20. const uchar tab1[16]={//共阳数码管段码表
  21. 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x86,0x87,0xFF,0xc6,0xbf,0xff};
  22. //0        ,1        ,2        ,3        ,4        ,5        ,6        ,7        ,8        ,9        ,                       
  23. const uchar tab2[16]={//数码管3特殊处理用的段码表
  24. 0xc0,0xf9,0x64,0x70,0x59,0x52,0x42,0xf8,0x40,0x50,0x86,0x87,0xFF,0xc6,0x7f,0xff};
  25.                         //    C      -
  26. bit gm_en=0,zdbs_en=0;//光敏使能信号/整点报时使能信号
  27. uchar gm_time=40; //光敏控制亮度值
  28. char shi,fen,miao,b_shi=7,b_fen=0; //必须是有符号型:数据暂存单元shi/fen/miao,闹铃时间b_shi,b_fen,
  29. uchar hour,minute,second,n=0,a=0,b=0;//从1302读出的实时时间数据hour,minute,second,        b控制字符闪烁
  30. uchar tab23[3];//={0x40,0x59,0x23,0x28,0x11,0x06,0x09};//首次上电时默认的时间
  31. uchar bell_en=0,x=1;//闹钟使能信号,任意键关闭铃声标志位
  32. char zjs_en=0,zjs_shi=0,zjs_fen=0,djs_en=0,djs_shi=60,djs_fen=0,jsq_shi=0,jsq_fen=0;
  33. void key();
  34. void  delay_3us();//3US的延时程序
  35. void  delay_50us(uint t);//延时50*T微妙函数的声明
  36. void  display(uchar shi,fen,miao);//显示子程序
  37. void  set_ds1302();//设置时间
  38. void  get_ds1302();//读取当前时间
  39. void  w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据
  40. uchar r_1byte_ds1302();//从DS1302读一个字节的数据
  41. void init(); //初始化函数

  42. void baojing()//报警函数
  43. {
  44.          uint j=10,i=10;
  45.          bell=0;
  46.          while(i--)display(shi,fen,miao);
  47.          bell=1;
  48.          while(j--)display(shi,fen,miao);
  49. }

  50. /******温度传感器18b20  IO引脚定义********/
  51. sbit DS=P2^3;           //定义DS18B20接口
  52. uchar ly_dis[4];                //定义显示温度的缓冲区
  53. float tt;                        //定义浮点型变量tt存放温度值
  54. uchar temp_en=0;
  55. uchar wendu=0;
  56. uint t=0;

  57. /**********18b20延时子函数 *************/
  58. void delayb(uint count)
  59. {
  60.   uint i;
  61.   while(count)
  62.   {
  63.     i=200;
  64.     while(i>0)
  65.     i--;
  66.     count--;
  67.   }
  68. }

  69. /*********DS18B20初始化************/
  70. void dsreset(void)
  71. {
  72.   uint i;
  73.   DS=0;
  74.   i=103;
  75.   while(i>0)i--;
  76.   DS=1;
  77.   i=4;
  78.   while(i>0)i--;
  79. }

  80. /**********18b20读一位***********/
  81. bit tmpreadbit(void)
  82. {
  83.    uint i;
  84.    bit dat;
  85.    DS=0;
  86.    i++;          //小延时一下
  87.    DS=1;
  88.    i++;i++;
  89.    dat=DS;
  90.    i=8;
  91.    while(i>0)i--;
  92.    return (dat);
  93. }

  94. /**********18b20读一个**********/
  95. uchar tmpread(void)
  96. {
  97.   uchar i,j,dat;
  98.   dat=0;
  99.   for(i=1;i<=8;i++)
  100.   {
  101.     j=tmpreadbit();
  102.     dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好//一个字节在DAT里
  103.   }
  104.   return(dat);             //将一个字节数据返回
  105. }

  106. /**********18b20写一个字节**********/
  107. void tmpwritebyte(uchar dat)
  108. {
  109.   uint i;
  110.   uchar j;
  111.   bit testb;
  112.   for(j=1;j<=8;j++)
  113.   {
  114.     testb=dat&0x01;
  115.     dat=dat>>1;
  116.     if(testb)     // 写1部分
  117.     {
  118.       DS=0;
  119.       i++;i++;
  120.       DS=1;
  121.       i=8;
  122.           while(i>0)i--;
  123.     }
  124.     else
  125.     {
  126.       DS=0;       //写0部分
  127.       i=8;
  128.           while(i>0)i--;
  129.       DS=1;
  130.       i++;i++;
  131.     }
  132.   }
  133. }

  134. /***********18b20发送温度转换命令*************/
  135. void tmpchange(void)
  136. {
  137.   dsreset();             //初始化DS18B20
  138.   delayb(1);             //延时
  139.   tmpwritebyte(0xcc);  // 跳过序列号命令
  140.   tmpwritebyte(0x44);  //发送温度转换命令
  141. }

  142. /***********获得温度************/
  143. int tmp()
  144. {
  145.   int temp;
  146.   uchar a,b;
  147.   dsreset();
  148.   delayb(1);

  149.   tmpwritebyte(0xcc);  
  150.   tmpwritebyte(0xbe);   //发送读取数据命令

  151.   a=tmpread();          //连续读两个字节数据
  152.   b=tmpread();
  153.   temp=b;
  154.   temp<<=8;
  155.   temp=temp|a;                 //两字节合成一个整型变量。
  156.   return temp;     //返回温度值
  157. }
  158. void dis_temp()
  159. {        
  160.         tmpchange();              //温度转换
  161.         tt=tmp()*0.0625;          //得到真实十进制温度值,因为DS18B20
  162.         wendu=tt;                                                                //可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度。
  163.         if(tt<0)        //判断第一位显示整数还是负号
  164.         tt=0;        
  165.         if((wendu%100/10)<1) //如果温度小于10,不显示十位
  166.         smg1=1;
  167.         else
  168.         {
  169.                 smg_data=tab1[wendu%100/10];//送显示断码  十位
  170.                 smg1=0;
  171.                 delay_50us(gm_time);
  172.                 smg1=1;
  173.         }
  174.         smg_data=tab1[wendu%10];//送显示断码  个位
  175.         smg2=0;
  176.         delay_50us(gm_time);
  177.         smg2=1;
  178.         smg_data=tab1[13];//送显示断码  ℃
  179.         smg3=0;
  180.         delay_50us(gm_time);
  181.         smg3=1;        
  182.         smg4=1;
  183. }
  184. //***********************************************************************
  185. //主程序
  186. void main()
  187. {        
  188.         tmpchange();              //温度转换,为了消除首次显示的85,每次提前转换一次即可解决
  189.     init();
  190.         gm=1;
  191.         while(1)
  192.     {        
  193.                 if(n==0&&temp_en==1)
  194.                 dis_temp();//每15秒切换显示温度一次
  195.                 else
  196.                 {
  197.                         get_ds1302();
  198.                         display(shi,fen,miao);
  199.                         key();
  200.                         if(n==0&&x==1&&bell_en==1&&b_shi==hour&&b_fen==minute)
  201.                         baojing();
  202.                         if(hour==b_shi&&minute==b_fen+1)x=1;
  203.                 }
  204.                 if(gm_en==1)//光敏控制亮度开关
  205.                 {
  206.                         if(gm==1)
  207.                         gm_time=1;
  208.                         else gm_time=40;
  209.                 }
  210.                 else gm_time=40;
  211.                 if(zdbs_en==1&&n==0&&minute==0&&miao==0)//整点报时开关
  212.                 baojing();                                                                 
  213.     }
  214. }

  215. //数码管显示程序
  216. void  display(uchar s,f,m)
  217. {
  218.    if((s/10)<1) smg1=1;
  219.    else
  220.    {
  221.            smg_data=tab1[s/10];//送显示断码  时
  222.            if((n==1||n==3)&&a<5)
  223.            smg1=1;//锁存数据
  224.            else smg1=0;
  225.            delay_50us(gm_time);
  226.            smg1=1;        
  227.    }

  228.    if((n==1||n==3)&&a<5)        smg_data=0x7f; //字符闪烁,小点不闪
  229.    else if(b>=10)                        smg_data=tab1[s%10]-0x80;//小点闪烁,字符不闪
  230.    else                                         smg_data=tab1[s%10];//送显示断码
  231.    smg2=0;
  232.    delay_50us(gm_time);
  233.    smg2=1;

  234.    if((n==2||n==4)&&a<5)         smg_data=0xbf;//b是控制小数点闪烁的,需要闪烁的时候他等于a
  235.    else if(b>=10)                        smg_data=tab1[f/10]; //显示小点//送显示断码
  236.    else                                       smg_data=tab1[f/10];//送显示断码         分
  237.    smg3=0;//锁存数据
  238.    delay_50us(gm_time);
  239.    smg3=1;         

  240.    if(bell_en==1)         smg_data=tab1[f%10]-0x80;//送显示断码
  241.    else                         smg_data=tab1[f%10];//送显示断码
  242.    if((n==2||n==4)&&a<5)
  243.    smg4=1;//锁存数据
  244.    else smg4=0;
  245.    delay_50us(gm_time);
  246.    smg4=1;
  247. /**************秒,不需要显示********************/   
  248.    smg_data=tab2[m/10];//送显示断码   秒
  249.    smg5=0;//锁存数据
  250.    delay_50us(40);
  251.    smg5=1;

  252.    smg_data=tab1[m%10];//送显示断码
  253.    smg6=0;//锁存数据
  254.    delay_50us(40);
  255.    smg6=1;
  256. /*********************************************/

  257. }
  258. void key() //按键控制函数
  259. {
  260.         if(k2==0&&k3==0) //k2k3同时按下,切换闹铃开关 并且在按下之后查看闹钟时间松手后恢复时间显示
  261.         {
  262.                 delay_50us(1);
  263.                 if(k2==0&&k3==0)
  264.                 {        
  265.                         shi=b_shi;
  266.                         fen=b_fen;
  267.                         bell_en=!bell_en;
  268.                         baojing();
  269.                         baojing();
  270.                         while(k2==0&&k3==0)display(shi,fen,miao);//等待松手
  271.                         shi=hour;
  272.                         fen=minute;
  273.                 }
  274.         }
  275.         
  276.         if(k1==0&&k3==0) //k1k3同时按下,切换闹铃开关 并且在按下之后查看闹钟时间松手后恢复时间显示
  277.         {
  278.                 delay_50us(1);
  279.                 if(k1==0&&k3==0)
  280.                 {        
  281.                         gm_en=!gm_en;
  282.                         if(gm_en==1)//使能的话报警两声
  283.                         {baojing();baojing();}
  284.                         else baojing();//无效的话报警一声
  285.                         while(k1==0&&k3==0)display(shi,fen,miao);//等待松手
  286.                 }
  287.         }
  288.         if(k1==0&&k2==0) //k1k2同时按下,切换整点报时开关
  289.         {
  290.                 delay_50us(1);
  291.                 if(k1==0&&k2==0)
  292.                 {        
  293.                         zdbs_en=!zdbs_en;
  294.                         if(zdbs_en==1)//使能的话报警两声
  295.                         {baojing();baojing();}
  296.                         else baojing();//无效的话报警一声        
  297.                         while(k1==0&&k2==0)display(shi,fen,miao);//等待松手
  298.                 }
  299.         }
  300.         if(n==0&&(k2==0||k3==0)&&bell_en==1&&b_shi==hour&&b_fen==minute&&x==1)
  301.         { //功能键k1被按下
  302.                 delay_50us(1);//消抖延时
  303.                 if(n==0&&(k2==0||k3==0)&&bell_en==1&&b_shi==hour&&b_fen==minute&&x==1)
  304.                 {        
  305.                         x=0;   //如果处于响零状态,就任意键关闭响铃
  306.                         while(k1==0)display(shi,fen,miao);//等待松手
  307.                 }
  308.         }
  309.         if(k1==0)
  310.         { //功能键k1被按下
  311.                 delay_50us(1);//消抖延时
  312.                 if(k1==0)
  313.                 {        
  314.                         uint i=0;
  315.                         while(k1==0)
  316.                         {
  317.                                 display(shi,fen,miao);//等待松手
  318.                                 i++;
  319.                                 if(i>(2*(70-gm_time))){n=0;baojing();baojing();break;}//长按K1退出
  320.                         }
  321.                         if(bell_en==1&&b_shi==hour&&b_fen==minute&&x==1)x=0;   //如果处于响零状态,就任意键关闭响铃
  322.                         else if(i<=(2*(70-gm_time)))
  323.                         {
  324.                                 n++;//n记录功能键状态
  325.                                 if(n>7)  n=0; //n清零
  326.                                 baojing();        
  327.                         }
  328.                         i=0;                        
  329.                 }
  330.         }

  331.         if(n==0)//状态0,正常显示时间
  332.         {
  333.                 b=a; //b是控制小数点闪烁的
  334.                 shi=hour;
  335.                 fen=minute;
  336.                 miao=second;
  337.         }        
  338.         if(n==1)//状态1:调节时间的“时”
  339.         {
  340.                 b=10;
  341.                 if(k2==0)
  342.                 { //k2被按下
  343.                         uint i=6,j=10;
  344.                         while(i--)display(shi,fen,miao);//长按连续递减                        
  345.                         if(k2==0)
  346.                         {
  347.                                 shi++;//小时加一
  348.                                 if(shi==24)
  349.                                 shi=0;//达到24清零        
  350.                         }
  351.                          while(j--)display(shi,fen,miao);//长按连续递减
  352.                 }
  353.                
  354.                 if(k3==0)
  355.                 {  //k3被按下
  356.                         uint i=6,j=10;
  357.                         while(i--)display(shi,fen,miao);//长按连续递减        
  358.                         if(k3==0)
  359.                         {
  360.                                 shi--; //小时减一
  361.                                 if(shi<0)
  362.                                 shi=23;//小于0,重新复制
  363.                         }
  364.                         while(j--)display(shi,fen,miao);//长按连续递减
  365.                 }               
  366.         }
  367.         if(n==2)//状态2:调节时间的“分”
  368.         {        b=10;
  369.                  if(k2==0)
  370.                 { //k2被按下
  371.                         uint i=6,j=10;
  372.                         while(i--)display(shi,fen,miao);//长按连续递减
  373.                         if(k2==0)
  374.                         {
  375.                                 fen++;//分加一
  376.                                 if(fen==60)
  377.                                 fen=0;//分到达60 分清零        
  378.                         }        
  379.                         while(j--)display(shi,fen,miao);//长按连续递减
  380.                 }
  381.                
  382.                 if(k3==0)
  383.                 {  //k3被按下
  384.                         uint i=6,j=10;
  385.                         while(i--)display(shi,fen,miao);//长按连续递减
  386.                         if(k3==0)
  387.                         {
  388.                                 fen--;//分减一
  389.                                 if(fen<0)
  390.                                 fen=59;//分小于0,分重新赋值59                                          
  391.                         }
  392.                         while(j--)display(shi,fen,miao);//长按连续递减
  393.                 }
  394.                 tab23[2]=shi/10*16+shi%10;
  395.         tab23[1]=fen/10*16+fen%10;
  396.         hour=shi;
  397.         minute=fen;
  398.         second=0;
  399.         tab23[0]=0;
  400.         set_ds1302();//设置DS1302的初始时间               
  401.         }
  402.         
  403.         if(n==3)//状态三:调节闹铃“时”
  404.         {        
  405.                 shi=b_shi;
  406.                 fen=b_fen;
  407.                 b=10;
  408.                 if(k2==0)
  409.                 {  //k2被按下
  410.                         uint i=6,j=10;
  411.                         while(i--)display(shi,fen,miao);//长按连续递减
  412.                         if(k2==0)
  413.                         {
  414.                                 b_shi++;//闹铃时间加一
  415.                                 if(b_shi==24)
  416.                                 b_shi=0;//闹铃时间清零        
  417.                         }
  418.                         while(j--)display(shi,fen,miao);//长按连续递减
  419.                 }
  420.                
  421.                 if(k3==0)
  422.                 {  //k3被按下
  423.                         uint i=6,j=10;
  424.                         while(i--)display(shi,fen,miao);//长按连续递减
  425.                         if(k3==0)
  426.                         {
  427.                                 b_shi--;//闹铃时间减一
  428.                                 if(b_shi<0)
  429.                                 b_shi=23;//闹铃时间        
  430.                         }
  431.                         while(j--)display(shi,fen,miao);//长按连续递减
  432.                 }               
  433.         }

  434.         if(n==4)//状态四 :调节闹铃的”分“
  435.         {        b=10;
  436.         shi=b_shi;
  437.                 fen=b_fen;
  438.                 if(k2==0)
  439.                 {  //k2被按下
  440.                         uint i=6,j=10;
  441.                         while(i--)display(shi,fen,miao);//长按连续递减
  442.                         if(k2==0)
  443.                         {
  444.                                 b_fen++;//闹铃时间分加一
  445.                                 if(b_fen==60)
  446.                                 b_fen=0;//闹铃分到达60 清零        
  447.                         }        
  448.                         while(j--)display(shi,fen,miao);//长按连续递减
  449.                 }
  450.                
  451.                 if(k3==0)
  452.                 {  //k3被按下
  453.                         uint i=6,j=10;
  454.                         while(i--)display(shi,fen,miao);//长按连续递减
  455.                         if(k3==0)
  456.                         {
  457.                                 b_fen--;//闹铃时间分减一
  458.                                 if(b_fen<0)
  459.                                 b_fen=59;//闹铃时间分重新赋值
  460.                         }
  461.                         while(j--)display(shi,fen,miao);//长按连续递减                        
  462.                 }               
  463.         }
  464.         if(n==5)//状态5 :正计时
  465.         {
  466.                 b=10; //显示小点
  467.                 shi=zjs_shi;
  468.                 fen=zjs_fen;
  469.                 if(k2==0)
  470.                 {  //k2被按下
  471.                         delay_50us(1);//消抖延时
  472.                         if(k2==0)
  473.                         {        
  474.                                 zjs_en=!zjs_en;        
  475.                                 baojing();
  476.                                 while(k2==0)display(shi,fen,miao);//等待松手
  477.                         }
  478.                 }
  479.                
  480.                 if(k3==0)
  481.                 {  //k3被按下
  482.                         delay_50us(1);//消抖延时
  483.                         if(k3==0)
  484.                         {
  485.                                 zjs_shi=0;
  486.                                 zjs_fen=0;
  487.                                 baojing();
  488.                                 while(k3==0)display(shi,fen,miao);//等待松手        
  489.                         }
  490.                 }               
  491.         }
  492.         if(n==6)//状态5 :倒计时
  493.         {        b=10; //显示小点
  494.         shi=djs_shi;
  495.                 fen=djs_fen;
  496.                 if(k2==0)
  497.                 {  //k2被按下
  498.                         delay_50us(1);//消抖延时
  499.                         if(k2==0)
  500.                         {        
  501.                                 djs_en=!djs_en;        
  502.                                 baojing();
  503.                                 while(k2==0)display(shi,fen,miao);//等待松手
  504.                         }
  505.                 }
  506.                
  507.                 if(k3==0&&djs_en==0)
  508.                 {  //k3被按下
  509.                         uint i=6,j=10;
  510.                         while(i--)display(shi,fen,miao);//长按连续递减
  511.                         if(k3==0)
  512.                         {
  513.                                 djs_shi--;
  514.                                 if(djs_shi<0)
  515.                                 djs_shi=60;               
  516.                         }
  517.                         while(j--)display(shi,fen,miao);//长按连续递减
  518.                 }
  519.                 if(k3==0&&djs_en==1)
  520.                 {  //k3被按下
  521.                         delay_50us(1);//消抖延时
  522.                         if(k3==0)
  523.                         {
  524.                                 djs_shi=60;
  525.                                 djs_fen=0;
  526.                                 baojing();
  527.                                 while(k3==0)display(shi,fen,miao);//等待松手        
  528.                         }
  529.                 }               
  530.         }
  531.         if(n==7)//状态5 :计数器
  532.         {        
  533.                 b=1; //不显示小点
  534.                 shi=jsq_shi;
  535.                 fen=jsq_fen;
  536.         
  537.                 if(k2==0)
  538.                 {  
  539.                         uint i=6,j=10;
  540.                         while(i--)display(shi,fen,miao);//长按连续递减
  541.                         if(k2==0)
  542.                         {
  543.                                 jsq_fen++;
  544.                                 if(jsq_fen>99)
  545.                                 {
  546.                                         jsq_fen=0;
  547.                                         jsq_shi++;
  548.                                         if(jsq_shi>99)
  549.                                         jsq_shi=0;
  550.                                 }                        
  551.                         }
  552.                         while(j--)display(shi,fen,miao);//长按连续递减
  553.                 }
  554.                 if(k3==0)
  555.                 {  //k3被按下
  556.                         delay_50us(1);//消抖延时
  557.                         if(k3==0)
  558.                         {
  559.                                 jsq_shi=0;
  560.                                 jsq_fen=0;
  561.                                 baojing();
  562.                                 while(k3==0)display(shi,fen,miao);//等待松手        
  563.                         }
  564.                 }               
  565.         }                        
  566. }
  567. void init()        //初始化函数
  568. {
  569.         IE=0X82;//1000 0010
  570.         TMOD=0X01;    //0000 0001选择定时器0的工作方式1        选择定时器1的工作方式1
  571.         TH0=(65536-50000)/256;//初值15536定时50mS
  572.         TL0=(65536-50000)%256;
  573.         TR0=1; //开启定时器0
  574. }

  575. void timer0() interrupt        1  //定时器0中断服务程序,用来设置冒号闪烁频率
  576. {
  577.         TH0=(65536-50000)/256;//进入中断重新赋初值15536
  578.         TL0=(65536-50000)%256;//计数5万次(50毫秒)
  579.         a++; //标志位b,用来确定光标闪烁频率
  580.         t++;
  581.         if(t==300)t=0;
  582.         if(t>260)temp_en=1;
  583.         else temp_en=0;
  584.         
  585.         if(a==20)
  586.         {        
  587.                 a=0;//a=20 时被清零        
  588.                 if(zjs_en==1)        //正计时
  589.                 {
  590.                         zjs_fen++;
  591.                         if(zjs_fen==60)
  592.                         {
  593.                                 zjs_fen=0;
  594.                                 zjs_shi++;
  595.                                 if(zjs_shi==60)
  596.                                 {
  597.                                         zjs_shi=0;        
  598.                                 }
  599.                         }        
  600.                 }
  601.                 /**********倒计时**********/
  602.                 if(djs_en==1)
  603.                 {
  604.                         djs_fen--;
  605.                         if(djs_fen==-1)
  606.                         {
  607.                                 djs_fen=59;
  608.                                 djs_shi--;
  609.                                 if(djs_shi==-1)
  610.                                 {
  611.                                         djs_shi=0;
  612.                                         djs_fen=0;
  613.                                         djs_en=0;//关闭倒计时
  614.                                         baojing();
  615.                                 baojing();
  616.                                 baojing();
  617.                                 }
  618.                         }        
  619.                 }
  620.                 /*************************/
  621.         }
  622. }


  623. //函数名称:void delay_50US(unsigned int t)
  624. //功能: 延时50*t(us)
  625. void delay_50us(uint t)
  626. {
  627.   unsigned char j;
  628.   for(;t>0;t--)
  629.   {
  630.     for(j=19;j>0;j--);
  631.   }
  632. }
  633. //*******************************************************************************

  634. //*******************************************************************************
  635. //3微秒延时程序
  636. void delay_3us()
  637. {
  638.   ;
  639.   ;
  640. }


  641. //;##############################################################################
  642. //;子程序名:w_1byte_ds1302
  643. //;功能:    向DS1302写一个字节的数据
  644. void w_1byte_ds1302(uchar t)
  645. {
  646.   uchar i;
  647.   for(i=0;i<8;i++)
  648.   {
  649.     if(t & 0x01)
  650.      {io_ds1302=1;}
  651.     else
  652.      {io_ds1302=0;}
  653.     clk_ds1302=1;
  654.     delay_3us();
  655.     delay_3us();
  656.     clk_ds1302=0;
  657.     delay_3us();
  658.     delay_3us();
  659.     t>>=1;
  660.   }  
  661. }
  662. //;########################################################################
  663. //;子程序名:r_1byte_ds1302()
  664. //;功能:    从DS1302读一个字节的数据
  665. uchar r_1byte_ds1302()
  666. {
  667.   uchar i,temp11=0;
  668.   io_ds1302=1;//置IO为1,准备读入数据
  669.   for(i=0;i<8;i++)
  670.   {
  671.     temp11>>=1;
  672.     if(io_ds1302) temp11 |= 0x80;
  673.     clk_ds1302=1;
  674.     delay_3us();
  675.     delay_3us();
  676.     clk_ds1302=0;
  677.     delay_3us();
  678.   }
  679.   return(temp11);
  680. }  
  681. //;#################################################################################
  682. //;子程序名:setbds1302
  683. //;功能:   设置DS1302初始时间,并启动计时
  684. void set_ds1302()
  685. {
  686.   uchar i,j;
  687.   rest_ds1302=0;
  688.   delay_3us();
  689.   clk_ds1302=0;
  690.   delay_3us();
  691.   rest_ds1302=1;
  692.   delay_3us();
  693.   w_1byte_ds1302(0x8e);//写控制命令字
  694.   delay_3us();
  695.   w_1byte_ds1302(0x00);//写保护关闭
  696.   clk_ds1302=1;
  697.   delay_3us();
  698.   rest_ds1302=0;
  699.   for(i=0,j=0x80;i<7;i++,j+=2)
  700.   {
  701.     rest_ds1302=0;
  702.     delay_3us();
  703.     clk_ds1302=0;
  704.     delay_3us();
  705.     rest_ds1302=1;
  706.     delay_3us();
  707.     w_1byte_ds1302(j);
  708.     delay_3us();
  709.     w_1byte_ds1302(tab23[i]);
  710.     delay_3us();
  711.     delay_3us();
  712.     clk_ds1302=1;
  713.     delay_3us();
  714.     rest_ds1302=0;
  715.     delay_3us();
  716.     delay_3us();
  717.   }
  718.   rest_ds1302=0;
  719.   delay_3us();
  720.   clk_ds1302=0;
  721.   delay_3us();
  722.   rest_ds1302=1;
  723.   delay_3us();
  724.   w_1byte_ds1302(0x8e);
  725.   delay_3us();
  726.   w_1byte_ds1302(0x80);
  727.   clk_ds1302=1;
  728.   delay_3us();
  729.   rest_ds1302=0;
  730.   delay_3us();
  731. }  
  732. //;#################################################################-------
  733. //;子程序名:get1302
  734. void get_ds1302()
  735. {  uchar hour_count,minute_count,second_count;
  736.    uchar temp11[7],i,j;
  737.    for(i=0;i<7;i++)
  738.    {temp11[i]=0;}
  739.    for(i=0,j=0x81;i<7;i++,j+=2)
  740.    {  
  741.     rest_ds1302=0;
  742.     delay_3us();
  743.     clk_ds1302=0;
  744.     delay_3us();
  745.     rest_ds1302=1;
  746.     delay_3us();
  747.     w_1byte_ds1302(j);
  748.     temp11[i]=r_1byte_ds1302();
  749.     delay_3us();
  750.     clk_ds1302=1;
  751.     delay_3us();
  752.     rest_ds1302=0;
  753.     delay_3us();
  754.   }
  755.   if(temp11[0]!=0xff)
  756.   {second_count=temp11[0];}
  757.   if(temp11[1]!=0xff)// 数据验证
  758.   {minute_count=temp11[1];}
  759.   if(temp11[2]!=0xff)//数据验证
  760.   {hour_count=temp11[2];}
  761.          hour=hour_count/16*10+hour_count%16;
  762.         minute=minute_count/16*10+minute_count%16;
  763.         second=second_count/16*10+second_count%16;
  764.           /*zancun4=hour_count&0xf0;
  765.           zancun4>>=4;
  766.           zancun5=minute_count&0xf0;
  767.           zancun5>>=4;
  768.           zancun6=second_count&0xf0;
  769.           zancun6>>=4;*/
  770. }
复制代码
回复

使用道具 举报

ID:488532 发表于 2019-3-18 20:15 | 显示全部楼层
谢谢楼主的分享,下载下来看看。
回复

使用道具 举报

ID:208271 发表于 2019-3-28 09:58 | 显示全部楼层
很厉害。写数据到DS1302一直没做成功能,看了楼主的,很快成功了,51有你更精彩。真感谢!
回复

使用道具 举报

ID:324043 发表于 2019-3-29 13:09 来自手机 | 显示全部楼层
不错,谢谢分享。
回复

使用道具 举报

ID:476064 发表于 2019-4-27 21:37 来自手机 | 显示全部楼层
有人做出成品了吗? 请教个问题!为什我做出来后时钟芯片备用电池不但没有效果还被掏空了电
回复

使用道具 举报

ID:469510 发表于 2019-5-13 16:00 | 显示全部楼层
很给力!
回复

使用道具 举报

ID:224006 发表于 2020-3-6 18:00 | 显示全部楼层
学习了!
回复

使用道具 举报

ID:1119839 发表于 2024-5-8 21:42 | 显示全部楼层
真的对我帮助很大!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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