一个关于I2C(E2PROM 24C02C)的奇怪问题,值得一看


一个简单的关于I2C(E2PROM 24C02C)的仿真程序,电路图如下:


i2c.JPG


代码如下:
#include<regx52.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define WriteDeviceAddress 0xa0
#define ReadDeviceAddress 0xa1
sbit SCL=P2^6;
sbit SDA=P2^7;

void DelayMs(unsigned int number)
{
unsigned char temp;
for(;number>=1;number--)
{
  for(temp=112;temp>=1;temp--) ;
}
}
void i2cStart(void)
{
  SDA=1;
  SCL=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  SDA=0;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  SCL=0;
}
void i2cStop(void)
{
  SDA=0;
  SCL=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  SDA=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}
void i2cWrite8Bit(unsigned char input)
{
  unsigned char temp;
  for(temp=8;temp!=0;temp--)
  {
    SDA=(bit)(input&0x80);
    SCL=1;
_nop_();
    _nop_();
    _nop_();
_nop_();
    _nop_();
SCL=0;
input=input<<1;
  }
  DelayMs(20);
}
unsigned char i2cRead8Bit(void)
{
  unsigned char temp,rbyte=0;
  for(temp=8;temp!=0;temp--)
  {
    SCL=1;
_nop_();
    _nop_();
    _nop_();
rbyte=rbyte<<1;
rbyte=rbyte|((unsigned char)(SDA));
SCL=0;
  }
  return(rbyte);
}
void i2cAck(void)
{
  SDA=0;
  SCL=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  SDA=1;
  SCL=0;
}
void i2cNoAck(void)
{
  SDA=1;
  SCL=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  SDA=0;
  SCL=0;
}
void i2cWrite24LC16B(unsigned char wdata,unsigned char RomAddress)
{
  i2cStart();
  i2cWrite8Bit(WriteDeviceAddress);
  i2cAck();
  i2cWrite8Bit(RomAddress);
  i2cAck();
  i2cWrite8Bit(wdata);
  i2cAck();
  i2cStop();
  DelayMs(20);
}
unsigned char i2cRead24LC16B(unsigned char RomAddress)
{
  unsigned char x;
  i2cStart();
  i2cWrite8Bit(WriteDeviceAddress);
  i2cAck();
  i2cWrite8Bit(RomAddress);
  i2cAck();
  i2cStart();
  i2cWrite8Bit(ReadDeviceAddress);
  i2cAck();
  _nop_();
  _nop_();
  _nop_();
  x=0;
  x=i2cRead8Bit();
  i2cNoAck();
  i2cStop();
  return(x);
}
void main(void)
{
  //unsigned char output;
  i2cWrite24LC16B(0x88,0x00);
  P1=i2cRead24LC16B(0x00);
//output=i2cRead24LC16B(0x00);
}

该程序是在24C02C的0x00地址处写入0x88,并将该值读出,通过数码管显示。结果如上图所示,该程序应该是正确的。但是,
问题一:如果在电路图中加入示波器后,数码管显示结果就非常奇怪了。如下图:


i2c_.JPG


问题二:不添加示波器时,数码管显示正确。但是执行下列代码
unsigned char output;
output=i2cRead24LC16B(0x00);
output始终输出为ff,为什么?按道理应该是output=0x88才对啊?百思不得其解。
请教大家了,多谢。附件有仿真电路图。

i2c.rar
(2008-07-14 21:16:35, Size: 13.5 KB, Downloads: 6)


我也来说两句 查看全部回复

最新回复

  • leotron (2008-7-14 21:20:42)

    如果大家有兴趣,可以运行一下这个仿真例子,还望大家不吝赐教。
  • bonjour (2008-7-14 22:34:08)

    下载看看是为什么
  • ybzjllj (2008-7-15 06:49:07)

    下下来帮你看看.                                                 .
  • ybzjllj (2008-7-15 07:08:26)

    我用你的程序,画一个相同的电路,测试完全正常啊........................

    只是你的主函数里没有主循环哟!!!!!!!!!!!!!!!!!!!!

    CODE:


    void main(void)
    {
    unsigned char output;
    while(1){
      i2cWrite24LC16B(0x88,0x00);
      //P1=i2cRead24LC16B(0x00);
      output=i2cRead24LC16B(0x00);
      P1=output;
    }
    }


    完全正常.JPG

  • leotron (2008-7-15 21:02:34)

    To ybzjllj,先谢谢你。这就怪了,请问:
    1. 你proteus版本是?能否把你仿真的DSN文件传给我,zuoshh23@163.com
    2. 运行这段代码
    void main(void)
    {
    unsigned char output;
    while(1){
      i2cWrite24LC16B(0x88,0x00);
      output=i2cRead24LC16B(0x00);
      }
    }
    变量output是多少?在我的电脑上output=ffH,不对吧?!
  • ybzjllj (2008-7-15 21:26:35)

    我又用如下代码测试,交替显示AA,55,完全正确.

    CODE:


    void main(void)
    {
    i2cWrite24LC16B(0x55,0x00);
    DelayMs(1);
    i2cWrite24LC16B(0xaa,0x01);
    DelayMs(1);
    while(1){
      P1=i2cRead24LC16B(0x00);
      DelayMs(1000);
      P1=i2cRead24LC16B(0x01);
      DelayMs(1000);
    }
    }
  • ybzjllj (2008-7-15 21:30:31)

    Proteus v7.2SP6                                                                                                            .
  • leotron (2008-7-17 09:28:21)

    多谢ybzjllj的软件,在v7.2 SP6上我也测试正确。现在基本确定v7.1 SP2在这个地方存在bug.另外,还得请教ybzjllj及各位,我现在想将24C02C里的值读出来赋给一变量,如output,为什么总不能实现了,一直是output=ffH。大家帮忙试一下。谢谢。
  • zswlove (2008-7-30 22:11:14)

    看看呀,学习学习
    看看呀,学习学习看看呀,学习学习
  • zswlove (2008-7-30 22:15:16)

    看看呀,学习学习看看呀,学习学习看看呀,学习学习看看呀,学习学习
  • sac_meTeor (2008-8-07 17:43:48)

    我看一下
    看看呀,学习学习看看呀,学习学习看看呀,学习学习看看呀,学习学习
  • sac_meTeor (2008-8-07 17:44:35)

    看看呀,学习学习看看呀,学习学习看看呀,学习学习看看呀,学习学习
  • sac_meTeor (2008-8-07 17:47:22)

    看看呀,学习学习看看呀,学习学习看看呀,学习学习看看呀,学习学习
  • chenzk (2008-8-07 18:30:23)

    不好意思,借用下帖子。。。
    为什么我发不了新贴啊????
    我做了个0832的仿真,但是P0口作为数据端,传给0832,居然传不过去?把0832的WR(两个WR是连在一起的),改接到51的WR端(原来是接在P2。6),数据就传过去了,可结果却不对?请教高手解决!谢谢!不知道回复里怎么加附件。