HammingNg 发表于 2009-2-19 15:24:20

有谁做过I2C

利用NEC单片机(78F0513)对AT24C02进行写数据,例如对AT24C02中的0x02地址写入数据0x20,再对该地址读取数据,是否为0x20
我是菜鸟,谁能分享例子菜鸟贴呢?

dongdaxing 发表于 2009-2-19 20:17:08

可以用模拟i2c来做

io端口属性设置一下

llxf 发表于 2009-2-21 22:25:57

....三言两语还真不好说。先看看AT24C02的和I2C的工作原理,再去网上搜一段I2C读写E2PROM的源代码,很容易理解。

archeng504 发表于 2009-2-22 11:23:41

给你参考一下,适用24c02 24c01A
#define SDA             P2.1
#define SDA_DIR         PM2.1
#define SCL             P4.2

//port direction
#define INPUT         1
#define OUTPUT          0

//for AT2402 write or read command
#define W_ADD_COM       0xA0    //1010 A2 A1 A0   0
#define R_ADD_COM       0xA1    //1010 A2 A1 A0   1
//the first address of data writed to 2402
#define RomAddress      0x02

//-----------------------------------------------------------------------------
// Function: I2C operation for at2402
//
//
//
//-----------------------------------------------------------------------------
//start I2C
void I2CStart(void)
{
    SCL = 0;
    SDA = 1;
    SCL = 1;
    NOP();NOP();
    SDA = 0;
    NOP();NOP();
    SCL = 0;
}
//stop I2C
void I2CStop(void)
{
    SDA = 0;
    SCL = 1;
    NOP();
    NOP();
    SDA = 1;
}
//ask
void I2CAck(void)
{
    SDA = 0;
    SCL = 1;
    NOP();
    NOP();
    SCL = 0;
    SDA = 1;
}
//noack
void I2CNoAck(void)
{
    SDA = 1;
    SCL = 1;
    NOP();
    NOP();
    SCL = 0;
}

char I2CTestAck(void)
{
    char ErrorBit;

    SDA = 1;
    SDA_DIR = INPUT;      //change SDA direction to input
    SCL = 1;
    NOP();NOP();
    NOP();NOP();
    NOP();NOP();
    ErrorBit = SDA;         // 0 is ask; 1 is noack
    SCL = 0;
    SDA_DIR = OUTPUT;       //change SDA direction to output
    return(ErrorBit);
}

/* write one byte to I2C */
void I2CWrite8Bit(unsigned char data)
{
    unsigned char i;
    SDA_DIR = OUTPUT;   //change SDA direction to output
    //SCL must is low level

    for(i = 8; i != 0; i--)
    {
      if(data & 0x80)
      {
            SDA = 1;
      }
      else
      {
            SDA = 0;
      }
      SCL = 1;
      data = data << 1;
      SCL = 0;
    }
}

/* read one byte fromI2C */
unsigned char I2CRead8Bit(void)
{
    unsigned char i, rbyte = 0;
    SDA_DIR = INPUT;      //change SDA direction to input

    for(i = 8; i != 0; i--)
    {
      SCL = 1;
      rbyte = rbyte << 1;
      if(SDA)
      {
            rbyte |= 0x01;
      }
      else
      {
            rbyte |= 0x00;
      }
      SCL = 0;
    }
    SDA_DIR = OUTPUT;   //change SDA direction to output
    return(rbyte);
}

void write2402(void)
{
    I2CStart();               //start
    I2CWrite8Bit(W_ADD_COM);    //write the address of AT2401a
    if(I2CTestAck() == 1)goto i2cerror;

    I2CWrite8Bit(RomAddress);
    if(I2CTestAck() == 1)goto i2cerror;

    I2CWrite8Bit(67);
    if(I2CTestAck() == 1)goto i2cerror;

    I2CWrite8Bit(12);
    if(I2CTestAck() == 1)goto i2cerror;

    I2CWrite8Bit(134);
    if(I2CTestAck() == 1)goto i2cerror;

    I2CWrite8Bit(12);
    if(I2CTestAck() == 1)goto i2cerror;

    I2CStop();
    Delay10us(1000);
    return;

i2cerror:
    I2CStop();
}

void Read24c02(unsigned char *RamAddress, unsigned char bytes)
{
    I2CStart();
    I2CWrite8Bit(W_ADD_COM);
    if(I2CTestAck() == 1)goto i2cend;

    I2CWrite8Bit(RomAddress);
    if(I2CTestAck() == 1)goto i2cend;

    I2CStart();
    I2CWrite8Bit(R_ADD_COM);
    if(I2CTestAck() == 1)goto i2cend;

    while(bytes != 0)
    {
      *RamAddress = I2CRead8Bit();
      I2CAck();       //
      RamAddress++;
      bytes--;
    }
    *RamAddress = I2CRead8Bit();
    I2CNoAck();         //

i2cend:
    I2CStop();          //
}

HammingNg 发表于 2009-2-24 12:11:15

谢谢楼上的例子,让我受益不少

bg7fw 发表于 2009-3-5 22:39:23

当你作了一次写操作以后地址会自动增加的
页: [1]
查看完整版本: 有谁做过I2C