¿Cuándo libera y vuelve a adquirir el control sobre SDA en torno a un i2c Ack?

3

Tengo un comportamiento extraño con la biblioteca Wire de Energia, así que pensé que intentaría hacerlo yo mismo.

Estoy escribiendo mi propia implementación (bit-bang) si i2c y lo mantengo bastante simple. Por ahora, solo quiero detectar un dispositivo i2c en particular. Aquí está mi algoritmo básico.

  1. Comience el mensaje conduciendo SDA de alto a bajo, mientras que SCL se mantiene alto.
  2. Envíe la dirección de 7 bits un bit a la vez llevando el SDA a alto o bajo, mientras que SCL es bajo y luego cambie SCL a alto para que el dispositivo esclavo lea cada bit.
  3. Envía 1 bit de escritura o lectura.
  4. Recibe Ack del esclavo.
  5. Termine el mensaje llevando el SDA de bajo a alto, mientras que SCL se mantiene alto.

Sé que lo anterior puede estar un poco simplificado, pero solo quería poner las cosas en contexto. Tengo problemas con el paso 4 y conozco el momento concreto en el momento de liberar y recuperar el control de la línea SDA durante un Ack.

Entonces, después de que el último bit de lectura / escritura se haya configurado en SDA y el SCL esté en ALTO, necesito saber cuál es el orden de las operaciones para obtener un Ack del esclavo.

He intentado todas las combinaciones que se me ocurren, pero no parece funcionar correctamente. Parece que debería hacer lo siguiente:

setMode(SDA, INPUT);                //Release the SDA line to the slave device
digitalWrite(SCL,LOW);              //Pulse the SCL line
digitalWrite(SCL,HIGH);
int ack = digitalRead(SDA) == LOW;  //Read from the SDA line
setMode(SDA, OUTPUT);               //Seize control of the SDA line

La secuencia anterior no parece estar funcionando. Mi analizador digital no reconoce mis comunicaciones como debería.

Cualquier corrección en mis suposiciones o ajustes al código anterior sería de gran ayuda.

Para mayor aclaración:

Estoy usando un entorno de desarrollo llamado 'Energia'. Es una bifurcación de Arduino y se utiliza para "simplificar" el proceso de programación de los procesadores TI MSP430x. De todos modos, parece que no tiene ningún concepto de modo 'OpenCollector'.

Es Input, Output o Input_Pullup. Me pregunto si Input_Pullup no es su versión del modo OpenCollector. Intentaré eso. Aquí hay una interesante discusión de Input, Output, Input_Pullup:

Constantes de energía

    
pregunta Curtis

2 respuestas

2

La mayor parte de su problema probablemente se deba al hecho de que está configurando estas líneas en alto en lugar de dejarlas flotar. SDA y SCL van a alto porque hay una resistencia que los empuja hasta + V, no porque sean elevados. Muchas personas no se dan cuenta de que la línea del reloj también está diseñada para funcionar de esta manera.

Hay algo más en la forma en que describe su lógica que me hace pensar que mientras ve una transición de SCL a baja como el evento que retiene los datos, parece pensar que luego vuelve a poner de alta la SCL. Te animo a que pienses en el evento del reloj de esta manera:

  • configurar los datos
  • levanta el reloj
  • espere un tiempo de bit apropiado
  • baja el reloj

De la forma en que lo estás haciendo, puedes tener problemas de la siguiente manera:

  • usted escribe SDA, digamos que es bajo.
  • subes el reloj, por lo que SCL ahora es alto
  • liberas SDA porque quieres leerlo.
  • SDA va alto si no hay ACK presente

¡Sorpresa! Acaba de crear una condición de PARADA sin darse cuenta.

    
respondido por el gbarry
1

Cada vez que se transmite un bit, el escritor controla SDA (o no) inmediatamente después de que SCL baja, y el lector lee el estado de SDA cuando SCL pasa a nivel alto. (El esclavo puede demorar el SCL al subir de nivel con el alargamiento del reloj; hay que esperar a que el SCL se ponga alto).

Su código debe pulsar SCL durante el tiempo suficiente para que el esclavo tenga tiempo suficiente para establecer el valor (al menos 4.7 µs).

Cambiar SDA al modo de salida podría reducirlo si ese fuera el último valor anterior. Esto no está permitido mientras SCL es alto (a menos que realmente desee hacer un inicio repetido).

    
respondido por el CL.

Lea otras preguntas en las etiquetas