为什么我做的用eeprom来实现检验上电次数实现不了功能

[复制链接]
4755|21
 楼主| q1074926748 发表于 2012-4-30 22:08 | 显示全部楼层 |阅读模式
我做的这个程序是想实现断电后上电,数码管加一,,利用了eeprom的掉电数据不丢失的性能,利用结构体定义一个标志位,每次上电检测这个标志位,如果和定义的标志位相同,就加一,如果不相同,就把定义的标志位赋给结构体中得那个标志位,然后数码管显示为一。。不胜感激!!!具体程序如下(多文件程序
  1. #include "main.h"
  2. #include "eeprom.h"
  3. void iic_start()
  4. {
  5.   SDA=1;
  6.   _nop_();
  7.   SCL=1;
  8.   nops();
  9.   SDA=0;
  10.   nops();
  11.   SCL=0;
  12. }
  13. void iic_stop()
  14. {
  15.   SDA=0;
  16.   _nop_();
  17.   SCL=0;
  18.   nops();
  19.   SCL=1;
  20.   nops();
  21.   SDA=1;
  22. }
  23. void iic_write_byte(uint8 dat)
  24. {
  25.    uint8 i=0;
  26.    for(i=0;i<8;i++)
  27.    {
  28.       if(dat&0x80==0)
  29.           {
  30.              SDA=0;
  31.           }
  32.           else
  33.           {
  34.              SDA=1;
  35.           }
  36.           SCL=1;
  37.           dat<<=1;
  38.           nops();
  39.           SCL=0;
  40.           
  41.    }
  42. }
  43. uint8 iic_read_byte()
  44. {
  45.     uint8 dat,i=0;
  46.         for(i=0;i<8;i++)
  47.         {
  48.            SCL=1;
  49.            nops();
  50.            dat<<=1;
  51.            if(SDA)
  52.            {
  53.              dat|=0x01;
  54.            }
  55.            SCL=0;
  56.            nops();
  57.         }
  58.         return dat;
  59. }
  60. void iic_ack(bit ck)
  61. {
  62.   if(ck)
  63.   {
  64.      SDA=0;
  65.   }
  66.   else
  67.   {
  68.     SDA=1;
  69.   }
  70.   SCL=1;
  71.   nops();
  72.   SCL=0;
  73.   nops();
  74. }
  75. bit waitack()
  76. {
  77.    SDA=1;
  78.    nops();
  79.    SCL=1;
  80.    if(SDA)
  81.    {
  82.      SCL=0;
  83.          iic_stop();
  84.          return 1;
  85.    }
  86.    else
  87.    {
  88.      SCL=0;
  89.          return 0;

  90.    }
  91. }
  92. bit iic_write(uint8 addr,uint8 dat)
  93. {
  94.   iic_start();
  95.   iic_write_byte(0xa0);
  96.   if(waitack()==1)
  97.   {
  98.     return 1;
  99.   }
  100.     iic_write_byte(addr);
  101.   if(waitack()==1)
  102.   {
  103.     return 1;
  104.   }
  105.     iic_write_byte(dat);
  106.   if(waitack()==1)
  107.   {
  108.     return 1;
  109.   }
  110.   iic_stop();
  111.   return 0;
  112. }
  113. bit iic_read(uint8 addr,uint8*dat)
  114. {
  115.   iic_start();
  116.   iic_write_byte(0xa0);
  117.   if(waitack()==1)
  118.   {
  119.     return 1;
  120.   }
  121.   iic_write_byte(addr);
  122.   if(waitack()==1)
  123.   {
  124.     return 1;
  125.   }
  126.   iic_start();
  127.   iic_write_byte(0xa1);
  128.   if(waitack()==1)
  129.   {
  130.     return 1;
  131.   }
  132.   *dat=iic_read_byte();
  133.   iic_ack(0);
  134.   iic_stop();
  135.   return 0;
  136. }
  137. bit iic_write_buf(uint8 *buf,uint8 addr,uint8 len)
  138. {
  139.   while(len--)
  140.   {
  141.      if(iic_write(addr++,*buf++))
  142.          {
  143.            return 1;
  144.          }
  145.   }
  146.   return 0;
  147. }
  148. bit iic_read_buf(uint8 *buf,uint8 addr,uint8 len)
  149. {
  150.   while(len--)
  151.   {
  152.      if(iic_read(addr++,buf++))
  153.          {
  154.            return 1;
  155.          }
  156.   }
  157. return 0;
  158. }//这是eeprom.c

  159. #include "main.h"
  160. #include "eeprom.h"
  161. code uint8 a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
  162. code uint8 b[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
  163. uint8 c[10];
  164. uint8 i=0;
  165. POWER_UP Power_up;
  166. void delay(uint8 n)
  167. {
  168.   while(n--);
  169. }

  170. void main()
  171. {
  172.           while(1)
  173.     {
  174.     iic_read_buf((uint8*)&Power_up,0x00,sizeof(POWER_UP));
  175.         if(Power_up.flag!=P0WER_UP_MARK)
  176.         {
  177.            Power_up.flag=P0WER_UP_MARK;
  178.            Power_up.times=1;
  179.         }
  180.         else
  181.         {
  182.            Power_up.times++;
  183.         }
  184.         iic_write_buf((uint8*)&Power_up,0x00,sizeof(POWER_UP));
  185.         c[0]=a[Power_up.times%10];
  186.         c[1]=a[Power_up.times/10%10];
  187.         c[2]=a[Power_up.times/100%10];
  188.         c[3]=a[Power_up.times/1000%10];
  189.         c[4]=a[Power_up.times/10000%10];
  190.         c[5]=a[Power_up.times/100000%10];
  191.         c[6]=a[Power_up.times/1000000%10];
  192.         c[7]=a[Power_up.times/10000000%10];
  193.         for(i=0;i<8;i++)
  194.         {
  195.           P0=c[i];
  196.           P1=b[i];
  197.           delay(150);
  198.         }
  199.         }
  200. }//这是main.c
  201. #ifndef _MAIN_H_
  202. #define _MAIN_H_
  203. #include <reg51.h>
  204. #include <intrins.h>
  205. typedef unsigned char uint8;
  206. typedef unsigned int  uint16;
  207. typedef unsigned long uint32;
  208. sbit SDA=P2^1;
  209. sbit SCL=P2^0;
  210. typedef struct{
  211. uint32 times;
  212. uint8   flag;
  213. }POWER_UP;
  214. #define P0WER_UP_MARK 0xAB
  215. #endif//这是main.h
  216. #ifndef _EEPROM_H_
  217. #define _EEPROM_H_
  218. #define nops() do{_nop_();_nop_();_nop_();_nop_();}while(0)
  219. bit iic_write_buf(uint8*buf,uint8 addr,uint8 len);
  220. bit iic_read_buf(uint8*buf,uint8 addr,uint8 len);
  221. #endif//这是eeprom.h
 楼主| q1074926748 发表于 2012-4-30 22:11 | 显示全部楼层
说明一下了,我的是用共阴数码管,P0是段选,P1负责8个数码管的亮灭,SDA是P2^1,SCL是P2^0;
ningling_21 发表于 2012-5-1 09:01 | 显示全部楼层
IIC的读写函数都验证过吗?
 楼主| q1074926748 发表于 2012-5-1 09:01 | 显示全部楼层
自己顶一下
 楼主| q1074926748 发表于 2012-5-1 09:25 | 显示全部楼层
3# ningling_21 是的,,我这个程序是根据别人已经做好的程序修改的,我只是修改了一下main.c函数,其他的都没变,,由于别人的板子和我的不一样,不一样的地方只是在于数码管,所以我把数码管的部分修改了一下,还有SDA, SCL,,也是看到电路图引脚定义的,,,我感觉应该是写入eeprom有问题了,可是检查了好几遍,还是没发现问题在哪,,昨晚曾怀疑过是不是24c02坏了,不过运行了一下我买的板子的例程,能正常工作,所以程序出问题了,多谢您了
NE5532 发表于 2012-5-1 10:26 | 显示全部楼层
楼主的关键是如何尽快得知“掉电”,并且赶在电源电压下降之前把E2给写好,软件是浮云,硬件才是关键,这个东西不是软件对了就能做的。
 楼主| q1074926748 发表于 2012-5-1 10:46 | 显示全部楼层
6# NE5532 “如何尽快得知“掉电”,并且赶在电源电压下降之前把E2给写好”,这句话我倒是原来并没有注意到。那到底怎么避免这个问题呢,24c02不都是相同的吗?只要把SDA,SCL定义对了不就行了吗?和硬件有哪方面的联系?多谢了!希望能有进一步解释
autopccopy 发表于 2012-5-1 11:46 | 显示全部楼层
直接每次开机EEPROM的数值加一不行吗?不少开发板的标准例程都有。
NE5532 发表于 2012-5-1 14:02 | 显示全部楼层
任何芯片都要有电源才能工作吧,掉电和上电期间电源电压不稳定,E2读写都容易出错。8楼上电写的思路倒是很好,楼主可以参考。
再告诉楼主,不要以为软件对了就OK了,硬件才是天。
hzci12lc 发表于 2012-5-1 18:45 | 显示全部楼层
顶8楼,简单实用!
 楼主| q1074926748 发表于 2012-5-1 19:18 | 显示全部楼层
8# autopccopy 我的这个程序就是开机的时候实现加一,,但是不知道怎么回事每次开机都是从零开始了,这个我的板子里面例程没有,是根据别的开发板的程序写的,那我再看看Iic读写--
 楼主| q1074926748 发表于 2012-5-1 19:19 | 显示全部楼层
9# NE5532 恩,,我做程序那个思路我8楼的一样,我再看看代码,,实在不行我就换个板子试一试看行不行
 楼主| q1074926748 发表于 2012-5-1 19:23 | 显示全部楼层
9# NE5532 恩,硬件才是天,,看来我再单片机学习的路上过于偏“软“以为只要能看得懂单片机电路图就行了,会看着电路图定义一些管教就行了,以后多注意硬件!!!
 楼主| q1074926748 发表于 2012-5-1 22:14 | 显示全部楼层
13# q1074926748 那如果是硬件的问题,怎么解决呢,难道在实际工作中碰到这样的问题,就放弃了吗。或者换板子,那不是很浪费,我现在还是一个学生,求教!!
NE5532 发表于 2012-5-2 08:04 | 显示全部楼层
13# q1074926748 那如果是硬件的问题,怎么解决呢,难道在实际工作中碰到这样的问题,就放弃了吗。或者换板子,那不是很浪费,我现在还是一个学生,求教!! ...
q1074926748 发表于 2012-5-1 22:14


硬件和软件都是根据需求来进行设计的,你的认识反了。你现在是“因为是学生”,所以“将就”手里有的东西做着玩,跟搞设计是两码事。
 楼主| q1074926748 发表于 2012-5-2 17:44 | 显示全部楼层
仍然希望这方面问题的大侠发言。顶起来
234641497 发表于 2012-5-4 13:39 | 显示全部楼层
开机加延时没有?开机延时,读一下,再加一保存,然后结束,应该就可以了,开机要加延时,1ms
234641497 发表于 2012-5-4 13:39 | 显示全部楼层
开机加延时没有?开机延时,读一下,再加一保存,然后结束,应该就可以了,开机要加延时,1ms
 楼主| q1074926748 发表于 2012-5-4 22:59 | 显示全部楼层
18# 234641497 开机加延时?为啥????是为了等待电源稳定吗?还是等待什么???
cjseng 发表于 2012-5-5 23:53 | 显示全部楼层
我觉得楼主缺乏查找问题的经验。
就你这个例子来说:IIC的读写函数验证了吗?数码管显示验证了吗?就算IIC读写函数没问题,数据在送到显示之前会不会中间被改变了呢?另外,编程思路是否正确呢?为什么要判断标志位呢?上电一次就加一不就完事了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:郭强

0

主题

58

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部