实在搞不定了,求助高手 指出CC530读取24C02中的BUG

2020-01-21 21:46发布

本帖最后由 lixin91985 于 2014-11-1 17:06 编辑

本来是认为是一个很简单的事情。

IO模拟IIC,使用了不知道多少次。花了整整两天时间,参考了不知道多少个以前成功的程序。。。。。还是没有成功

硬件 外部上拉,有试过1k,4,7k 10k。

IC没有问题,因为焊接到STM32上面测试过。。
写入之间的延时有调整过。
测试过多个PCB。排除焊接问题。
用示波器观察,IO有电平输出。逻辑眼观是正确的。

现象:能读出来,,先这么认为吧。


10个数据,第一个能正常写入,每隔两个能正常一个。

#define SCL_H         (P1_3=1)
#define SCL_L          (P1_3=0)
   
#define SDA_H         (P1_2=1)
#define SDA_L          (P1_2=0)

//#define SCL_read      (P1_3)
#define SDA_Out   (P1DIR|=(1<<2))
#define SDA_In     (P1DIR&=~(1<<2))
#define SDA_read      (P1_2)

、、----------------------------------------------------下面是程序--------------------------------------------------------------
void EEPROM_HAL_Init(void)
{
// P0DIR|=((1<<6)|(1<<7));
//P1_0=0;P0_6=0;P0_7=0;
//-------------------------------------
SDA_H;SCL_H;
P1DIR|=((1<<3)|(1<<2));// CLK pin is output
// P1INP&=~((1<<3)|(1<<2));
P1SEL&=~((1<<3)|(1<<2));

  EE_Delay_ms(100);
I2C_Test();
}


void I2C_delay(void)
{       
   uint8 i=20; //这里可以优化速度        ,经测试最低到5还能写入
   while(i)
   {
     i--;
   }
}

void delayus(uint8 time)
{       
   while(time)
   {
     time--;//nop();
   }
}
bool I2C_Start(void)
{
   
    SDA_Out;
   
    SDA_H;
    SCL_H;
    delayus(5);
    SDA_L;
    delayus(5);
    SCL_L;    //拉低
    delayus(5);   return TRUE;
}

void I2C_Stop(void)
{
    SDA_Out;
   
    SDA_L;
    SCL_H;
    delayus(5);
    SDA_H;
    delayus(5);   
    SCL_L;
    delayus(250);delayus(50);
}

void I2C_Ack(void)
{       
   SCL_L;I2C_delay();
   SDA_Out;SDA_L;
   I2C_delay();
   SCL_H;
   I2C_delay();
   SCL_L;
   I2C_delay();
}

void I2C_NoAck(void)
{       
    SDA_Out;
   
    SCL_H;
    SDA_H;
    delayus(5);
    SCL_L;
    SDA_L;
    delayus(5);
}

bool I2C_WaitAck(void)          //返回为:=1有ACK,=0无ACK
{uint8 cnt=255;
  //SCL_L;
  //I2C_delay();
  SDA_Out;
  SDA_H;       
  SCL_H;
     I2C_delay();
  SDA_In;
  //I2C_delay();
  while(SDA_read&&cnt) cnt--;
  if(cnt==0)
     { SCL_L;//I2C_delay();
           return FALSE;
     }
  SCL_L;//SDA_Out;
  return TRUE;
}

void I2C_SendByte(uint8 SendByte) //数据从高位到低位//
{
    uint8 i,temp;
       
    SDA_Out;
    for(i = 0;i < 8;i ++)
    {
        temp = SendByte & 0x80;
        if(temp)
            SDA_H;
        else
            SDA_L;
        SCL_H;
        delayus(5);
        SCL_L;
        delayus(5);
        SendByte <<= 1;
    }
}

uint8 I2C_ReceiveByte(void)  //数据从高位到低位//
{
    uint8 i,temp;
       
    SDA_In;
    for(i = 0;i < 8;i ++)
    {
        temp <<= 1;
        SCL_H;
        delayus(5);
        if(SDA_read)
        {
            temp |= 1;
        }
        SCL_L;
        delayus(5);
    }
    return temp;
}

void EE_Delay_ms(uint16 Count)
{uint16 i;
   uint8 J;
  for(;Count>0;Count--)
          {for(i=0;i<0x4fff;i++) J++;
     }
}


//写入1字节数据       待写入数据    待写入地址       器件类型(24c16或SD2403)
bool I2C_WriteByte(uint8 SendByte, uint16 WriteAddress, uint8 DeviceAddress)
{               
    I2C_Start();
    I2C_SendByte(0xa0);//((WriteAddress & 0x0700) >>7) | DeviceAddress & 0xFFFE);//设置高起始地址+器件地址
    I2C_WaitAck();
    I2C_SendByte(WriteAddress);//& 0x00FF));   //设置低起始地址      
    I2C_WaitAck();       
    I2C_SendByte(SendByte);
    I2C_WaitAck();   
    I2C_Stop();
        //注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms)
    EE_Delay_ms(10);///EE_Delay_ms(1000);
    return TRUE;
}

//读出1串数据         存放读出数据  待读出长度      待读出地址       器件类型(24c16或SD2403)       
bool I2C_ReadByte(uint8* pBuffer,   uint8 length,     uint16 ReadAddress)
{
while(length--)
  {
   *pBuffer=I2C_ReadChar(ReadAddress);
   pBuffer++;ReadAddress++;
   EE_Delay_ms(5);
  }
return TRUE;

}


uint8 I2C_ReadChar(uint8 addr)
{
  uint8 temp;

  I2C_Start();
  I2C_SendByte(0xa0);
  I2C_WaitAck();
  I2C_SendByte(addr);
  I2C_WaitAck();
  I2C_Start();
  I2C_SendByte(0xa0 +0x01);
  I2C_WaitAck();
  temp=I2C_ReceiveByte();
  I2C_NoAck();
  I2C_Stop();
  return temp;

}


void I2C_ReadS_24C(uint16 addr ,uint8* pBuffer,uint16 no)
{I2C_ReadByte(pBuffer,(uint8)no,addr);
}

void I2C_WriteS_24C(uint16 addr,uint8* pBuffer,  uint16 no)
{
while(no)
  {I2C_WriteByte(*pBuffer,addr,EEPROM_ADDR);// I2C_WriteByte(u8 SendByte, u16 WriteAddress, u8 DeviceAddress)
   pBuffer++;addr++;
   no--;
   //Delay_ns(20);
  }
/*
  HAL_ENTER_ISR();
  I2C_Start();
  I2C_SendByte(0xa0);//((addr & 0x0700) >>7) | EEPROM_ADDR& 0xFFFE);//设置高起始地址+器件地址
  I2C_WaitAck();
  I2C_SendByte((uint8)(addr& 0x00FF));   //设置低起始地址      
  I2C_WaitAck();
  while(no--)
          {I2C_SendByte(*pBuffer);pBuffer++;
         I2C_WaitAck();
          }
  I2C_Stop();
  HAL_EXIT_ISR();*/
}




void I2C_ByteWrite_24C(uint16 addr,uint8 dat)
{I2C_WriteByte(dat,addr,EEPROM_ADDR);
}


//测试用
void I2C_Test(void)
{
        uint8 i;
        uint8 I2c_Buf[30];
        //I2C_Standby_24C();
        //填充缓冲
        for(i=0;i<20;i++)
                I2c_Buf=i+0x70;
        //写
        I2C_WriteS_24C(10,I2c_Buf,20);EE_Delay_ms(100);
        I2C_WriteByte(0x41,31,EEPROM_ADDR);
        I2C_WriteByte(0x42,32,EEPROM_ADDR);
        I2C_WriteByte(0x43,33,EEPROM_ADDR);
        //清缓冲
        for(i=0;i<20;i++)
                I2c_Buf=0;
        //读
        EE_Delay_ms(100);
        I2C_ReadS_24C(10,I2c_Buf,30);
        EE_Delay_ms(100);
}


、、--------------------------
混论坛这么久,一直都不敢让坛友看这么长的程序。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
3条回答
dzymushi
2020-01-21 23:49
void IIC_WriteByte(unsigned int Addr,unsigned char Data)
{
    uint16 i;
        IIC_Start();
        IIC_Send(0xa0|((Addr/256)<<1));
        IIC_Send(Addr%256);
        IIC_Send(Data);
        IIC_Stop();
    for(i=0;i<5000;i++);        //这个时间很重要               
}
这个是我一直用的写字节的代码,是不是延时不足?
24C02硬件地址三根线需要接,是不是地址不对?

一周热门 更多>