Estoy tratando de implementar i2c de bit banging para comunicarse entre un GPIO de atmega128A y un SHT21 (el bus I2C se usó para algunos otros dispositivos). La primera tarea es enviar una secuencia de escritura al SHT21. Al usar un osciloscopio, puedo ver que la secuencia de envío desde la atmósfera tiene la señal de inicio correcta, el orden correcto de los bits, la señal de detención correcta y los niveles de señal parecen correctos. El analizador en serie del alcance lee el mensaje I2C correcto: S80W ~ A (la dirección SHT21 es 0x80, y el último bit es 0). Sin embargo, no hay ninguna respuesta ACK del SHT21. El SDA y el SCL se elevan a 3.3V a través de resistencias de 6.7K.
Realmente necesito ayuda para descubrir qué está mal.
El códigoenvía el primer byte repetidamente si no se recibe ACK:
i2c_start();
while(!i2c_send(0x80)){
i2c_stop();
i2c_start();
}
código del protocolo i2c:
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
}
}