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

2019-07-15 07:28发布

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

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


  6. sbit 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<Num;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<Num;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. }
复制代码

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
13条回答
ZQW发烧友
1楼-- · 2019-07-16 13:04
速率调低点,IIC只有一个设备吗?
罕井雅直
2楼-- · 2019-07-16 14:32
不止一个,还有DS1302时钟 LCD1602这些
bleupealike
3楼-- · 2019-07-16 19:32
先调时序,读出累死芯片id之类的固定寄存器来验证时序的正确性。模拟iic在前期可以通过逻辑分析仪来分析时序的正确性,没有逻辑分析仪只能自己分析。自己手写模拟iic一次正确感觉还是有点儿难度。
dfasda
4楼-- · 2019-07-16 20:32
本人遇到过这种问题,是时序的问题!
后来调整时序解决了,你可以试试  高低电平,第几个边沿 可以取数,传一个 方波
别看别人代码 没有,自己试着调整!
  问题肯定是时序的问题!
    并且 就是取数的 第几个沿 有问题,或者 上升沿 取数,或者下降沿取数
jenny042
5楼-- · 2019-07-16 23:46
 精彩回答 2  元偷偷看……
c1441424
6楼-- · 2019-07-17 01:41
24c02读取与写入的时候,建议把延时调大,可以让数据完整的读取与写入。

一周热门 更多>