Посмотрел вышеупомянутый драйвер i2c.. Там что-то сильно сложно все imho, возможно в этом и причина. Задержка i2c делается там каким-то странным образом.
Наскоро сделал пример, проверил с имеющейся под рукой AT24C512:
Код
#define U8 unsigned char
#define i2cRead 1
#define i2cWrite 0
#define ACK 0 // continue receiving
#define NACK 1 // end of receiving
#define i2c_processing (!( TWCR & (1 << TWINT)))
void I2C_hw_init(void)
{
TWDR = 0;
TWAR = 0;
TWSR = 0; // setting prescaler to 1
TWBR = 12; // Baud Rate = Fosc / (16 + 2*(TWBR)*4^TWPS,
// при Fosc=11.059 и TWBR = 12, Baud Rate ~ 100Khz
TWCR = (1 << TWEN);
}
void I2C_hw_start(void)
{
TWCR = (1 << TWEN)|(1 << TWSTA)|(1 << TWINT);
while (i2c_processing)
__delay_cycles(1);
}
void I2C_hw_stop(void)
{
TWCR = (1 << TWEN)|(1 << TWSTO)|(1 << TWINT);
}
U8 I2C_hw_send(U8 value)
{
TWDR = value;
TWCR = (1 << TWEN)|(1 << TWINT);
while (i2c_processing)
__delay_cycles(1);
return TWSR;
}
U8 I2C_hw_rec(U8 TransferStatus)
{
if (TransferStatus == ACK)
TWCR = (1 << TWEN)|(1 << TWEA)|(1 << TWINT);
else
TWCR = (1 << TWEN)|(1 << TWINT);
while (i2c_processing)
__delay_cycles(1);
return TWDR;
}
inline U8 I2C_hw_SetAddressDir(U8 Address, U8 dir)
{
return I2C_hw_send( (Address & 0xFE) | (dir != 0) );
}
Пример применения:
Код
int main( void )
{ // Test AT24C512
volatile U8 i2c_data;
// Hardware test
I2C_hw_init();
I2C_hw_start();
I2C_hw_SetAddressDir( 0xA0, i2cWrite ); // <-- AT24
I2C_hw_send( 0x00 );
I2C_hw_send( 0x26 );
I2C_hw_start();
I2C_hw_SetAddressDir( 0xA0, i2cRead );
i2c_data = I2C_hw_rec( ACK );
i2c_data = I2C_hw_rec( ACK );
i2c_data = I2C_hw_rec( NACK );
I2C_hw_stop();
for(;;);
}
Удачи