Problemas de escritura en memoria serial I2C (solucionado)

Hola!

Oigan, un favorsote, yo tengo un problema al escribir entre una y otra página.

Trabajo con la 24C64 y no tengo problemas cuando escribo una página de 32 Bytes, pero si quiero seguir a la página siguiente cuando le doy después del stop, un retardo de hasta un segundo no hace nada; vuelve a sobreescribir sobre la dirección 0x00 hasta la 0x1f y allí se queda siempre, nomás sobreescribiendo y sobreescribiendo.

Así como si le pido que escriba por primera vez en una dirección que no sea la 0x00, no hace caso; solo obedece cuando es la dirección cero.

¿qué hago?

Ya me tardé mucho y no le hallo.


Muchísimas gracias,

Fabián
 
P.D.

Y el retardo se lo he dado antes y después del AcnowledgePollling, para dis que no fallarle, pero ni así :(

Saludos,
 
Código:
#include<p18f452.h>
#include <my_i2c.h>

#pragma config LVP = OFF
#pragma config STVR = OFF
#pragma config WDT = OFF
#pragma config OSC = HS 

void main(void)
{
char c;
PORTA = PORTB = PORTC = PORTD = PORTE = 0x00;
TRISA = 0;
TRISB = 0;
TRISD = 0;
TRISC = 0x18;

OpenI2C(MASTER, SLEW_OFF);
SSPADD = 19;

comienzaI2C();
PrepareWWord_I2C(0xa0,0x00,0x00);
for (c=0x01;c<=0x20;c++)
{
WWord_I2C(c);
}
FinishWWord_I2C();
AckPolling(0xa0);


comienzaI2C();
PrepareWWord_I2C(0xa0,0x00,0x20);
for (c=0x01;c<=0x20;c++)
{
WWord_I2C(c);
}
FinishWWord_I2C();

retardo_1ms(0xfe);
AckPolling(0xa0);

PrepareWWord_I2C(0xa0,0x00,0x20);
for (c=0x02;c<=0x40;c=c+0x02)
{
WWord_I2C(c);
}
FinishWWord_I2C();

retardo_1ms(0xfe);
AckPolling(0xa0);


c = 0x01;
comienzaI2C();
PrepareRWord_I2C(0xa0,0x00,0x00);
for (c=0x00;c<=0x3f;c++)
{
PORTB = RWord_I2C();
retardo_1ms(0x80);
}
FinishRWord_I2C();
IdleI2C();


PORTAbits.RA0 = 1;


while(1)
{
}
}


Este es el main, y estas las funciones como header file:





#include <funciones_i2c.h>
#include <my_Delays.h>
/**************************************
*									  *
*        Escribe I2C  Byte            *
*									  *
**************************************/
unsigned char dato[7];


unsigned char escribeI2C(unsigned char dir_slv, 
						 unsigned char dir_low, 
						 unsigned char dir_high, 
						 unsigned char dato )
{
 WriteI2C(dir_slv);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_high);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_low);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dato);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )
 IdleI2C();
 StopI2C();
 while ( SSPCON2bits.PEN );      // wait until stop condition is over 
return (0);
}




/**************************************
*									  *
*            Lee I2C  Random          *
*									  *
**************************************/

unsigned char leeI2C( unsigned char dir_slv, 
					  unsigned char dir_high, 
					  unsigned char dir_low) 
{
 unsigned char read;
 WriteI2C(dir_slv);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_high);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_low);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 RestartI2C();
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_slv+0x01);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 IdleI2C();
 read = ReadI2C();
 NotAckI2C();
 while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over 
 StopI2C();
 while ( SSPCON2bits.PEN ); // wait until stop condition is over 
 return (read);
}


/**************************************
*									  *
*        Comienza I2C                 *
*									  *
**************************************/

void comienzaI2C(void)
{
 IdleI2C();
 StartI2C();
 while ( SSPCON2bits.SEN );      // wait until start condition is over

}



/**************************************
*									  *
*        Detiene I2C                  *
*									  *
**************************************/
void detenI2C(void)
{
IdleI2C();
StopI2C();
while ( SSPCON2bits.PEN ); // wait until stop condition is over 
}


/***********************************************************************
************************************************************************
*									                        
*        				Escribe I2C  Word                              
*									  			*********************************************************************
/***********************************************************************/


 void PrepareWWord_I2C ( unsigned char dir_slv, 
					     unsigned char dir_low, 
					     unsigned char dir_high )
{
 WriteI2C(dir_slv);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_high);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_low);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )
 IdleI2C();
}

void WWord_I2C(unsigned char Word)
{
 WriteI2C(Word);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )
 IdleI2C();
}

 void FinishWWord_I2C(void)
{
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )
 IdleI2C();
 StopI2C();
 while ( SSPCON2bits.PEN );      // wait until stop condition is over 
}




/***********************************************************************
************************************************************************
*									                      *
*        			    	Lee I2C  Word                                                            *
*									  	          *
************************************************************************
/***********************************************************************/
unsigned char PrepareRWord_I2C( unsigned char dir_slv, 
					  			unsigned char dir_high, 
					  			unsigned char dir_low) 
{
 WriteI2C(dir_slv);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_high);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_low);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 RestartI2C();
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )

 WriteI2C(dir_slv+0x01);
 IdleI2C();
 if ( !SSPCON2bits.ACKSTAT )
 IdleI2C();
 return (0);
}

 unsigned char RWord_I2C(void)
{
  ReadI2C();	
  AckI2C();
  return (SSPBUF);
}

void FinishRWord_I2C()
{
 NotAckI2C();
 while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over 
 StopI2C();
 while ( SSPCON2bits.PEN ); // wait until stop condition is over 
}



/********************************************************************
********************************************************************/
unsigned char AckPolling( unsigned char control )
{
  IdleI2C();                      // ensure module is idle 
  StartI2C();                     // initiate START condition
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
  WriteI2C( control );    // write byte - R/W bit should be 0
  IdleI2C();                    // ensure module is idle   
   while ( SSPCON2bits.ACKSTAT ) // test for ACK condition received
   {
    RestartI2C();               // initiate Restart condition
    while ( SSPCON2bits.RSEN ); // wait until re-start condition is over 
    WriteI2C( control );  // write byte - R/W bit should be 0
    IdleI2C();                  // ensure module is idle
   }
  StopI2C();                      // send STOP condition
  while ( SSPCON2bits.PEN );      // wait until stop condition is over         
  return ( 0 );                   // return with no error     
}
 
Código:
#define SSPENB 0x20 /* Enable serial port and configures
SCK, SDO, SDI */
#define SLAVE_7 6 /* I2C Slave mode, 7-bit address */
#define SLAVE_10 7 /* I2C Slave mode, 10-bit address */
#define MASTER 8 /* I2C Master mode */
 
/* SSPSTAT REGISTER */
#define SLEW_OFF 0xC0 /* Slew rate disabled for 100kHz mode */
#define SLEW_ON 0x00 /* Slew rate enabled for 400kHz mode */
 
 
 
 
/********************************************************************
* Function Name: IdleI2C *
* Return Value: void *
* Parameters: void *
* Description: Test and wait until I2C module is idle. *
********************************************************************/
void IdleI2C( void )
{
while ( ( SSPCON2 & 0x1F ) | ( SSPSTATbits.R_W ) );
}
 
 
 
 
 
/********************************************************************
* Function Name: ReadI2C *
* Return Value: contents of SSPBUF register *
* Parameters: void *
* Description: Read single byte from I2C bus. *
********************************************************************/
unsigned char ReadI2C( void )
{
SSPCON2bits.RCEN = 1; // enable master for 1 byte reception
while ( SSPCON2bits.RCEN ); // wait until byte received 
return ( SSPBUF ); //return with read byte 
}
 
 
 
 
 
 
 
 
/********************************************************************
* Function Name: RestartI2C *
* Return Value: void *
* Parameters: void *
* Description: Send I2C bus restart condition. *
********************************************************************/
void RestartI2C( void )
{
SSPCON2bits.RSEN = 1; // initiate bus restart condition
}
 
 
 
 
 
/********************************************************************
* Function Name: StopI2C *
* Return Value: void *
* Parameters: void *
* Description: Send I2C bus stop condition. *
********************************************************************/
 
void StopI2C( void )
{
SSPCON2bits.PEN = 1; // initiate bus stop condition
}
 
 
 
 
 
 
/********************************************************************
* Function Name: StartI2C *
* Return Value: void *
* Parameters: void *
* Description: Send I2C bus start condition. *
********************************************************************/
 
void StartI2C( void )
{
SSPCON2bits.SEN = 1; // initiate bus start condition
}
 
 
/********************************************************************
* Function Name: WriteI2C *
* Return Value: Status byte for WCOL detection. *
* Parameters: Single data byte for I2C bus. *
* Description: This routine writes a single byte to the * 
* I2C bus. *
********************************************************************/
unsigned char WriteI2C( unsigned char data_out )
{
IdleI2C();
SSPBUF = data_out; // write single byte to SSPBUF
if ( SSPCON1bits.WCOL ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
{
while( SSPSTATbits.BF ); // wait until write cycle is complete 
IdleI2C(); // ensure module is idle
}
if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition, if received 
return ( 0 ); // if WCOL bit is not set return non-negative #
else
{
return ( -3 );
}
}
 
 
/********************************************************************
* Function Name: NotAckI2C *
* Return Value: void *
* Parameters: void *
* Description: Initiate NOT ACK bus condition. *
********************************************************************/
 
void NotAckI2C( void )
{
SSPCON2bits.ACKDT = 1; // set acknowledge bit for not ACK
SSPCON2bits.ACKEN = 1; // initiate bus acknowledge sequence
}
 
 
 
/********************************************************************
* Function Name: AckI2C *
* Return Value: void *
* Parameters: void *
* Description: Initiate ACK bus condition. *
********************************************************************/
 
void AckI2C( void )
{
SSPCON2bits.ACKDT = 0; // set acknowledge bit state for ACK
SSPCON2bits.ACKEN = 1; // initiate bus acknowledge sequence
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
}
 
 
 
/********************************************************************
* 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 I2C *
* EEPROM device or I2C 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 
DDRCbits.RC3 = 1; // Set SCL (PORTC,3) pin to input
DDRCbits.RC4 = 1; // Set SDA (PORTC,4) pin to input
SSPCON1 |= SSPENB; // enable synchronous serial port 
SSPADD = 19; // CLK = [8MHz/4*(19+1)] = 100 KHz
}
 
Última edición por un moderador:
hola yo tengo problemas porque no me lee nada, solo me aparece parpadeando el cursos en el lcd, este es mi codigo cualquier cosa por favor me sirve, trabajo con C18

Código:
#include <p18f1320.h>
#include <delays.h>
#include <adc.h>
#include <xlcd.h>
#include <sw_i2c.h>
#include <stdlib.h>
#include <stdio.h>
#pragma config OSC=INTIO2, WDT=OFF, MCLRE=ON, LVP=OFF
 
void DelayFor18TCY( void )
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}
 
void DelayPORXLCD (void)
{
Delay1KTCYx(60); // Delay of 15ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (15ms * 16MHz) / 4
// Cycles = 60,000
return;
}
 
void DelayXLCD (void)
{
Delay1KTCYx(20); // Delay of 5ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (5ms * 16MHz) / 4
// Cycles = 20,000
return;
}
 
 
void main(void)
{
 
 
int dato,x,otra,cont,contador2;
unsigned char buf[9],cosa,contchar,i2c,nuevo;
 
 
ADCON1=0x7F;
TRISA=0xFF;
TRISB=0x00;
PORTBbits.RB7=0;
 
OpenXLCD( FOUR_BIT & LINES_5X7 );
 
WriteCmdXLCD( BLINK_ON );
putrsXLCD("ESIME CULHUACAN"); 
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 ); 
putrsXLCD("1ER AVANCE");
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 ); 
 
cont=35;
 
while(1)
{
/*Inicializa el convertidor ADC con canal 0 como entrada analógica */
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_12_TAD,
ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS &
ADC_CH0 & ADC_INT_OFF, 0x7E );
 
 
SetDDRamAddr(0x00);
//while(BusyXLCD());
putrsXLCD("PRESIONA UNA TECLA");
do{
x=0;
ConvertADC(); 
while(BusyADC()); 
dato= ReadADC();
}while(dato<20); 
 
 
while(BusyXLCD()); 
 
if(dato>855&&dato<875)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 1");
Delay1KTCYx(10);
itoa(cont, contchar);
WriteCmdXLCD( 0x01 );
SWStartI2C();
SWPutcI2C(0xA0); // control byte
SWAckI2C();
SWPutcI2C(0x00); // address high byte
SWAckI2C();
SWPutcI2C(0x00); //address low byte
SWAckI2C();
SWPutcI2C(contchar); // data
SWAckI2C();
SWStopI2C();
Delay100TCYx(100);
}
 
if(dato>645&&dato<655)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 2");
Delay1KTCYx(10); 
WriteCmdXLCD( 0x01 );
SWStartI2C();
SWPutcI2C(0xA0); // control byte
SWAckI2C();
SWPutcI2C(0x00); // address high byte
SWAckI2C();
SWPutcI2C(0x00); //address low byte
SWAckI2C();
SWStartI2C();
SWPutcI2C(0xA1);
SWAckI2C();
i2c=SWGetcI2C(); // data
SWNotAckI2C();
SWStopI2C(); 
Delay100TCYx(100);
WriteCmdXLCD( 0x01 );
}
 
if(dato>495&&dato<515)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 3");
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 ); 
itoa(cont, nuevo);
putsXLCD( nuevo ); 
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 );
putsXLCD( i2c );
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 );
}
 
if(dato>335&&dato<345)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 4");
cont++; 
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 );
}
 
if(dato>797&&dato<809)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 5");
Delay1KTCYx(10);
}
 
if(dato>610&&dato<621)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 6");
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 );
}
 
if(dato>480&&dato<491)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 7");
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 );
}
 
if(dato>322&&dato<333)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 8");
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 );
}
 
if(dato>728&&dato<740)
{
WriteCmdXLCD( 0x01 );
putrsXLCD("tecla 9");
Delay1KTCYx(10);
WriteCmdXLCD( 0x01 );
}
 
if(dato>568&&dato<580)
{
WriteCmdXLCD( 0x01 ); 
putrsXLCD("corrertecla");
do{ //WriteCmdXLCD( 0x01 );
Delay1KTCYx(10);
WriteCmdXLCD( SHIFT_CUR_LEFT );
x++; 
}while(x<4);
Delay1KTCYx(10);
while ( BusyXLCD() );
cosa = ReadDataXLCD();
btoa(cosa, buf);
WriteCmdXLCD( 0x01 ); 
putsXLCD(buf);
Delay1KTCYx(10);
atoi(cosa);
WriteCmdXLCD( 0x01 ); 
putsXLCD(cosa);
Delay1KTCYx(10); 
WriteCmdXLCD( 0x01 );
}
 
CloseADC(); 
while(BusyADC());
}
 
 
}
 
Última edición por un moderador:
hola, estoy envalado por q no he podido poner a funcionar el adc interno y la memoria i2c simultaneamente, cada uno funciona muy bien independientemente pero al usarlos a la vez el programa se bloquea, estoy usando un pic 18f4455, hay q tener en cuenta algun retardo entre lectura adc y escritura eeprom, o q hay q hacer?
 
fijense que andando con el mismo problema acerca de como conectar memorias I2C a un pic y leerlas asi como escribirlas correctamente me encontre un tutorial en español para utilizar todas las memorias seriales 24c02,24c04,24c08,24c16,24c32,24c64,24c128,24c256,24c512 y la 24c1025 asi como los ejemplos para conectarlas a cualquier tipo de pic, todos los ejemplos estan en ASM lenguaje ensamblador aqui:
 
Atrás
Arriba