找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2655|回复: 6
收起左侧

关于51单片机与AT24C02万年历设计EEPORM写入失败的疑问

[复制链接]
ID:318173 发表于 2018-8-5 23:04 | 显示全部楼层 |阅读模式
50黑币
这个是用AT24C02和51单片机做得本来只差年的拆分了,其他部分都可以正常变化,因为AT24C02一个地址只能存一字节,结果后来自己调的年月份都有问题,我直接在write_add里给除年以外的月份,日,小时赋正常值,结果有时只会有一个比如月份变化,其他的几个没变化,我怀疑是不是EEPORM有啥问题,为啥我直接赋值都没变化,每次赋值后我还RESET了一下然后再重启,求大佬解决一下,调了几天了。
  1. /***************************************************
  2.      程序功能:实现一个万年历
  3.          拓展模块:之后加GPS定位和温度数据以及红外遥控
  4. ***************************************************/
  5. #include<reg52.h>
  6. #include<string.h>
  7. #include<stdio.h>
  8. #define uchar unsigned char
  9. #define unit unsigned int

  10. unit nian;
  11. uchar yue,ri,shi,feng,miao;           //将这些数据定义为全局变量,因为等下会对他们进行计数
  12. unit num,num0;                           //通过对功能选择键按的次数进行计数来选择对年月日还是时分秒进行修改
  13. unit number;
  14. sbit lcden=P2^5;
  15. sbit lcdrs=P1^0;
  16. sbit RW=P1^1;
  17. sbit dula=P2^6;
  18. sbit wela=P2^7;
  19. sbit SDA=P2^0;
  20. sbit SCL=P2^1;
  21. sbit option=P3^4;
  22. sbit add=P3^5;
  23. sbit dcen=P3^6;
  24. sbit beef=P2^3;

  25. /*****************************
  26.          延迟函数
  27. *****************************/
  28. void delayms(unit ms)
  29. {
  30.    unit i,j;
  31.    for(i=ms;i>0;i--)
  32.    for(j=110;j>0;j--);
  33. }

  34. void delay()
  35. {

  36. }

  37. /******************************
  38.         初始化函数
  39. ******************************/
  40. void init()
  41. {
  42. EA=1;
  43. ET0=1;
  44. TMOD=0x01;
  45. TH0=(65536-50000)/256;
  46. TL0=(65536-50000)%256;
  47. TR0=1;
  48. }

  49. /******************************
  50.       蜂鸣器函数
  51. ******************************/
  52. void di()
  53. {
  54.    beef=0;
  55.    delayms(100);
  56.    beef=1;
  57. }
  58. ///////////////////////////////////////////////////////////////////////
  59. //                        1602模块程序                                         //
  60. ///////////////////////////////////////////////////////////////////////



  61. /****************************
  62.         写命令函数
  63. ****************************/     
  64. void write_com(uchar com)
  65. {
  66.   P0=0xff;
  67.   P0=com;
  68.   lcdrs=0;
  69.   RW=0;
  70.   delayms(5);
  71.   lcden=1;
  72.   delayms(5);
  73.   lcden=0;
  74. }

  75. /****************************
  76.         写数据函数
  77. ****************************/
  78. void write_data(uchar Data)
  79. {
  80.    P0=0xff;
  81.    P0=Data;
  82.    lcdrs=1;
  83.    RW=0;
  84.    delayms(5);
  85.    lcden=1;
  86.    delayms(5);
  87.    lcden=0;
  88. }

  89. /*****************************
  90.        屏幕初始化函数      
  91. *****************************/
  92. void screen_init()
  93. {
  94.   dula=0;
  95.   wela=0;           ///关闭数码管
  96.   write_com(0x38);
  97.   write_com(0x0e);
  98.   write_com(0x06);
  99.   write_com(0x01);
  100. }

  101. /*****************************
  102.         1602显示函数
  103. *****************************/
  104. void display(unit nian,uchar yue,uchar ri,uchar shi,uchar feng,uchar miao)         //此函数的形参变化由中断函数提供  
  105. {  
  106.    screen_init();

  107.    write_com(0x80);
  108.    write_data(nian/1000+0x30);

  109.    write_data(nian/100%10+0x30);

  110.    write_data(nian%100/10+0x30);

  111.    write_data(nian%10+0x30);

  112.    write_data('-');

  113.    write_data(yue/10+0x30);

  114.    write_data(yue%10+0x30);

  115.    write_data('-');

  116.    write_data(ri/10+0x30);

  117.    write_data(ri%10+0x30);




  118.    write_com(0x80+0x40);

  119.    write_data(shi/10+0x30);

  120.    write_data(shi%10+0x30);

  121.    write_data('-');

  122.    write_data(feng/10+0x30);

  123.    write_data(feng%10+0x30);

  124.    write_data('-');

  125.    write_data(miao/10+0x30);

  126.    write_data(miao%10+0x30);




  127. }


  128. //////////////////////////////////////////////////////////////////////////////////////
  129. //                          AT24C02模块程序                                                                                        //
  130. //////////////////////////////////////////////////////////////////////////////////////

  131. /*****************************
  132.         启动信号函数
  133. *****************************/
  134. void start()
  135. {
  136. SDA=1;
  137. delay();
  138. SCL=1;
  139. delay();
  140. SDA=0;
  141. delay();
  142. }

  143. /*****************************
  144.         终止信号函数
  145. *****************************/
  146. void stop()
  147. {
  148. SDA=0;
  149. delay();
  150. SCL=1;
  151. delay();
  152. SDA=1;
  153. delay();
  154. }

  155. /*****************************
  156.           应答函数
  157. *****************************/
  158. void response()
  159. {
  160.   unit i;
  161.   SCL=1;
  162.   delay();
  163.   while((SDA==1)&&(i<255))
  164.   i++;
  165.   SCL=0;
  166.   delay();
  167. }
  168. /*****************************
  169.       写一字节函数
  170. *****************************/
  171. void write_byte(uchar Data)
  172. {
  173.   uchar temp;
  174.   uchar i;
  175.   temp=Data;
  176.   for(i=0;i<8;i++)
  177.   {
  178.      temp=temp<<1;
  179.      SCL=0;
  180.          delay();
  181.          SDA=CY;
  182.          delay();
  183.          SCL=1;
  184.          delay();
  185.   }
  186.   SCL=0;
  187.   delay();
  188.   SDA=1;
  189.   delay();
  190. }
  191. /****************************
  192.        读一字节函数
  193. ****************************/
  194. uchar read_byte()
  195. {
  196. uchar i,k;
  197. SCL=0;
  198. delay();
  199. SDA=1;
  200. delay();
  201. for(i=0;i<8;i++)
  202. {
  203.   SCL=1;
  204.   delay();
  205.   k=(k<<1)|SDA;
  206.   SCL=0;
  207.   delay();
  208.   }
  209.   delay();
  210.   return k;
  211. }

  212. /*****************************
  213.        写操作方式函数      
  214. *****************************/
  215. void write_add(uchar address,uchar Data)
  216. {
  217.    start();
  218.    write_byte(0xa0);
  219.    response();
  220.    write_byte(address);
  221.    response();
  222.    write_byte(Data);
  223.    response();
  224.    stop();
  225. }
  226. /*****************************
  227.        读操作方式函数
  228. *****************************/
  229. uchar read_add(uchar address)
  230. {
  231.    uchar Data;
  232.    start();
  233.    write_byte(0xa0);
  234.    response();
  235.    write_byte(address);
  236.    response();
  237.    start();
  238.    write_byte(0xa1);
  239.    response();
  240.    Data=read_byte();
  241.    stop();

  242.    return Data;
  243. }

  244. ////////////////////////////////////////////////////////////////////////////
  245. //                       键盘功能程序                                                                  //
  246. ////////////////////////////////////////////////////////////////////////////
  247. void keyscan()
  248. {
  249.   if(option==0)
  250.   {         
  251.     TR0=0;
  252.     delayms(10);
  253.         if(option==0)                         //检测功能键是否按下
  254.           {
  255.             di();
  256.             number++;
  257.                 while(!option);
  258.                 if(number==1)
  259.                  {                                            
  260.                    write_com(0x80+4);     //光标定义到年位置
  261.             
  262.                  }
  263.                  if(number==2)
  264.                  {
  265.                    write_com(0x80+7);
  266.                  }
  267.                  if(number==3)
  268.                  {
  269.                    write_com(0x80+10);
  270.                  }
  271.                  if(number==4)
  272.                  {
  273.                   write_com(0x80+0x40+2);
  274.                  }
  275.                  if(number==5)
  276.                  {
  277.                    write_com(0x80+0x40+5);
  278.                  }
  279.                  if(number==6)
  280.                  {
  281.                    write_com(0x80+0x40+8);
  282.                  }
  283.                  
  284.            }
  285.         }
  286.          if(number!=0)           //如果按下了功能键  以下是功能键次数
  287.          {
  288.            if(add==0)
  289.            {
  290.              delayms(10);
  291.                  if(add==0)
  292.                    {
  293.                      while(!add);
  294.                          di();
  295.                          if(number==1)
  296.                           {
  297.                              nian++;
  298.                            }
  299.                           if(number==2)
  300.                           {
  301.                             yue++;
  302.                           }
  303.                           if(number==3)
  304.                           {
  305.                             ri++;
  306.                           }
  307.                           if(number==4)
  308.                           {
  309.                             shi++;
  310.                           }
  311.                           if(number==5)
  312.                           {
  313.                              feng++;
  314.                           }
  315.                           if(number==6)
  316.                           {
  317.                              miao++;
  318.                           }
  319.                          }
  320.                  }
  321.                  
  322.                    if(dcen==0)
  323.                    {
  324.                      delayms(10);
  325.                          if(dcen==0)
  326.                     {
  327.                             while(!dcen);
  328.                                 di();
  329.                                 if(number==1)
  330.                            {
  331.                              nian--;
  332.                            }
  333.                           if(number==2)
  334.                            {
  335.                             yue--;
  336.                            }
  337.                           if(number==3)
  338.                            {
  339.                             ri--;
  340.                            }
  341.                           if(number==4)
  342.                            {
  343.                             shi--;
  344.                            }
  345.                           if(number==5)
  346.                            {
  347.                              feng--;
  348.                            }
  349.                           if(number==6)
  350.                            {
  351.                              miao--;
  352.                            }
  353.                          }
  354.                    }
  355.       }
  356.                TR0=1;
  357. }      
  358.                                                                                       
  359. ////////////////////////////////////////////////////////
  360. ///                  主函数                                               /////
  361. ////////////////////////////////////////////////////////

  362. void main()
  363. {  
  364.    init();

  365.    nian=read_add(1);
  366.    yue=read_add(2);
  367.    ri=read_add(3);
  368.    shi=read_add(4);
  369.    feng=read_add(5);
  370.    miao=read_add(6);


  371.    while(1)
  372.    {  

  373.          
  374.        display(nian,yue,ri,shi,feng,miao);                  //接收到数据后在1602上显示
  375.          
  376.        keyscan();                                         //对日期时间的调整,同时注意对日期进行调整的时候是不允许进入中断的

  377.                                   //接收到数据显示完,而且更改完了之后就把数据写入内存中,以方便以后断电保存
  378.          
  379.          
  380.          
  381.          
  382.                
  383.           write_add(1,nian);
  384.           write_add(2,yue);
  385.           write_add(3,ri);
  386.           write_add(4,shi);  //刚才显示时15,因为直接写21会默认你为int,记住要复位重烧也不会改变数据
  387.           write_add(5,feng);
  388.           write_add(6,miao);
  389.    }

  390. }


  391. /***************************
  392.       定时器中断函数
  393. ****************************/
  394. void ser()interrupt 1
  395. {

  396.   TH0=(65536-50000)/256;
  397.   TL0=(65536-50000)%256;

  398.       num++;

  399.          
  400.            if(num>=20)
  401.           {
  402.             miao++;
  403.                 num=0;
  404.       
  405.           }
  406.           if(miao==60)
  407.           {
  408.             feng++;
  409.                 miao=0;
  410.           }
  411.           if(feng==60)
  412.           {
  413.              feng=0;
  414.                  shi++;
  415.                  
  416.           }
  417.           if(shi==24)
  418.           {
  419.               shi=0;
  420.               ri++;
  421.                   
  422.       }
  423.           if(ri==30)
  424.           {
  425.             ri=0;
  426.             yue++;
  427.           }
  428.           if(yue==12)
  429.           {
  430.             yue=0;
  431.             nian++;
  432.           }
  433.          
  434. }   
复制代码



回复

使用道具 举报

ID:318173 发表于 2018-8-5 23:11 | 显示全部楼层
我就是想先手动写入正常值然后再让他自己变化,结果写入不了,感觉是不是形参传递我的形参类型设置有问题,传来传去有点晕.
回复

使用道具 举报

ID:310519 发表于 2018-8-6 10:38 | 显示全部楼层
可以单独测试读写。
回复

使用道具 举报

ID:292503 发表于 2018-8-6 12:06 | 显示全部楼层
我就是想先手动写入正常值然后再让他自己变化,,感觉是不是形参传递我的形参类型设置有问题,传来传去有点晕.
回复

使用道具 举报

ID:268717 发表于 2018-10-2 16:42 | 显示全部楼层
你这个写入的时候是不是先写入月  在写入年日时间?
回复

使用道具 举报

ID:268717 发表于 2018-10-2 16:46 | 显示全部楼层
典型郭天祥风格  AT24C02的驱动程序是直接拿的郭天祥的实例程序吧!
你这问题我也遇到过,想要答案加我QQ:2577647123!有偿回答!
回复

使用道具 举报

ID:387733 发表于 2018-10-3 08:04 | 显示全部楼层
我自己一直使用的AT24C02库,反复优化过的,可供参考

AT24C02.rar

972 Bytes, 下载次数: 25

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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