找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1601|回复: 8
收起左侧

关于51单片机制作时钟?不知道是断电保护还是代码问题

[复制链接]
ID:687423 发表于 2020-2-15 13:44 | 显示全部楼层 |阅读模式
用51单片机做时钟,我没用1302,就是一个简单的时钟,可以用6个数码管显示时分秒,液晶上显示日期和时间,可以用3个按键实现功能选择和加减。这些在开发板上都可以实现,之后我想在此基础上我想用AT24C02实现断电保护功能,当我的程序写完之后,发现无法实现,这个只能实现的是用按键控制的数字,比如我用按键将时间调成000019,之后让它自己往上加,然后我再断电,等我在上电的时候数码管上显示的还是000019,这个现象是属于断电保护还是代码出问题了,我有点不太清楚,代码如下,请求大家帮助。谢谢。

单片机源程序如下:
  1. #include<reg52.h>
  2. sbit lsa=P2^2;
  3. sbit lsb=P2^3;
  4. sbit lsc=P2^4;
  5. sbit k1=P3^1;
  6. sbit k2=P3^0;
  7. sbit k3=P3^2;
  8. sbit SDA=P2^0;
  9. sbit SCL=P2^1;
  10. sbit e=P2^7;
  11. sbit rw=P2^5;
  12. sbit rs=P2^6;
  13. typedef unsigned int ui;
  14. typedef unsigned char uc;
  15. ui code shuju[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  16.      0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  17. ui disp[6];
  18. ui num,shi,fen,miao;
  19. ui ss=0;
  20. uc code table[]="  2020-2-12 WED";
  21. void delay(ui i)
  22. {
  23. while(i--);
  24. }
  25. void Delay10us()
  26. {
  27. unsigned char a,b;
  28. for(b=1;b>0;b--)
  29.   for(a=2;a>0;a--);[/backcolor][/color]
  30. [color=rgb(102, 102, 102)][backcolor=rgb(255, 255, 255)]}
  31. void yjdelay(ui c)
  32. {
  33. uc a,b;
  34. for (; c>0; c--)
  35. {
  36.    for (b=199;b>0;b--)
  37.    {
  38.      for(a=1;a>0;a--);
  39.    }      
  40. }
  41. }[/backcolor][/color]
  42. [color=rgb(102, 102, 102)][backcolor=rgb(255, 255, 255)]void I2cStart()
  43. {
  44. SDA=1;
  45. Delay10us();
  46. SCL=1;
  47. Delay10us();//?????????SDA???????>4.7us
  48. SDA=0;
  49. Delay10us();//?????????>4us
  50. SCL=0;   
  51. Delay10us();  
  52. }
  53. void I2cStop()
  54. {
  55. SDA=0;
  56. Delay10us();
  57. SCL=1;
  58. Delay10us();//??????????4.7us
  59. SDA=1;
  60. Delay10us();  
  61. }
  62. void respons()
  63. {
  64. ui b;
  65. SCL=1;
  66. while(SDA)//????????????????豸??SDA????
  67. {
  68.   b++;
  69.   if(b>200)  //???????2000us????????????????????????????????
  70.   {
  71.    SCL=0;
  72.    Delay10us();
  73.   }
  74. }
  75. SCL=0;
  76. Delay10us();  
  77. }
  78. void I2cSendByte(unsigned char dat)
  79. {
  80. unsigned char a=0,b=0;//???255??????????????1us????????255us??  
  81. for(a=0;a<8;a++)//?????8λ???????λ???
  82. {
  83.   SDA=dat>>7;  //?????????SCL=0??????????????SDA???
  84.   dat=dat<<1;
  85.   Delay10us();
  86.   SCL=1;
  87.   Delay10us();//???????>4.7us
  88.   SCL=0;
  89.   Delay10us();//??????4us  
  90. }
  91. SDA=1;
  92. Delay10us();
  93. SCL=0;
  94. Delay10us();
  95. }
  96. unsigned char I2cReadByte()
  97. {
  98. unsigned char a=0,dat=0;
  99. SDA=1;   //?????????????????SCL????0
  100. Delay10us();
  101. for(a=0;a<8;a++)//????8?????
  102. {
  103.   SCL=1;
  104.   Delay10us();
  105.   dat<<=1;
  106.   dat|=SDA;
  107.   Delay10us();
  108.   SCL=0;
  109.   Delay10us();
  110. }
  111. return dat;  
  112. }[/backcolor][/color]
  113. [color=rgb(102, 102, 102)][backcolor=rgb(255, 255, 255)]
  114. void write_add(unsigned char addr,unsigned char dat)
  115. {
  116. I2cStart();
  117. I2cSendByte(0xa0);//????д???????
  118. respons();
  119. I2cSendByte(addr);//?????д???????
  120. respons();
  121. I2cSendByte(dat); //????????
  122. respons();
  123. I2cStop();
  124. }
  125. unsigned char read_add(unsigned char addr)
  126. {
  127. unsigned char num;
  128. I2cStart();
  129. I2cSendByte(0xa0); //????д???????
  130. respons();
  131. I2cSendByte(addr); //????????????
  132. respons();
  133. I2cStart();
  134. I2cSendByte(0xa1); //????????????
  135. respons();
  136. num=I2cReadByte(); //???????
  137. I2cStop();
  138. return num;
  139. }
  140. void init24c02()
  141. {
  142. SDA=1;
  143. Delay10us();
  144. SCL=1;
  145. Delay10us();
  146. miao=read_add(1);
  147. fen=read_add(2);
  148. shi=read_add(3);
  149. }
  150. void write_com(uc com)
  151. {
  152. rs=0;
  153. rw=0;
  154. e=0;
  155. P0=com;
  156. yjdelay(1);
  157. e=1;
  158. yjdelay(5);
  159. e=0;
  160. }
  161. void lcdwrite_data(uc dat)
  162. {
  163. e=0;
  164. rs=1;
  165. rw=0;
  166. P0=dat;
  167. yjdelay(1);
  168. e=1;
  169. yjdelay(5);
  170. e=0;
  171. }
  172. void write_sfm(uc add,uc date)
  173. {
  174. uc shi,ge;
  175. shi=date/10;
  176. ge=date%10;
  177. write_com(0x80+0x40+add);
  178. lcdwrite_data(0x30+shi);
  179. lcdwrite_data(0x30+ge);
  180. }
  181. void lcdinit()
  182. {
  183. write_com(0x38);
  184. write_com(0x0c);  //?????????????
  185. write_com(0x06);  //д???????1
  186. write_com(0x01);  //????
  187. }
  188. void yejing()
  189. {
  190. uc i;
  191. lcdinit();
  192. for(i=0;i<15;i++)
  193. {
  194.   lcdwrite_data(table[i]);
  195.   delay(10);  
  196. }
  197. write_com(0x80+0x40+6);
  198. lcdwrite_data(':');
  199. delay(10);
  200. write_com(0x80+0x40+9);
  201. lcdwrite_data(':');
  202. delay(10);
  203. write_sfm(4,shi);
  204. write_sfm(7,fen);
  205. write_sfm(10,miao);
  206. }
  207. void datapros()
  208. {
  209. disp[0]=shuju[miao%10];
  210. disp[1]=shuju[miao/10];
  211. disp[2]=shuju[fen%10];
  212. disp[3]=shuju[fen/10];
  213. disp[4]=shuju[shi%10];
  214. disp[5]=shuju[shi/10];
  215. }
  216. void display()
  217. {
  218. ui i;
  219. for(i=0;i<6;i++)
  220. {
  221.   switch(i)
  222.   {
  223.    case(0): lsa=0;lsb=0;lsc=0;break;
  224.    case(1): lsa=1;lsb=0;lsc=0;break;
  225.    case(2): lsa=0;lsb=1;lsc=0;break;
  226.    case(3): lsa=1;lsb=1;lsc=0;break;
  227.    case(4): lsa=0;lsb=0;lsc=1;break;
  228.    case(5): lsa=1;lsb=0;lsc=1;break;
  229.   }
  230.   P0=disp[i];
  231.   delay(100);
  232.   P0=0x00;
  233. }
  234. }
  235. void init()
  236. {
  237. TMOD=0x01;
  238. TH0=0xfc;
  239. TL0=0x18;  //1ms
  240. EA=1;
  241. TR0=1;
  242. ET0=1;
  243. }
  244. void key()
  245. {
  246. if(k1==0)
  247. {
  248.   delay(100);
  249.   {
  250.    if(k1==0)
  251.    {
  252.     ss=ss+2;
  253.     while(!k1);
  254.     switch(ss)
  255.     {
  256.      case(2): lsa=0;lsb=0;lsc=0;TR0=0;write_com(0x80+0x40+10);write_com(0x0f);break;
  257.    
  258.      case(4): lsa=0;lsb=1;lsc=0;write_com(0x80+0x40+7);break;
  259.    
  260.      case(6): lsa=0;lsb=0;lsc=1;write_com(0x80+0x40+4);break;
  261.    
  262.      case(8): ss=0;write_com(0x0c);TR0=1;break;
  263.     }
  264.    }
  265.   }
  266. }
  267. if(ss!=0)
  268. {
  269.   if(k2==0)
  270.   {
  271.    delay(100);
  272.    {
  273.     if(k2==0)
  274.     {
  275.      while(!k2);
  276.      if(ss==2)
  277.      {
  278.       miao++;
  279.       if(miao==60)
  280.        miao=0;
  281.       write_sfm(10,miao);
  282.       write_com(0x80+0x40+10);
  283.       write_add(1,miao);
  284.      }
  285.      if(ss==4)
  286.      {
  287.       fen++;
  288.       if(fen==60)
  289.        fen=0;
  290.       write_sfm(7,fen);
  291.       write_com(0x80+0x40+7);
  292.       write_add(2,fen);
  293.      }
  294.      if(ss==6)
  295.      {
  296.       shi++;
  297.       if(shi==24)
  298.        shi=0;
  299.       write_sfm(4,shi);
  300.       write_com(0x80+0x40+4);
  301.       write_add(3,shi);
  302.      }
  303.     }
  304.    }
  305.   }
  306.   if(k3==0)
  307.   {
  308.    delay(100);
  309.    if(k3==0)
  310.    {
  311.     while(!k3);
  312.     if(ss==2)
  313.     {
  314.      miao--;
  315.      if(miao==-1)
  316.       miao=59;
  317.      write_sfm(10,miao);
  318.      write_com(0x80+0x40+10);
  319.      write_add(1,miao);
  320.     }
  321.     if(ss==4)
  322.     {
  323.      fen--;
  324.      if(fen==-1)
  325.       fen=59;
  326.      write_sfm(7,fen);
  327.      write_com(0x80+0x40+7);
  328.      write_add(2,fen);
  329.     }
  330.     if(ss==6)
  331.     {
  332.      shi--;
  333.      if(shi==-1)
  334.       shi=23;
  335.      write_sfm(4,shi);
  336.      write_com(0x80+0x40+4);
  337.      write_add(3,shi);
  338.     }
  339.    }
  340.   }
  341. }

  342. }
  343. void main()
  344. {
  345. init();
  346. init24c02();
  347. yejing();
  348. while(1)
  349. {
  350.   key();
  351.   datapros();
  352.   display();
  353. }
  354. }
  355. void init0() interrupt 1
  356. {
  357. TH0=0xfc;
  358. TL0=0x18;
  359. num++;
  360. if(num==1000)
  361. {
  362.   miao++;
  363.   write_sfm(10,miao);
  364.   num=0;
  365.   if(miao==60)
  366.   {
  367.    miao=0;
  368.    fen++;
  369.    write_sfm(7,fen);
  370.    if(fen==60)
  371.    {
  372.     fen=0;
  373.     shi++;
  374.     write_sfm(4,shi);
  375.     if(shi==24)
  376.     {
  377.      shi=0;
  378.      write_sfm(4,shi);
  379.      write_add(3,shi);
  380.     }
  381.     write_sfm(7,fen);
  382.     write_add(2,fen);
  383.    }
  384.    write_sfm(10,miao);
  385.    write_add(1,miao);
  386.   }
  387. }
  388.   
  389. }
复制代码


回复

使用道具 举报

ID:377268 发表于 2020-2-15 14:43 来自手机 | 显示全部楼层
只要断掉复位后不是0就是保存过了,至于保存的和你自己预想的不一样应该是程序问题。
回复

使用道具 举报

ID:687423 发表于 2020-2-15 15:19 | 显示全部楼层
这个程序只能保护通过按键改变的数据,不能改变时钟自身改变的数据,我想知道怎样才能保护时钟自身改变的数据。
回复

使用道具 举报

ID:687423 发表于 2020-2-15 18:27 | 显示全部楼层
1105730718 发表于 2020-2-15 14:43
只要断掉复位后不是0就是保存过了,至于保存的和你自己预想的不一样应该是程序问题。

意思就是让时钟自身走一会之后断电在上电不是一样的数据就是保护过了吗,这个断电在上电数据是一样的,只有通过按键改变数据才能保护,我也不知道哪错了。
回复

使用道具 举报

ID:462827 发表于 2020-2-16 15:15 | 显示全部楼层
你在修改时间的时候要把它更新写入DS1302,不然你改你的,DS1302还是按它自己的来走时,重新读出来并不是你所修改的值呀。
回复

使用道具 举报

ID:687423 发表于 2020-2-16 18:55 来自手机 | 显示全部楼层
hantu 发表于 2020-2-16 15:15
你在修改时间的时候要把它更新写入DS1302,不然你改你的,DS1302还是按它自己的来走时,重新读出来并不是你 ...

找到了,我中断里没有把自身变化的值给存进去,感谢啊,找了好几天错误了,今天终于找到了。
回复

使用道具 举报

ID:718183 发表于 2020-3-29 15:36 来自手机 | 显示全部楼层
。。jj 发表于 2020-2-16 18:55
找到了,我中断里没有把自身变化的值给存进去,感谢啊,找了好几天错误了,今天终于找到了。

我想要你修改后的程序
回复

使用道具 举报

ID:718183 发表于 2020-3-30 00:26 来自手机 | 显示全部楼层
。。jj 发表于 2020-2-16 18:55
找到了,我中断里没有把自身变化的值给存进去,感谢啊,找了好几天错误了,今天终于找到了。

可以吗
回复

使用道具 举报

ID:65956 发表于 2020-3-30 08:36 | 显示全部楼层
没细看你的代码,但根据你的描述应是没有秒计数完成再把数值存入到EEPROM中,只有在每计一秒数值后即把数值再存一个,才能实现在什么时间停后,开机再读出时才能读到停电时间,但是时钟作这样会导致时间会不准
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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