i'm using AT24C04 I2C EEPROM ,i want to write 48 bytes into EEPROM but internally EEPROM organized to max 16bytes of each page write.
i can possible to write 16bytes in first...My doubt is ...How to write 16bytes into another page...
My code is here...
MAIN.C
#include <p18f4550.h>
#include "I2C_EEPROM.h"
#include <i2c.h>
// CONFIG1L
#pragma config PLLDIV = 5 // PLL Prescaler Selection bits (Divide by 5 (20 MHz oscillator input))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
// CONFIG1H
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator, PLL enabled (HSPLL))
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
// CONFIG3H
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config MCLRE = OFF // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
// CONFIG5L
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
//#pragma config DUBUG = ON
#define PAGESIZE 16
void InitI2C(void);
void I2CEeprom(void);
void PollI2CEeprom (void);
void Error(void);
unsigned int PageSize = 16;
unsigned char eeprom_address = 0xA0;
unsigned int EepAdd = 0x01; // address
unsigned char WrData[] = {0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
unsigned char RdData[PAGESIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void main(void)
{
unsigned char delay;
InitI2C();
I2CEeprom();
// incase of successful operation control reach here..
TRISDbits.TRISD2= 0;
while (1)
{
LATDbits.LATD2= ~(LATDbits.LATD2);// toggle RD2
delay = 0x50;
while(delay--);
}
}
void InitI2C(void)
{
TRISBbits.TRISB1 = 1; // SCL dir input
TRISBbits.TRISB0 = 1; // SDA dir input
PIR1bits.SSPIF = 0; // clear interrupt flag
SSPSTAT = 0x00;
SSPADD = 0x31; // I2C baud = 100KHz @ Fosc = 20MHz
SSPCON2 = 0x00;
SSPCON1 = 0x28; // Master mode I2C
}
void I2CEeprom(void)
{
unsigned char i;
unsigned char length;
length = 16;
ForWrite(eeprom_address, EepAdd, WrData);
PollI2CEeprom();
ForRead(eeprom_address, EepAdd, RdData, length);
for(i=0; i<length; i++)
{
if(RdData != WrData)
{
Error();
}
}
}
void PollI2CEeprom (void)
{
while (1)
{
StartI2C();
IdleI2C();
WriteI2C( eeprom_address );
IdleI2C();
if (SSPCON2bits.ACKSTAT == 0)
{
StopI2C();
IdleI2C();
break;
}
StopI2C();
IdleI2C();
}
}
void Error(void)
{
unsigned char delay;
TRISDbits.TRISD1 = 0;
while (1)
{
LATDbits.LATD3= ~(LATDbits.LATD3);// toggle RD3
delay = 0x50;
while(delay--);
}
}
EEPROM.C
#include <p18f4550.h>
#include <i2c.h>
#include "I2C_EEPROM.h"
unsigned char ForWrite( unsigned char ControlByte, unsigned char LowAdd, unsigned char *wrptr )
{
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
IdleI2C(); // ensure module is idle
WriteI2C( LowAdd ); // write LowAdd byte to EEPROM
IdleI2C(); // ensure module is idle
putstringI2C ( wrptr ); // pointer to data for page write
IdleI2C(); // ensure module is idle
StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN ); // wait until stop condition is over
return ( 0 ); // return with no error
}
unsigned char ForRead( unsigned char ControlByte, unsigned char address, unsigned char *rdptr, unsigned char length )
{
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
WriteI2C( ControlByte ); // write 1 byte
IdleI2C(); // ensure module is idle
WriteI2C( address ); // WRITE word address to EEPROM
IdleI2C(); // ensure module is idle
RestartI2C(); // generate I2C bus restart condition
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
IdleI2C(); // ensure module is idle
getsI2C( rdptr, length ); // read in multiple bytes
NotAckI2C(); // send not 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 ( 0 ); // return with no error
}
unsigned char putstringI2C( unsigned char *wrptr )
{
unsigned char x;
for (x = 0; x < PageSize; x++ ) // transmit data until PageSize
{
if ( SSPCON1bits.SSPM3 ) // if Master transmitter then execute the following
{
if ( putcI2C ( *wrptr ) ) // write 1 byte
{
return ( -3 ); // return with write collision error
}
IdleI2C(); // test for idle condition
if ( SSPCON2bits.ACKSTAT ) // test received ack bit state
{
return ( -2 ); // bus device responded with NOT ACK
} // terminateputstringI2C() function
}
else // else Slave transmitter
{
PIR1bits.SSPIF = 0; // reset SSPIF bit
SSPBUF = *wrptr; // load SSPBUF with new data
SSPCON1bits.CKP = 1; // release clock line
while ( !PIR1bits.SSPIF ); // wait until ninth clock pulse received
if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) )// if R/W=0 and BF=0, NOT ACK was received
{
return ( -2 ); // terminateputstringI2C() function
}
}
wrptr ++; // increment pointer
} // continue data writes until null character
return ( 0 );
}
i can possible to write 16bytes in first...My doubt is ...How to write 16bytes into another page...
My code is here...
MAIN.C
#include <p18f4550.h>
#include "I2C_EEPROM.h"
#include <i2c.h>
// CONFIG1L
#pragma config PLLDIV = 5 // PLL Prescaler Selection bits (Divide by 5 (20 MHz oscillator input))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
// CONFIG1H
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator, PLL enabled (HSPLL))
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
// CONFIG3H
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config MCLRE = OFF // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
// CONFIG5L
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
//#pragma config DUBUG = ON
#define PAGESIZE 16
void InitI2C(void);
void I2CEeprom(void);
void PollI2CEeprom (void);
void Error(void);
unsigned int PageSize = 16;
unsigned char eeprom_address = 0xA0;
unsigned int EepAdd = 0x01; // address
unsigned char WrData[] = {0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
unsigned char RdData[PAGESIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void main(void)
{
unsigned char delay;
InitI2C();
I2CEeprom();
// incase of successful operation control reach here..
TRISDbits.TRISD2= 0;
while (1)
{
LATDbits.LATD2= ~(LATDbits.LATD2);// toggle RD2
delay = 0x50;
while(delay--);
}
}
void InitI2C(void)
{
TRISBbits.TRISB1 = 1; // SCL dir input
TRISBbits.TRISB0 = 1; // SDA dir input
PIR1bits.SSPIF = 0; // clear interrupt flag
SSPSTAT = 0x00;
SSPADD = 0x31; // I2C baud = 100KHz @ Fosc = 20MHz
SSPCON2 = 0x00;
SSPCON1 = 0x28; // Master mode I2C
}
void I2CEeprom(void)
{
unsigned char i;
unsigned char length;
length = 16;
ForWrite(eeprom_address, EepAdd, WrData);
PollI2CEeprom();
ForRead(eeprom_address, EepAdd, RdData, length);
for(i=0; i<length; i++)
{
if(RdData != WrData)
{
Error();
}
}
}
void PollI2CEeprom (void)
{
while (1)
{
StartI2C();
IdleI2C();
WriteI2C( eeprom_address );
IdleI2C();
if (SSPCON2bits.ACKSTAT == 0)
{
StopI2C();
IdleI2C();
break;
}
StopI2C();
IdleI2C();
}
}
void Error(void)
{
unsigned char delay;
TRISDbits.TRISD1 = 0;
while (1)
{
LATDbits.LATD3= ~(LATDbits.LATD3);// toggle RD3
delay = 0x50;
while(delay--);
}
}
EEPROM.C
#include <p18f4550.h>
#include <i2c.h>
#include "I2C_EEPROM.h"
unsigned char ForWrite( unsigned char ControlByte, unsigned char LowAdd, unsigned char *wrptr )
{
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
IdleI2C(); // ensure module is idle
WriteI2C( LowAdd ); // write LowAdd byte to EEPROM
IdleI2C(); // ensure module is idle
putstringI2C ( wrptr ); // pointer to data for page write
IdleI2C(); // ensure module is idle
StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN ); // wait until stop condition is over
return ( 0 ); // return with no error
}
unsigned char ForRead( unsigned char ControlByte, unsigned char address, unsigned char *rdptr, unsigned char length )
{
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
WriteI2C( ControlByte ); // write 1 byte
IdleI2C(); // ensure module is idle
WriteI2C( address ); // WRITE word address to EEPROM
IdleI2C(); // ensure module is idle
RestartI2C(); // generate I2C bus restart condition
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
IdleI2C(); // ensure module is idle
getsI2C( rdptr, length ); // read in multiple bytes
NotAckI2C(); // send not 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 ( 0 ); // return with no error
}
unsigned char putstringI2C( unsigned char *wrptr )
{
unsigned char x;
for (x = 0; x < PageSize; x++ ) // transmit data until PageSize
{
if ( SSPCON1bits.SSPM3 ) // if Master transmitter then execute the following
{
if ( putcI2C ( *wrptr ) ) // write 1 byte
{
return ( -3 ); // return with write collision error
}
IdleI2C(); // test for idle condition
if ( SSPCON2bits.ACKSTAT ) // test received ack bit state
{
return ( -2 ); // bus device responded with NOT ACK
} // terminateputstringI2C() function
}
else // else Slave transmitter
{
PIR1bits.SSPIF = 0; // reset SSPIF bit
SSPBUF = *wrptr; // load SSPBUF with new data
SSPCON1bits.CKP = 1; // release clock line
while ( !PIR1bits.SSPIF ); // wait until ninth clock pulse received
if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) )// if R/W=0 and BF=0, NOT ACK was received
{
return ( -2 ); // terminateputstringI2C() function
}
}
wrptr ++; // increment pointer
} // continue data writes until null character
return ( 0 );
}