Interfaz PIC18F4550 con EEPROM I²C (24AA1025)

Ingrese la descripción de la imagen aquí

Estoy trabajando en un proyecto universitario en el que necesito conectar un PIC18F4550 con una EEPROM I²C.

Leí muchos códigos y vi muchos proyectos sobre este tema. Y escribí un código de muestra de MPLAB C18 (y también probé muchos códigos), pero nadie trabajó conmigo.

No sé dónde está el problema. Todo está bien con mi código y con mi circuito, pero la señal SCK no generó la señal CLK para escribir y no se ha escrito nada en la EEPROM .

Aquí está el código:

#include "p18f4550.h"
#include "i2c.h"
#pragma config FOSC = HS
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config MCLRE = ON
#pragma config PBADEN = OFF
#pragma config ICPRT = OFF
#pragma config LVP = OFF
#pragma config WDT = OFF,DEBUG=OFF

unsigned char arraywr[] = {1,2,3,4,5,6,7,8,0};
unsigned char arrayrd[20];
//***************************************************
void main(void)
{
    OpenI2C(MASTER, SLEW_ON);// Initialize I²C module
    SSPADD = 10; //400 kHz Baud clock(10) @20 MHz
    while(1)
    {
        EEByteWrite(0xA0, 0x30, 0xA5);
        EEAckPolling(0xA0);
        EECurrentAddRead(0xA0);
        EEPageWrite(0xA0, 0x70, arraywr);
        EEAckPolling(0xA0);
        EESequentialRead(0xA0, 0x70, arrayrd, 20);
        EERandomRead(0xA0,0x30);
    }
}

Este es el código de OpenI2C:

    /* $Id: i2c_open.c,v 1.1 2004/10/06 23:16:42 curtiss Exp $ */

    #include <p18cxxx.h>
    #include <i2c.h>


    /********************************************************************
    *   Function Name:  OpenI2C                                         *
    *   Return Value:   void                                            *
    *   Parameters:     SSP peripheral setup bytes                      *
    *   Description:    This function sets up the SSP module on a       *
    *                   PIC18CXXX device for use with a Microchip I²C   *
    *                   EEPROM device or I²C bus device.                *
    *********************************************************************/
    void OpenI2C( unsigned char sync_mode, unsigned char slew )
    {
        SSPSTAT &= 0x3F;                // Power on state
        SSPCON1 = 0x00;                 // Power on state
        SSPCON2 = 0x00;                 // Power on state
        SSPCON1 |= sync_mode;           // Select serial mode
        SSPSTAT |= slew;                // Slew rate on/off

        #if defined(__18F2455) || defined(__18F2550) || \
            defined(__18F4455) || defined(__18F4550)

            DDRBbits.RB1 = 1;           // Set SCL (PORTB,1) pin to input
            DDRBbits.RB0 = 1;           // Set SDA (PORTB,0) pin to input

        #else

            DDRCbits.RC3 = 1;           // Set SCL (PORTC,3) pin to input
            DDRCbits.RC4 = 1;           // Set SDA (PORTC,4) pin to input

        #endif

        SSPCON1 |= SSPENB;              // Enable synchronous serial port
    }
ya que estás en una universidad, ¿qué te parece obtener y publicar un seguimiento de osciloscopio de las líneas SDA y SCL? Te di un voto positivo con la esperanza de aumentar tu privilegio hasta el punto de poder publicar imágenes.
He publicado la imagen del circuito :)
¿De qué programa se captura su imagen, por curiosidad?
del simulador de isis
Ese es un producto de Proteus , para aquellos nuevos en Isis.

Respuestas (2)

No todo puede estar bien con su código y circuito si SCK no está generando un reloj ;-)

(Tenga en cuenta que SCK es para SPI. SCL es el nombre del pin I2C. Debajo de la referencia a SCL está lo que está llamando SCK)

Esto podría deberse a que no ha configurado los pines correctamente como menciona Leon, o posiblemente a que no ha agregado resistencias pullup a sus líneas SDA/SCL.

Si muestra su circuito (o simplemente nos informa si hay pullups presentes) y cualquier código de inicialización de I2C (por ejemplo, lo que sucede en OpenI2C), podemos confirmar cuál es el problema.

EDITAR: al mirar su esquema, parece que no tiene un pullup en SCL, lo que explicaría que no se vea nada en él. Las líneas I2C se controlan mediante salidas de drenaje abierto, lo que significa que el pin solo puede absorber corriente, no generarla.
Si agrega una resistencia (digamos, 2k a 10k) de SCL a Vdd, debería ver algo.

EDIT 2: no estoy seguro de dónde dice que no se necesita pullup en SCL. Acabo de echar un vistazo a la hoja de datos y encontré esto (página 207):

La selección de cualquier modo I 2 C con el conjunto de bits SSPEN obliga a que los pines SCL y SDA estén abiertos, siempre que estos pines estén programados como entradas configurando los bits TRISC o TRISD apropiados. Para garantizar el funcionamiento adecuado del módulo, se deben proporcionar resistencias pull-up externas a los pines SCL y SDA.

¿Está utilizando un PIC real aquí o simulando cosas en ISIS? Si se trata de una simulación, entonces puede ser algo relacionado con la configuración.
¿Tiene los bits TRIS configurados en consecuencia? (ambos a 1)
También por si acaso, configure los bits de registro ADCCON1 3:0 todos a 1, para configurar todos los pines como digitales. Puedes hacer, por ejemplo, ADCCON1 |= 0x0F;para esto.

Oli, edité mi publicación y agregué la imagen. Compruébelo por favor. Gracias :)
Además, he agregado la función OpenI2C ahora.
@m_engineer: está bien, vea las ediciones: no puedo ver un pullup en SCK.
De acuerdo con la hoja de datos, no es necesario tener pullup en SCK. ¡Pero traté de tener pullup y nada ha cambiado!
@m_engineer - ¿Dónde viste esto?
Para el scl, leí lo siguiente de la hoja de datos 2.3 Datos en serie (SDA) Este es un pin bidireccional que se usa para transferir direcciones y datos hacia y desde el dispositivo. Es un terminal de drenaje abierto, por lo tanto, el bus SDA requiere una resistencia pullup a VCC (típica de 10 kW para 100 kHz, 2 kW para 400 kHz y 1 MHz). Para la transferencia de datos normal, SDA solo puede cambiar durante SCL bajo. Los cambios durante SCL alto se reservan para indicar las condiciones de Inicio y Parada. 2.4 Reloj en serie (SCL) Esta entrada se utiliza para sincronizar la transferencia de datos desde y hacia el dispositivo.
@m_engineer: no puedo ver dónde dice que no se necesita un pullup allí. I2C siempre usa drenaje abierto + pullups para ambas líneas. ¿Puedes probar que el PIC funciona haciendo algo como alternar un pin? ¿Estás simulando esto o usando un PIC real?
R1 se coloca en el esquema actual, pero no tiene valor. Esencialmente no está allí.

Debe configurar los pines que se utilizan para la interfaz I2C para entrada/salida. Los pines de entrada que se comparten con las entradas analógicas deben configurarse como entradas digitales.

Gracias Leon :) ¿Hay otros pines que debo configurar además del scl y sdl?
Esos son los únicos dos pines utilizados por I2C.