Problema al escribir en los registros del Expander de E / S MCP23017 (i2c)

2

Estoy creando un dispositivo de prueba de cable básico y estoy usando I2C para interactuar con dos chips de expansión de E / S MCP23017.

En mi código, cada esclavo MCP23017 tiene su propia dirección y puedo comunicarme con ambos adecuadamente a través de I2C.

La idea es que ambos extremos de un "cable" se coloquen en los dos enchufes. Actualmente lo he programado para que funcione con solo 8 cables (usando solo GPA7-GPA0 en ambos chips). Básicamente, la idea es que se enviará un pulso alto lógico individualmente en cada cable (bucle 8 veces) desde el primer chip MCP23017 (pines configurados como salida y es esclavo 1) y recibido por el segundo chip MCP23017 (pines configurados como entrada y Esclavo 2). Ahora los LED se iluminan perfectamente, lo que indica que la conexión existe, sin embargo no puedo hacer que escriba en los registros del Esclavo 2.

Estoy escribiendo en los primeros chips OLATA y leyendo del segundo registro GPIOA de chips (Slave 2). Entonces, si OLATA está alto en GPA7 (primer chip), deseo leer el pin GPIOA GPA7 en el segundo chip. A través de estas lecturas, puedo realizar operaciones bitwise para determinar los tipos de cable, etc.

Mi problema es que, a pesar de que todos los LEDS se iluminan como se esperaba, no se está escribiendo nada en el segundo chip de expansión de E / S (la parte inferior). Esto no es bueno para mí, ya que necesito que se produzcan escrituras de datos en los registros para que pueda leer el valor en estos registros para realizar operaciones. El código I2C relevante para el expansor de E / S se proporciona a continuación, estas tres funciones se ejecutan cada una 8 veces en el orden mostrado, una para cada pin GPAx:

enlace

Ahora el problema es que no se está escribiendo nada en la variable ReadPin, está vacío para los 8 pines GPAx en el Esclavo 2 (el chip de expansión de E / S más abajo). También el valor de uint8_t es 1 <

¿Alguna idea? Por favor ayude, ya que este es el único problema principal que tengo que me impide continuar con la escritura de otra lógica de programa.

¡Gracias!

PS: FYI ninguno de mis pines de interrupción en ambos chips MCP23017 está conectado a nada y los pines de restablecimiento están conectados a VCC. Además, los pines GPAx que están configurados como entradas en el segundo esclavo no tienen resistencias conectadas a ellos. Solo el pin y luego el LED a GND.

EDITAR: Esquema: (haga clic con el botón derecho para ver a tamaño completo)

enlace

También sí, sé que en el Esquema no hay conexión GND en VSS para el Esclavo 1, pero tenga en cuenta que tengo mi configuración actual en un protoboard con todas las conexiones, que la conexión VSS está correctamente conectada.

    
pregunta JackSparrow123

1 respuesta

1

Bien, puedo ver los cambios.

Como se muestra ahora, los LED en el IC receptor bloquearán los datos a alta velocidad a medida que se invierten. Los LEDs en el lado de transmisión tampoco son una buena idea. Si desea LEDs, debe colocarlos desde la línea de datos a tierra a través de una resistencia, no en serie con la conexión a la toma de cable.

Acabo de ver tu foto: parece que has eliminado los LED, bien (estaba a punto de sugerir esto ... :-))
Así que ahora parece que tienes conexiones directas de IC1 a IC2. Si este es el caso, entonces si el código (parece razonable de un vistazo) y el cableado del IC son correctos, entonces debería funcionar.

Si puede confirmar con un multímetro que los pines de entrada están viendo un voltaje alto (o bajo) y el valor de lectura es diferente, esto confirmaría que el problema es uno u otro de los anteriores. Tal vez solo aplique un voltaje conocido directamente y vea si puede leerlo bien)

Sin embargo, si está leyendo valores diferentes cuando las activaciones están activadas / desactivadas, parecerá para indicar que la lectura es correcta. Intente leer un voltaje directo y publicar resultados, solo estoy revisando la hoja de datos de los circuitos integrados, se agregará más en breve.

EDITAR - sobre los pullups:

Puede usar los pullups internos si no le importa que la línea se "relaje" a alta cuando no se maneja (es decir, el estado por defecto 1). guardar un pullup externo.
Sin embargo, si desea que el estado predeterminado de las líneas sea bajo, (como es su caso) necesita un menú desplegable para detener la flotación de alta impedancia. Dado que el IC en cuestión no tiene despliegues internos, debe agregarlos externamente.

EDIT - ¡Doh! Acabo de ver el problema ...

En tu código, configuras 1 pin a la vez para la salida y todo el resto a las entradas. Esto significa que si tiene activadas las funciones internas, los pines no accionados quedarán predeterminados en alto. Cuando un pin se establece en entrada, es alta impedancia , por lo que efectivamente es como desconectar ese extremo de la línea, y los pullups débiles tirarán del extremo receptor a alto.
Debes mantener todos los pines como salidas, y solo establecer uno alto a la vez, esto mantendrá todos los pines activados. Prueba esto con los pullups, debería funcionar.
Si sabes que las líneas se manejarán correctamente todo el tiempo, no necesitas los pullups, pero no hace daño mantenerlos.

Aquí está el código relevante (en la función de registros de inicialización):

i2c_start_wait(SLAVE_ADDRESS(0x4E)+I2C_WRITE); // Address Slave 1
    i2c_write(0x00);        // Set memory pointer to the IODIRA register (IODIRA address is 0x00 - see Page 9)
    i2c_write(~(Value));    // Set only one pin at a time as an output and everything else as inputs
    i2c_stop(); 

Cambie a:

i2c_start_wait(SLAVE_ADDRESS(0x4E)+I2C_WRITE); // Address Slave 1
    i2c_write(0x00);        // Set memory pointer to the IODIRA register (IODIRA address is 0x00 - see Page 9)
    i2c_write(0x00);    // Set all pins as outputs
    i2c_stop();
    
respondido por el Oli Glaser

Lea otras preguntas en las etiquetas