单片机/MCU论坛
直播中

杨秀英

7年用户 1393经验值
私信 关注
[问答]

51单片机24c02读取出来的数据不对,再次复位后数值变大

每次设定好,结果再复位出现的数值总是大了些,但确定它是能写入的。
应该不是延时固化数据的问题,是WrToROM或者RdFromROM 这两个子程序出问题了吗

  1. #include    
  2. #include
  3. #include "24c02.h"   
  4. #define AddWr 0xa0   //写数据地址
  5. #define AddRd 0xa1   //读数据地址


  6. ***it WP=P1^6;        

  7. /*------------------------------------------------
  8.                      延时程序
  9. ------------------------------------------------*/
  10.   void mDelay(unsigned char j)
  11.   {
  12.    unsigned int i;
  13.    for(;j>0;j--)
  14.       {
  15.    for(i=0;i<100;i++)
  16.       {;}
  17.    }
  18.    }
  19.   
  20.   /*--------------------------------------------------
  21.                    初始化
  22. --------------------------------------------------*/
  23. void init(void)
  24. {
  25.    Sda = 1;
  26. mDelay(3);
  27. Scl=1;
  28. mDelay(3);
  29. }

  30. /*------------------------------------------------
  31.                     启动IIC总线
  32. ------------------------------------------------*/
  33.    void Start(void)
  34.    {
  35.    Sda=1;
  36.    mDelay(3);
  37.    Scl=1;
  38.    mDelay(3);
  39.    Sda=0;
  40.    mDelay(3);
  41.    }


  42. /*------------------------------------------------
  43.                      停止IIC总线
  44. ------------------------------------------------*/
  45.    void Stop(void)
  46.    {
  47.    Sda=0;
  48.    mDelay(3);
  49.    Scl=1;
  50.    mDelay(3);
  51.    Sda=1;
  52.    mDelay(3);
  53.     }


  54. /*------------------------------------------------
  55.                    应答IIC总线
  56. ------------------------------------------------*/
  57.     void Ack(void)
  58.     {
  59.      Sda=0;
  60.    mDelay(3);
  61.    Scl=1;
  62.    mDelay(3);
  63.    Scl=0;
  64.    mDelay(3);
  65. }

  66.    
  67. /*------------------------------------------------
  68.                   非应答IIc
  69. ------------------------------------------------*/
  70. void NoAck(void)
  71. {
  72.   Sda=1;
  73.     mDelay(3);
  74.     Scl=1;
  75.     mDelay(3);
  76.     Scl=0;
  77.     mDelay(3);
  78.   }
  79.      
  80.    
  81. /*------------------------------------------------
  82.                   发送一个字节
  83. ------------------------------------------------*/
  84.   void Send(unsigned char Data)
  85.   {
  86.    unsigned char BitCounter=8;
  87.    unsigned char temp;
  88.    do
  89.     {
  90.   temp=Data;
  91.   Scl=0;
  92.   _nop_();_nop_();_nop_();_nop_();_nop_();
  93.   if((temp&0x80)==0x80)
  94.      Sda=1;
  95.   else
  96.      Sda=0;
  97.    Scl=1;
  98.    temp=Data<<1;
  99.    Data=temp;
  100.    BitCounter--;
  101.    }
  102.    while(BitCounter);
  103.        Scl=0;
  104.    }

  105.                                                                      
  106. /*------------------------------------------------
  107.                读入一个字节
  108. ------------------------------------------------*/
  109.    unsigned char Read(void)
  110.    {
  111.     unsigned char temp=0;
  112.     unsigned char temp1=0;
  113.     unsigned char BitCounter=8;
  114.     WP = 0;
  115.     Sda=1;
  116.     do
  117.       {
  118.    Scl=0;
  119.            _nop_();_nop_();_nop_();_nop_();_nop_();
  120.    Scl=1;
  121.        _nop_();_nop_();_nop_();_nop_();_nop_();
  122.    if(Sda)
  123.       temp=temp|0x01;
  124.    else
  125.       temp=temp&0xfe;

  126.    if(BitCounter-1)
  127.       {
  128.    temp1=temp<<1;
  129.    temp=temp1;
  130.    }
  131.    BitCounter--;
  132.   }
  133. while(BitCounter);
  134. return(temp);
  135.    }
  136.   

  137. /*------------------------------------------------
  138.                     写入数据
  139. ------------------------------------------------*/
  140.    void WrToROM(unsigned char Data[],unsigned char Address,unsigned char Num)
  141.    {
  142.     unsigned char i;
  143.     unsigned char *PData;
  144.     PData=Data;
  145.       init();
  146.     WP = 0;
  147.     for(i=0;i
  148.     {
  149.     Start();
  150.     Send(AddWr);      //写入芯片地址
  151.    Ack();            //应答
  152.    Send(Address+i);  //写入芯片地址
  153.    Ack();            //应答
  154.    Send(*(PData+i)); //写数据
  155.    Ack();            //应答
  156.    Stop();           //停止总线
  157.    mDelay(20);
  158.     }
  159.     }

  160.   
  161. /*------------------------------------------------
  162.                   读出数据
  163. ------------------------------------------------*/
  164.    void RdFromROM(unsigned char Data[],unsigned char Address,unsigned char Num)
  165.    {
  166.     unsigned char i;
  167.     unsigned char *PData;
  168.     PData=Data;
  169.       for(i=0;i
  170.        {
  171.     Start();        
  172.     Send(AddWr);    //写入芯片地址
  173.    Ack();
  174.       Send(Address+i);//写入存储地址
  175.    Ack();
  176.     Start();
  177.     Send(AddRd);    //读入地址
  178.    Ack();
  179.     *(PData+i)=Read();//读数据
  180.    Scl=0;
  181.     NoAck();
  182.     Stop();
  183.     }
  184.    }


  185. void U16_Save(unsigned int *tmp,unsigned char add)
  186. {
  187.    unsigned char buf[2]=0;
  188.    buf[0]= *tmp/256;
  189.    buf[1]= *tmp%256;
  190.    WrToROM(buf,add,2);
  191.    mDelay(50);
  192. }

  193. void U16_Read(unsigned int *tmp,unsigned char add)
  194. {
  195.    unsigned char buf[2]=0;
  196.    RdFromROM(buf,add,2);
  197.    *tmp=256*(buf[0])+buf[1];
  198.    mDelay(50);
  199. }


回帖(15)

李娜

2019-2-13 10:01:00
EEPROM的初始值是否为0xFF?
举报

杨秀英

2019-2-13 10:01:12
没有设置初始值
举报

李梅

2019-2-13 10:01:20
楼主晶振用的多少MHz的?
举报

杨秀英

2019-2-13 10:01:51
12M的
举报

李斌

2019-2-13 10:02:05
修改一下发送子函数
/*------------------------------------------------
                 发送一个字节
------------------------------------------------*/
  void Send(unsigned char Data)
  {
   unsigned char BitCounter=8;
   unsigned char temp;
   do
    {
  temp=Data;
  Scl=0;
  if((temp&0x80)==0x80)
     Sda=1;
  else
     Sda=0;
  _nop_();_nop_();_nop_();_nop_();_nop_();
   Scl=1;
   temp=Data<<1;
   Data=temp;
   BitCounter--;
   }
   while(BitCounter);
       Scl=0;
   }
举报

杨秀英

2019-2-13 10:02:27
有个很奇怪的现象,比如我设定的温度,设定大于15就会飘到31,设定小于15就飘到15去了,但1~5却能正常保存
举报

李斌

2019-2-13 10:02:43
楼主再改一下应答和非应答的代码。
/*------------------------------------------------
                  应答IIC总线
------------------------------------------------*/
    void Ack(void)
    {
     Sda=0;
   mDelay(3);
   Scl=1;
   mDelay(3);
   Scl=0;
   mDelay(3);
Sda=1;
}

   
/*------------------------------------------------
                  非应答IIc
------------------------------------------------*/
void NoAck(void)
{
  Sda=1;
    mDelay(3);
    Scl=1;
    mDelay(3);
    Scl=0;
    mDelay(3);
Sda=0;
  }
举报

h1654155275.5748

2019-2-13 10:02:53
速率再调低点试试
举报

李俊

2019-2-13 10:03:12
速率调低点,IIC只有一个设备吗?
举报

杨秀英

2019-2-13 10:03:27
不止一个,还有DS1302时钟 LCD1602这些
举报

王斌

2019-2-13 10:04:26
先调时序,读出累死芯片id之类的固定寄存器来验证时序的正确性。模拟iic在前期可以通过逻辑分析仪来分析时序的正确性,没有逻辑分析仪只能自己分析。自己手写模拟iic一次正确感觉还是有点儿难度。
举报

李桂兰

2019-2-13 10:04:38
本人遇到过这种问题,是时序的问题!
后来调整时序解决了,你可以试试  高低电平,第几个边沿 可以取数,传一个 方波
别看别人代码 没有,自己试着调整!
  问题肯定是时序的问题!
    并且 就是取数的 第几个沿 有问题,或者 上升沿 取数,或者下降沿取数
举报

刘超

2019-2-13 10:04:48
这个问题应该是操作芯片时时序的问题;注意读过程中的延时最好是忙等待,不要被其他线程给中断
举报

王浩

2019-2-13 10:05:01
24c02读取与写入的时候,建议把延时调大,可以让数据完整的读取与写入。
举报

人中狼

2019-2-13 10:41:51
为什么没看到单片机对24c02的ACK或NAK的检查判断,记得这个是需要的。看24C02的手册,好像是有例程的。
另外IIC的时钟频率要降低,IIC只到400KHZ
举报

更多回帖

发帖
×
20
完善资料,
赚取积分