I2C no envía datos en PIC16F887

Soy relativamente nuevo en el uso de microcontroladores PIC y el compilador MPLAB XC8.

Quiero comunicar dos PIC16F887 usando I2C. Usé este tutorial (https://electrosome.com/i2c-pic-microcontroller-mlab-xc8/) como mi introducción a este protocolo, pero aunque mi código compila, mi simulación de proteus no hace nada. El objetivo es solo enviar el conteo de 0 a 3 a través de I2C del maestro a un esclavo, y el esclavo debe mostrar ese número en 2 led en PORTB.

Proteus simulación de mi circuito.

Depuré el programa en el lado maestro y el programa parece atascarse dentro de mi función I2C_Master_Wait(), realmente trato de entender qué sucede dentro de esta función, pero no obtengo ningún resultado desde hace demasiados días.

void I2C_Master_Wait(){
    while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); 
}

Espero que alguien pueda ayudarme con un mejor tutorial o alguna explicación sobre lo que sucede en esa función y tal vez otra forma de hacerlo. Adjunto aquí la carpeta con el código de maestro y esclavo y la simulación de proteus.

¡Gracias!

Respuestas (1)

Antes de comenzar, si desea trabajar con comunicación digital como I2C, SPI, I2S, CAN, etc., le recomiendo que invierta dinero en un analizador lógico. Estos protocolos no requieren una tasa de muestreo rápida, por lo que lo más probable es que pueda encontrar un dispositivo asequible. En cualquier caso, le ahorrará un tiempo valioso. Yo personalmente uso dispositivos Saleae .

Entendiendo los registros

Para comprender el pequeño fragmento de código que compartió, tendremos que aclarar un poco cómo funcionan los microprocesadores y cómo interactúan con el hardware. Supongo que sabe cómo funcionan los punteros en C/C++; apuntan a una dirección de memoria. Lo que probablemente no sepa es que no solo apuntan a una ubicación de memoria, sino que también pueden apuntar a un registro de hardware. Cuando lee o escribe en una variable, su procesador pondrá esa dirección en su bus de direcciones y leerá o escribirá el contenido en el bus de datos .

Como dije, no todas las direcciones se refieren a una ubicación de memoria. Si observa la hoja de datos PIC16F887 , encontrará muchos registros ubicados entre las direcciones 000h-1FFh. Puede leer o escribir su contenido. En algún momento serán accesibles solo para uno u otro, eso se especificará en la hoja de datos.

Estos registros se utilizan para 1) Configurar su periférico (como un transceptor I2C) 2) Pasar datos a un dispositivo (como los datos que desea enviar/recibir con I2c)

Los fragmentos de código que diste están leyendo estos registros. SSPSTAT (0x94) y SSPCON2 (0x91) son dos constantes definidas en un archivo de encabezado que viene con su compilador. Básicamente son punteros, y el código realiza una operación bit a bit para obtener el valor de un bit específico dentro de estos registros. En otras palabras, su programa está esperando mientras el bit 2 de SSPSTAT o los bits 8 a 0 de SSPCON2 estén configurados en alto. Parece que esto no funcionará porque SSPCON2 contiene bits de configuración, como el bit 7: GCEN. Si establece este bit en alto, las interrupciones se habilitan para I2C y este bit no cambiará.

tu problema

En cuanto a dónde está el problema, el cableado parece correcto. Los problemas podrían ser:

  1. Mala configuración de registro
  2. El esclavo nunca transmite (ahí es donde el analizador lógico se vuelve útil)
  3. La lógica de recepción no es buena. El que tienes me parece raro.

Creo que para la recepción, debería mirar SSPSTAT bit0 (BF). Este bit se vuelve alto cuando su búfer de recepción está lleno.

Buena suerte