I am trying to implement bit-banging i2c to communicate between an atmega128A's GPIO and an SHT21 (I2C bus was used for some other devices). The first task is to send a write sequence to the SHT21. Using an oscilloscope, I can see that the sequence sending out from the atmega has the correct start signal, correct order of bits, correct stop signal, signal levels looks correct. The serial analyzer from the scope reads out correct I2C message: S80W~A (SHT21 address is 0x80, writing so last bit is 0). Yet there is not any ACK response from the SHT21. The SDA and SCL are both pulled up to 3.3V via 6.7K resistors.
I really need help finding out what is wrong.
code sending the first byte repeatly if no ACK receive:
i2c_start();
while(!i2c_send(0x80)){
i2c_stop();
i2c_start();
}
code of i2c protocol:
void i2c_start ()
{
// Pull data high and sck low to ensure transition of start sequence
DATA_HIGH ();
SCK_HIGH ();
DATA_LOW ();
SCK_LOW ();
}
void i2c_stop ()
{
DATA_LOW ();
SetBit (DDRD, 7);
//pull data high while clck is high to end transmission.
SCK_HIGH ();
DATA_HIGH ();
}
uchar i2c_send (uchar command)
{
uchar i;
for (i = 0; i < 8; i++) // Send command
{
if ((command & 0x80) == 0x80)
DATA_HIGH ();
else
DATA_LOW ();
SCK_LOW ();
SCK_HIGH ();
SCK_LOW ();
command = command << 1;
}
Delay(5);
ClrBit (DDRD, 7); // Change Data Direction
//SetBit (PORTD, 7); // Turn on internal pull-up
//SCK_LOW ();
SCK_HIGH ();
if (!CheckBit (PIND, 7)) // Read ACK
{
SCK_LOW ();
SetBit (DDRD, 7);
return 1;
}
else
{
SCK_LOW ();
SetBit (DDRD, 7);
return 0; // NO ACK
}
}