TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: mauro_picotto_dj en 24 de Mayo de 2005, 10:50:00

Título: Ayuda programa escrit y lect memoria i2c EEPROM
Publicado por: mauro_picotto_dj en 24 de Mayo de 2005, 10:50:00
Hola amigos del foro tengo un problema en un programa de escritura y lectura de una memoria EEPROM por medio de I2C. Estoy trabajando en mplab con c18. el algoritmo es el siguiente:

archivo .h:

#ifndef __EEI2CPIC_H
#define __EEI2CPIC_H

#define Page_Lenght 8
#define EE_CMD 0xA4

#define PARAM_SCLASS auto
#define MEM_MODEL far
void Initialize_I2C_Master(void);
//unsigned char EEByteWrite( unsigned char control, unsigned char address, unsigned char data );
unsigned int EERandomRead( unsigned char control, unsigned char address );
void OpenI2C( unsigned char sync_mode, unsigned char slew );
void I2C_Done(void);
#endif


El archivo .c es:

#include <p18f452.h>
#include <i2c.h>
#include "EEi2cpic.h"

unsigned int read_value;

void main(void)
{
//inicialización de puertos y modo master del pic
   Initialize_I2C_Master();
   TRISD=0x00;   
   //EEByteWrite(0xA0, 0x01, 0xAB);
   read_value=EERandomRead(0xA0,0x01);
   for(;Giño
   {
      PORTD=read_value;
   }
}

/*unsigned char EEByteWrite( unsigned char control, unsigned char address, unsigned char data )
{
  IdleI2C();                      // ensure module is idle
  StartI2C();                     // initiate START condition
  while ( SSPCON2bits.SEN );      // wait until start condition is over
  if ( PIR2bits.BCLIF )           // test for bus collision
  {
    return ( -1 );                // return with Bus Collision error
  }
  else                            // start condition successful
  {
    if ( WriteI2C( control ) )    // write byte - R/W bit should be 0
    {
      return ( -3 );              // set error for write collision
    }

    IdleI2C();                    // ensure module is idle
    if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
    {
      if ( WriteI2C( address ) )  // write word address for EEPROM
      {
        return ( -3 );            // set error for write collision
      }

      IdleI2C();                  // ensure module is idle
      if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
      {
        if ( WriteI2C( data ) )   // data byte for EEPROM
        {
          return ( -3 );          // set error for write collision
        }
      }
      else
      {
        return ( -2 );            // return with Not Ack error condition  
      }
    }
    else
    {
      return ( -2 );              // return with Not Ack error condition  
    }
  }

  IdleI2C();                      // ensure module is idle  
  StopI2C();                      // send STOP condition
  while ( SSPCON2bits.PEN );      // wait until stop condition is over
  if ( PIR2bits.BCLIF )           // test for bus collision
  {
    return ( -1 );                // return with Bus Collision error
  }
  return ( 0 );                   // return with no error
}*/

unsigned int EERandomRead( unsigned char control, unsigned char address )
{

  SSPCON2bits.SEN=1;
  I2C_Done();
  while ( SSPCON2bits.SEN );      // wait until start condition is over

    WriteI2C( control );     // write 1 byte
    IdleI2C();                    // ensure module is idle
      while(SSPCON2bits.ACKSTAT);   // test for ACK condition, if received

    WriteI2C( address );  // WRITE word address for EEPROM
    IdleI2C();                    // ensure module is idle
    while(SSPCON2bits.ACKSTAT);   // test for ACK condition, if received
   
   StopI2C();              // send STOP condition
    while ( SSPCON2bits.PEN ); // wait until stop condition is over
    SSPCON2bits.SEN=1;
     I2C_Done();
    while ( SSPCON2bits.SEN );      // wait until start condition is over
   
           
    WriteI2C( control+1 ); // write 1 byte - R/W bit should be 1
    IdleI2C();                // ensure module is idle
    while(SSPCON2bits.ACKSTAT);// test for ACK condition, if received

    SSPCON2bits.RCEN = 1;       // enable master for 1 byte reception
    while ( SSPCON2bits.RCEN ); // check that receive sequence is over
    NotAckI2C();              // send ACK condition
    while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
    StopI2C();              // send STOP condition
    while ( SSPCON2bits.PEN ); // wait until stop condition is over

  return ( (unsigned int) SSPBUF );     // return with data
}

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
}


//Se asginará polling a la respuesta de la EEPROM
//ACK = regreso
//ACK = 1 envia reinicio y se revisa el ciclo

/*void EEPROM_ACK(unsigned char ctrl)
{
   unsigned char i;
   IdleI2C();
   for (i=0;i<240;i++);
   StartI2C();
   I2C_Done();
   
   WriteI2C(ctrl);
   I2C_Done();

   while(SSPCON2bits.ACKSTAT);
   {
      for   (i=0;i<250;i++);
      RestartI2C();
      while ( SSPCON2bits.RSEN );
      
      WriteI2C( ctrl );

       IdleI2C();
   }
   StopI2C();
   I2C_Done();
}*/



// Observar que se completó la acción I2C

void I2C_Done(void)
{
   while(!PIR1bits.SSPIF);
   PIR1bits.SSPIF=0;   
}

//Inicialización MODO MASTER con 7 bits de dirección
//velocidad del reloj:100khz a 10MHZ

void Initialize_I2C_Master(void)
{
   OpenI2C(MASTER,SLEW_ON);
   SSPADD=0x19;

}

Estoy haciendo lo siguiente: primero utilizo la rutina de escritura compilo y escribo la memoria con AB en la dirección 0x01. Utilizo el pic 18f452 y la memoria 24LC04B y simulo en proteus. Luego puedo leer el dato compilando solamente la rutina de lectura. ¿Como podría modificar el código para que me escriba el dato y me lea después lo que escribi? Creo que el problema está en la trama o datos que van en el bus y reinician la transmisión de la memoria 24LC04B.