Vielleicht hilft das, war für ein ATmega161:
#define READ 0x01 // I2C READ bit
#define SCLPORT PORTE
#define SDAPORT PORTD
#define SCL PE2
#define SDA PD2
#define QDEL delay(5)
#define HDEL delay(10)
#define I2C_SDL_LO cbi( SDAPORT, SDA)
#define I2C_SDL_HI sbi( SDAPORT, SDA)
#define I2C_SCL_LO cbi( SCLPORT, SCL);
#define I2C_SCL_HI sbi( SCLPORT, SCL);
void i2ct(void)
{
HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO;
}
void i2cstart(void)
{
I2C_SDL_LO; QDEL; I2C_SCL_LO;
}
void i2cstop(void)
{
HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL;
}
#define I2C_SCL_TOGGLE i2ct();
#define I2C_START i2cstart();
#define I2C_STOP i2cstop();
u16 i2c_putbyte(u08 b)
{
s16 i;
for (i=7;i>=0;i--)
{
if ( b & (1<<i) )
I2C_SDL_HI;
else
I2C_SDL_LO; // address bit
I2C_SCL_TOGGLE; // clock HI, delay, then LO
}
I2C_SDL_HI; // leave SDL HI
// added
cbi(SDAPORT-1, SDA); // change direction to input on SDA line
(may
not be needed)
HDEL;
I2C_SCL_HI; // clock back up
b = inp(SDAPORT-2) & (1<<SDA); // get the ACK bit
HDEL;
I2C_SCL_LO; // not really ??
sbi(SDAPORT-1, SDA); // change direction back to output
HDEL;
//printf("put: %x\r\n",b);
return (b == 0); // return ACK value
}
u08 i2c_getbyte(u16 last)
{
s16 i;
u08 b = 0;
u08 c = 0;
I2C_SDL_HI; // make sure pullups are ativated
cbi(DDRD, SDA); // change direction to input on SDA line (may not
be
needed)
for (i=7;i>=0;i--)
{
HDEL;
I2C_SCL_HI; // clock HI
c = bit_is_set(SDAPORT-2, SDA);
b <<= 1;
if (c)
b |= 1;
HDEL;
I2C_SCL_LO; // clock LO
}
sbi(DDRD, SDA); // change direction to output on SDA line
if (last)
I2C_SDL_HI; // set NAK
else
I2C_SDL_LO; // set ACK
I2C_SCL_TOGGLE; // clock pulse
I2C_SDL_HI; // leave with SDL HI
return b; // return received byte
}