aizhixi106 发表于 2012-7-28 11:30:32

关于430操作EEPROM的问题 有点奇怪

调试一个430读写24C02,时序我是按照user guide 中要求写的,觉得时序是没有问题,
但是出现一个问题,在我写完控制位A0 有ACK 这个没有问题, 然后是地址为00,我也能写进去,同样有ACK,拉低SDA,也没有问题,
现象来了,就是在写数据的时候,却怎么也写不进去,表明没有应答信号,这一点,我很奇怪,问题在这:
(1)能写进去控制位A0有应答信号,证明SPI时序是没有问题的,然后是地址位00也有应答信号,更加证明我的SPI是正确的,不然不会有ACK,
   但是在写数据的时候却怎么也写不进去,我很奇怪,想不通?
(2)由于24C02只有8位地址,照理写进去控制位A0 然后地址位,应该没有问题,就能写数据了,但是我发数据,却没有应答信号,一直返回错。

程序模块如下:
I2CStart();
I2CSendByte(ControlByte&0xfe); //Only write
if(!WaitAck())
      continue;
I2CSendByte(Address);
if(!WaitAck())
      continue;
    if(!(ControlByte&0x01))         //write
    {
      errorflag=right;
      while(ByteQuantity--)
      {
      I2CSendByte(*DataBuffer++);
      if(WaitAck())               //enter next while loop
          continue;
      else
      {
          errorflag=error;         // no ack stop while
          break;
      }
      }
      if(errorflag==error)
      {
      continue;
      }
      else
      {
      break;                     //finsh write         
      
      }
    }

也就是在I2CSendByte(*DataBuffer++); 之后判断ACK  ACK返回1 表明有应答信号,返回0没有,但是我执行完发送数据后,却看点 SDA的电平
没有拉低,能解释下么?我看过数据手册中的说明,一直没有查到原因,但我知道,写不进去肯定SPI的时序有问题,但是就找不原因,因为控制位和地址能写
很奇怪~~~~
希望能有高手回答下~~~谢谢~~~

lcw_swust 发表于 2012-7-28 16:16:27

楼主“写进去控制位A0”是什么意思?
能不能看看“WaitAck()” 的代码?

aizhixi106 发表于 2012-7-28 16:54:07

lcw_swust 发表于 2012-7-28 16:16 static/image/common/back.gif
楼主“写进去控制位A0”是什么意思?
能不能看看“WaitAck()” 的代码?

感谢你的回帖,waitAck() 是可以进去的 A0 是24c02的控制字

lcw_swust 发表于 2012-7-28 16:56:25

aizhixi106 发表于 2012-7-28 16:54 static/image/common/back.gif
感谢你的回帖,waitAck() 是可以进去的 A0 是24c02的控制字

"waitAck() 是可以进去的"不代表这个函数没问题
“A0 是24c02的控制字”这是第一次听说

aizhixi106 发表于 2012-7-29 00:16:33

lcw_swust 发表于 2012-7-28 16:56 static/image/common/back.gif
"waitAck() 是可以进去的"不代表这个函数没问题
“A0 是24c02的控制字”这是第一次听说 ...

你好,我明白你的意思,A0是 1010 0000 这个是开始的控制位啊~~~24C02开始时候发送这个,然后会收到ACK ,SDA收到拉低电平,你说WiatAck()有问题
但是在我发送完地址位置后看到SDA 能被拉低。说明应该没有问题啊~~~如果有问题,说明在发送sda收不到拉低电平啊?
对么?

aizhixi106 发表于 2012-7-29 14:24:48

lcw_swust 发表于 2012-7-28 16:16 static/image/common/back.gif
楼主“写进去控制位A0”是什么意思?
能不能看看“WaitAck()” 的代码?

unsigned charWaitAck()
{
unsigned char errtime=255;
SDA1;
SomeNop();
SCL1;
SomeNop();
SDAIN;
while(SDA_STATE)
{
    errtime--;
    if(!errtime)
    {
      I2CStop();
      return NO;
    }
}
SDAOUT;
SCL0;

return OK;
}

这个是WaitAck的代码

lcw_swust 发表于 2012-7-29 15:25:25

看了楼主的程序,貌似没问题,下面是我写的程序,给楼主参考参考:
#define SLAW       0XA0
#define SLAR        0XA1

#define PWP_H        IOSET(P3,BIT(4))
#define PWP_L        IOCLR(P3,BIT(4))
#define PSCL_H        IOSET(P3,BIT(5))
#define PSCL_L        IOCLR(P3,BIT(5))
#define PSDA_H       IOSET(P3,BIT(6))
#define PSDA_L        IOCLR(P3,BIT(6))
#define PINSDA        (P3&BIT(6))
//------------------------------------------------
//IIC启始信号
//------------------------------------------------
void IICStart(void)
{
        PSCL_H;
        PSDA_H;
        delayus(1);
        PSDA_L;
        delayus(1);
        PSCL_L;
        delayus(1);
}
//------------------------------------------------
//IIC终止信号
//------------------------------------------------
void IICEnd(void)
{
        PSCL_L;
        PSDA_L;
        delayus(1);
        PSCL_H;
        delayus(1);
        PSDA_H;
        delayus(1);
}
//------------------------------------------------
//IIC回应
//------------------------------------------------
U8 IICACK(void)       reentrant
{
        U8 ret=0;
        PSDA_H;//放开数据线
        PSCL_H;
        delayus(1);
        if(PINSDA)ret=1;//读数据线
        PSCL_L;
        delayus(1);
        return ret;
}
//------------------------------------------------
//IIC发出一字节数据
//------------------------------------------------
void IICSendByte(U8 sdata)reentrant//Thigh,Tlow>2US 就行
{
        U8 i;
        for(i=0;i<8;i++)//之前PSCL=0;
        {
                if(sdata&0x80)
                        PSDA_H;
                else
                        PSDA_L;
                delayus(1);//NOP();        //delayus()
                PSCL_H;
                delayus(1);//NOP();       
                PSCL_L;
                sdata<<=1;//移位
        }
}
//------------------------------------------------
//IIC读取一字节数据
//------------------------------------------------
U8 IICReadByte(void)reentrant
{
        U8 ret,i;
        PSDA_H;
        for(i=0;i<8;i++)//之前PSCL=0;
        {
                ret<<=1;
                delayus(1);//NOP();
                PSCL_H;
                delayus(1);//NOP();
                if(PINSDA)ret|=1;
                PSCL_L;
        }
        return ret;
}
//------------------------------------------------
//IIC存入一字节
//addr:地址
//wdata:数据
//返回:第一个ACK,为0是正常的
//------------------------------------------------
U8 IICEEPW(U16 addr,U8 wdata)//写入24C01
{
        U8 pg;//页地址
        U8 ack;
        pg=addr>>8;
        IICStart();
        IICSendByte(SLAW|(pg<<1));
        ack=IICACK();
        IICSendByte(addr);
        IICACK();
        IICSendByte(wdata);
        IICACK();
        IICEnd();
        delayms(6);
        return ack;
}
//------------------------------------------------
//IIC读取一字节
//addr:地址
//rdata:返回读到的数据
//返回:第一个ACK,为0是正常的
//------------------------------------------------
U8 IICEEPR(U16 addr,U8 * rdata)reentrant//读一字节
{
        U8 ack,d;
        U8 pg;//页地址
        pg=addr>>8;
        IICStart();
        IICSendByte(SLAW|(pg<<1));
        ack=IICACK();
        IICSendByte(addr);//伪写操作
        IICACK();
       
        IICStart();
        IICSendByte(SLAR|(pg<<1));
        IICACK();
        d=IICReadByte();       
        IICACK();
        IICEnd();

        *rdata=d;
        return ack;
}

aizhixi106 发表于 2012-7-29 22:58:41

lcw_swust 发表于 2012-7-29 15:25 static/image/common/back.gif
看了楼主的程序,貌似没问题,下面是我写的程序,给楼主参考参考:
#define SLAW       0XA0
#define SLAR        0XA ...

我就发送的A0 然后地址 这样没有问题吧? 我看见的程序 怎么左移后右移 为什么不直接发送A0? 不理解 你为什么那么做?当然你的地址是16为的 为什么不给8位的? 而是要通过移位?

aizhixi106 发表于 2012-7-30 11:27:18

现在出现写偶数可以,写奇数,写不进去?好奇怪~~~
页: [1]
查看完整版本: 关于430操作EEPROM的问题 有点奇怪