¿Pueden los pines GPIO interferir entre sí?

5

Tengo un circuito simple donde bitbang I2C (SCL / SDA es GP5 / GP4) en una foto 12F629. Funciona perfectamente, todos los tiempos son correctos, no hay errores, etc. El esquema exacto es irrelevante porque deconstruí todo el circuito en bloques básicos y probé cada parte por separado para asegurar que el esclavo no tiene la culpa.

Tenga en cuenta que probé con diferentes chips y diferentes modelos y el problema persiste.

Ahora quiero conducir un pin aleatorio, digamos GP2 bajo. En el momento en que hago esto, la forma de onda I2C se vuelve loca. Aquí está la forma de onda después de bajar GP2 (SDA azul, SCL amarillo):

Después de algunos experimentos, aquí están mis conclusiones:

En I2C, los dispositivos solo pueden arrastrar o soltar SDA / SCL (en cuyo caso son arrastrados por las extensiones). Así que para designar ALTO configuramos el pin SDA o SCL en entrada y, por lo tanto, se libera y se eleva a + 5 V, y para designar BAJO, lo configuramos en salida y se maneja BAJO. Por supuesto, para que los niveles de SDA / SCL sean bajos al configurarlos para la salida, durante la inicialización del programa, estos dos pines se configuran primero en salida y se les asigna el valor BAJO, por lo que cada vez que cambian de entradas a salidas durante las comunicaciones i2c conducir automáticamente bajo.

Y la última parte es donde creo que se rompe todo.

Si después de algún punto, después de una comunicación i2c, conduzco un pin GPIO, por ejemplo. GP2 LOW o HIGH, esto afecta de alguna manera al valor GPIO de los OTROS pines gpio (es decir, SCL / SDA) que desordena todo. es decir. Los pines GPIO SDA / SCL se configuran en 1, por lo que cuando se cambian de entrada a salida durante las comunicaciones i2c, obtienen el valor 1 en lugar de 0 y, por lo tanto, en lugar de conducir el bus i2c BAJO, lo manejan en ALTO, lo que no está permitido . Y ahora la única manera de hacerlo funcionar de nuevo es:  1. Establezca la dirección SDA / SCL en TRISIO en SALIDA  2. Establezca el valor SDA / SCL en GPIO en 0  3. Vuelva a establecer la dirección SDA / SCL en la entrada para liberar el bus y dejar que se levante por los pullups.

Y ahora estamos listos para reanudar las comunicaciones. Hasta que saque otro GPIO alto o bajo, por supuesto, donde todo se atornilla nuevamente.

Ahora mi pregunta es esta: ¿Cómo se podría arreglar esto? ¿Podría ser esto un problema de lectura-modificación-escritura? Pensé que esto sería un problema común, estaba seguro de que habría mucha gente que utilizara i2c y un gpio pin a la vez y los interceptaría entre ellos, pero mis búsquedas no arrojaron resultados.

Tenga en cuenta que no hay nada conectado a la unidad de usuario que no sea el osciloscopio. Eliminé todo uno por uno para encontrar el problema y el problema aún persiste.

    
pregunta John

3 respuestas

23

Creo que he encontrado tu problema y (sé que no te va a gustar esto) un esquema preciso hubiera resaltado el problema para (al menos algunos) lectores de inmediato. :-)

Mirando el voltaje de inicio en los dos pines en sus dos trazas anteriores, ese voltaje es de alrededor de + 3.3V. Eso me dice que el PIC se alimenta de ese voltaje. Luego vemos que el voltaje aumenta a + 5V, cuando su código cambia los pines a las entradas y las resistencias de recuperación I²C toman el control.

Así que estás elevando las señales I²C a + 5V, pero el PIC se alimenta desde + 3.3V. Ese es el problema. Eso causará un flujo continuo de corriente a través de los "diodos de sujeción ESD" internos (normalmente no son diodos en estos días, pero esa es una historia diferente). Hay consecuencias por hacer eso (especialmente en corrientes más que mínimas), que incluyen afectar otras partes del PIC o incluso causar fallas debido a EOS, debido a que se está inyectando una corriente donde no debería estar.

Algunos de los síntomas en su pregunta de ayer: " Todo deja de funcionar después de habilitar PWM ": sugerí esta posibilidad, especialmente cuando informó que todo estaba bien cuando desarmó el circuito y lo reconstruyó (ya que, si no se ha hecho un daño permanente, los efectos de este problema a veces desaparecen cuando el poder es completamente eliminado). Sin embargo, sin un esquema no podría hacer una hipótesis con la que estuviera contento, ya que usted dijo que no había nada conectado al PIC, pero algo estaba conectado al PIC: las resistencias de extracción I²C a + 5V!

Luego, tu pregunta anterior de hoy: " ¿Mi pin GPIO está frito? "- pareció confirmar daños en el hardware. Ese podría seguir siendo cierto, y el daño (o el resultado temporal alternativo que estaba ocurriendo en su primera pregunta) encaja con esta hipótesis.

Esta hipótesis también explica completamente su nuevo comentario en esta pregunta:

  

Tenga en cuenta que probé con diferentes chips y diferentes modelos y el problema persiste.

Sí, todos los dispositivos similares se comportarían de manera similar, en esta situación de flexiones a un voltaje muy por encima de + Vdd.

En la hoja de datos PIC relevante (que descargaré en un minuto) mostrará que las "Condiciones de funcionamiento recomendadas" (en otras palabras, las condiciones en las que el chip debería funcionar ) son sin encontrarse con un chip alimentado por + 3.3V y entradas que reciban + 5V (a través de las resistencias pull-up I²C). Sin embargo, con los efectos limitantes de la corriente de esos pull-ups de I²C, podría tener suerte de que los efectos sean solo temporales, si no superó la Corriente de pinza máxima que se indica en "Máximos absolutos" sección.

La solución será ejecutar el bus I²C a la misma tensión que el propio PIC, no superior . Si lo requieren las restricciones impuestas por los esclavos I²C (cualquiera que sean), use traductores de nivel I²C para lograr un voltaje local I²C para el PIC, que cumple con esa regla.

[Espere una nueva edición más adelante, cuando pueda citar algunas cifras de la hoja de datos, solo para completarla.]

    
respondido por el SamGibson
1

Suena como si estuviera escribiendo en el puerto (ej. PORTA == Registro de valor de puerto para el puerto A) en lugar de los registros de latch (ej. LATA == Registro de latch de salida para el puerto A). El registro de puertos rastrea el valor actual de la entrada, el registro de retención mantiene su estado. Si intenta establecer / borrar un bit en un registro de puerto, los otros bits se configurarán / borrarán para que coincidan con su estado de entrada actual. Si establece / borra un bit en un registro de retención, solo la salida de ese bit se verá afectada.

Editar: de la hoja de especificaciones.

  

Leyendo el registro GPIO lee el estado de los pines, mientras que   escribiéndole escribirá al pestillo del puerto. Todas las operaciones de escritura son   Operaciones de lectura-modificación-escritura. Por lo tanto, una escritura a un puerto implica   que los pines del puerto se leen, este valor se modifica y luego se escribe   al puerto de datos de cierre. GP3 lee "0" cuando MCLREN = 1.

Parece que esta serie PIC de hecho omite los registros LATCH como usted ha comentado. Una solución alternativa simple (no la solución más limpia, pero funcionaría) es utilizar una variable global para hacer el seguimiento de estado manualmente por usted. Simplemente modifique un poco este global y luego copie todo al registro de puerto (GPIO en esta serie).

    
respondido por el Mathieu L.
-3
  

esto de alguna manera afecta el valor GPIO de OTHER gpio pins (SCL / SDA) que desordena todo.

que solo puede ocurrir en un sistema donde el software está mal diseñado.

  

Ahora mi pregunta es la siguiente: ¿cómo podría uno solucionar este problema?

escribe el código apropiado para que no suceda.

antes de eso, restablezca el registro de datos de salida del pin a su estado adecuado antes de cambiando su registro de dirección de salida.

    
respondido por el dannyf

Lea otras preguntas en las etiquetas