Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

lpc1769 24c256 eeprom writing error

Status
Not open for further replies.

eray81

Junior Member level 3
Joined
Jan 1, 2012
Messages
29
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,461
Hi,
I am trying to write eeprom by using i2c, but i can't. Maybe , there is power difference between 24C256 and 24LC256. 24C256 works with +5v and 24LC256 works +3.3v. What do you think ?
 

Hi,
I am trying to write eeprom by using i2c, but i can't.

This statement does not explain much about your problem.

Perhaps if you post your code others can rule out that as being the problem.
What about the circuit diagram? Did you use pullups on the data & clock lines?
 

I use LPC1700 BUNDLE code for i2c and for the circuit diagram I use 3.3k pull ups for clock and data. And I connect the WP pin to the ground.
 

My read and write codes are below: I can read my eeprom but i can't write to it.
main.c:
Code:
#include <LPC17xx.h>
#include "lcd.h"
#include "delay.h"
#include "i2c.h"



extern volatile uint32_t I2CCount;
extern volatile uint8_t I2CMasterBuffer[BUFSIZE];
extern volatile uint32_t I2CCmd, I2CMasterState;
extern volatile uint32_t I2CReadLength, I2CWriteLength;
uint8_t  j,i;

/********************************************************************************************/
uint8_t  EX_EEPROM_WRITE(uint8_t adres, uint8_t veri)
{
  for ( i = 0; i < BUFSIZE; i++ )	/* clear buffer */
  {
	I2CMasterBuffer[i] = 0;
  }
  I2CWriteLength = 3;
  I2CReadLength  = 0;
  I2CMasterBuffer[0] = ADR_BYTE;
  I2CMasterBuffer[1] = adres;
  I2CMasterBuffer[2] = veri;
  if(I2CEngine())
  return 1;
  else
  return 0;
}
/********************************************************************************************/ 
uint8_t  EX_EEPROM_READ(uint8_t adres)
{
   for ( i = 0; i < BUFSIZE; i++ )	  	/* clear buffer */
  {
	I2CMasterBuffer[i] = 0;
  }
  I2CWriteLength = 2;
  I2CReadLength = 1;
  I2CMasterBuffer[0] = ADR_BYTE;
  I2CMasterBuffer[1] = adres;
  I2CMasterBuffer[2] = ADR_BYTE|RD_BIT;
  I2CEngine();
  I2CStop();
  return (I2CMasterBuffer[3]);
}
/********************************************************************************************/
int main (void)
{

    SystemInit ();
	SysTick_Config(12000000/1000);

 	if ( I2CInit( (uint32_t)I2CMASTER ) == 0 )	/* initialize I2c */
  	{
		while ( 1 );				/* Fatal error */
  	}

				
	LPC_GPIO2->FIODIR = 0xFFFFFFFF; 
EX_EEPROM_WRITE(0,1);
}
i2c.c:
Code:
#include "lpc17xx.h"
#include "i2c.h"

volatile uint32_t I2CMasterState = I2C_IDLE;
volatile uint32_t I2CSlaveState = I2C_IDLE;

volatile uint32_t I2CCmd;
volatile uint32_t I2CMode;

volatile uint8_t I2CMasterBuffer[BUFSIZE];
volatile uint8_t I2CSlaveBuffer[BUFSIZE];
volatile uint32_t I2CCount = 0;
volatile uint32_t I2CReadLength;
volatile uint32_t I2CWriteLength;

volatile uint32_t RdIndex = 0;
volatile uint32_t WrIndex = 0;

/* 
From device to device, the I2C communication protocol may vary, 
in the example below, the protocol uses repeated start to read data from or 
write to the device:
For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(r),data...STO 
for master write: the sequence is: STA,Addr(W),length,RE-STA,Addr(w),data...STO
Thus, in state 8, the address is always WRITE. in state 10, the address could 
be READ or WRITE depending on the I2CCmd.
*/   

/*****************************************************************************
** Function name:		I2C0_IRQHandler
**
** Descriptions:		I2C0 interrupt handler, deal with master mode
**						only.
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
void I2C0_IRQHandler(void)  
{
  uint8_t StatValue;

  /* this handler deals with master read and master write only */
  StatValue = LPC_I2C0->I2STAT;
	
  switch ( StatValue )
  {
	case 0x08:			/* A Start condition is issued. */
	LPC_I2C0->I2DAT = I2CMasterBuffer[0];
	LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	I2CMasterState = I2C_STARTED;
	break;
	
	case 0x10:			/* A repeated started is issued */
	if ( ! I2CCmd )
	{
	  LPC_I2C0->I2DAT = I2CMasterBuffer[2];
	}
	LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	I2CMasterState = I2C_RESTARTED;
	break;
	
	case 0x18:			/* Regardless, it's a ACK */
	if ( I2CMasterState == I2C_STARTED )
	{
	  LPC_I2C0->I2DAT = I2CMasterBuffer[1+WrIndex];
	  WrIndex++;
	  I2CMasterState = DATA_ACK;
	}
	LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
	break;

	case 0x28:	/* Data byte has been transmitted, regardless ACK or NACK */
	case 0x30:
	if ( WrIndex != I2CWriteLength )
	{   
	  LPC_I2C0->I2DAT = I2CMasterBuffer[1+WrIndex]; /* this should be the last one */
	  WrIndex++;
	  if ( WrIndex != I2CWriteLength )
	  {   
		I2CMasterState = DATA_ACK;
	  }
	  else
	  {
		I2CMasterState = DATA_NACK;
		if ( I2CReadLength != 0 )
		{
		  LPC_I2C0->I2CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
		  I2CMasterState = I2C_REPEATED_START;
		}
	  }
	}
	else
	{
	  if ( I2CReadLength != 0 )
	  {
		LPC_I2C0->I2CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
		I2CMasterState = I2C_REPEATED_START;
	  }
	  else
	  {
		I2CMasterState = DATA_NACK;
		LPC_I2C0->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
	  }
	}
	LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x40:	/* Master Receive, SLA_R has been sent */
	LPC_I2C0->I2CONSET = I2CONSET_AA;	/* assert ACK after data is received */
	LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x50:	/* Data byte has been received, regardless following ACK or NACK */
	case 0x58:
	I2CMasterBuffer[3+RdIndex] = LPC_I2C0->I2DAT;
	RdIndex++;
	if ( RdIndex != I2CReadLength )
	{   
	  I2CMasterState = DATA_ACK;
	}
	else
	{
	  RdIndex = 0;
	  I2CMasterState = DATA_NACK;
	}
	LPC_I2C0->I2CONSET = I2CONSET_AA;	/* assert ACK after data is received */
	LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x20:		/* regardless, it's a NACK */

	case 0x48:
	LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
	I2CMasterState = DATA_NACK;
	break;
	
	case 0x38:		/* Arbitration lost, in this example, we don't
					deal with multiple master situation */
	default:
	LPC_I2C0->I2CONCLR = I2CONCLR_SIC;	
	break;
  }
}

/*****************************************************************************
** Function name:		I2CStart
**
** Descriptions:		Create I2C start condition, a timeout
**				value is set if the I2C never gets started,
**				and timed out. It's a fatal error. 
**
** parameters:			None
** Returned value:		true or false, return false if timed out
** 
*****************************************************************************/
uint32_t I2CStart( void )
{
  uint32_t timeout = 0;
  uint32_t retVal = 0;
 
  /*--- Issue a start condition ---*/
  LPC_I2C0->I2CONSET = I2CONSET_STA;	/* Set Start flag */
    
  /*--- Wait until START transmitted ---*/
  while( 1 )
  {
	if ( I2CMasterState == I2C_STARTED )
	{
	  retVal = 1;
	  break;	
	}
	if ( timeout >= MAX_TIMEOUT )
	{
	  retVal = 0;
	  break;
	}
	timeout++;
  }
  return( retVal );
}

/*****************************************************************************
** Function name:		I2CStop
**
** Descriptions:		Set the I2C stop condition, if the routine
**				never exit, it's a fatal bus error.
**
** parameters:			None
** Returned value:		true or never return
** 
*****************************************************************************/
uint32_t I2CStop( void )
{
  LPC_I2C0->I2CONSET = I2CONSET_STO;  /* Set Stop flag */ 
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;  /* Clear SI flag */ 
            
  /*--- Wait for STOP detected ---*/
  while( LPC_I2C0->I2CONSET & I2CONSET_STO );
  return 1;
}

/*****************************************************************************
** Function name:		I2CInit
**
** Descriptions:		Initialize I2C controller
**
** parameters:			I2c mode is either MASTER or SLAVE
** Returned value:		true or false, return false if the I2C
**				interrupt handler was not installed correctly
** 
*****************************************************************************/
uint32_t I2CInit( uint32_t I2cMode ) 
{
  LPC_SC->PCONP |= (1 << 19);

  /* set PIO0.27 and PIO0.28 to I2C0 SDA and SCK */
  /* function to 01 on both SDA and SCK. */
  LPC_PINCON->PINSEL1 &= ~0x03C00000;
  LPC_PINCON->PINSEL1 |= 0x01400000;	
 
  /*--- Clear flags ---*/
  LPC_I2C0->I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;    

  /*--- Reset registers ---*/
  LPC_I2C0->I2SCLL   = I2SCLL_SCLL;
  LPC_I2C0->I2SCLH   = I2SCLH_SCLH;
  if ( I2cMode == I2CSLAVE )
  {
	LPC_I2C0->I2ADR0 = ADR_BYTE;
  }    

  /* Install interrupt handler */
  NVIC_EnableIRQ(I2C0_IRQn);

  LPC_I2C0->I2CONSET = I2CONSET_I2EN;
  return( 1 );
}

/*****************************************************************************
** Function name:		I2CEngine
**
** Descriptions:		The routine to complete a I2C transaction
**				from start to stop. All the intermitten
**				steps are handled in the interrupt handler.
**				Before this routine is called, the read
**				length, write length, I2C master buffer,
**				and I2C command fields need to be filled.
**				see i2cmst.c for more details. 
**
** parameters:			None
** Returned value:		true or false, return false only if the
**				start condition can never be generated and
**				timed out. 
** 
*****************************************************************************/
uint32_t I2CEngine( void ) 
{
  I2CMasterState = I2C_IDLE;
  RdIndex = 0;
  WrIndex = 0;
  if ( I2CStart() != 1 )
  {
	I2CStop();
	return ( 0 );
  }

  while ( 1 )
  {
	if ( I2CMasterState == DATA_NACK )
	{
	  I2CStop();
	  break;
	}
  }    
  return ( 1 );      
}

/******************************************************************************
**                            End Of File
******************************************************************************/
i2c.h:
Code:
#ifndef __I2C_H 
#define __I2C_H

#define BUFSIZE			0x20
#define MAX_TIMEOUT		0x00FFFFFF

#define I2CMASTER		0x01
#define I2CSLAVE		0x02
 
#define	ADR_BYTE	0xA0
#define RD_BIT		0x01

#define I2C_IDLE			0
#define I2C_STARTED			1
#define I2C_RESTARTED		2
#define I2C_REPEATED_START	3
#define DATA_ACK			4
#define DATA_NACK			5

#define I2CONSET_I2EN		0x00000040  /* I2C Control Set Register */
#define I2CONSET_AA			0x00000004
#define I2CONSET_SI			0x00000008
#define I2CONSET_STO		0x00000010
#define I2CONSET_STA		0x00000020

#define I2CONCLR_AAC		0x00000004  /* I2C Control clear Register */
#define I2CONCLR_SIC		0x00000008
#define I2CONCLR_STAC		0x00000020
#define I2CONCLR_I2ENC		0x00000040

#define I2DAT_I2C			0x00000000  /* I2C Data Reg */
#define I2ADR_I2C			0x00000000  /* I2C Slave Address Reg */
#define I2SCLH_SCLH			0x00000080  /* I2C SCL Duty Cycle High Reg */
#define I2SCLL_SCLL			0x00000080  /* I2C SCL Duty Cycle Low Reg */

extern void I2C0_IRQHandler( void );
extern uint32_t I2CInit( uint32_t I2cMode );
extern uint32_t I2CStart( void );
extern uint32_t I2CStop( void );
extern uint32_t I2CEngine( void );

#endif /* end __I2C_H */
/****************************************************************************
**                            End Of File
*****************************************************************************/
 

Hi,
I am trying to write eeprom by using i2c, but i can't. Maybe , there is power difference between 24C256 and 24LC256. 24C256 works with +5v and 24LC256 works +3.3v. What do you think ?

No my friend voltage is not the cause, 24LC256 have voltage range from 2.5V to 5.5V, with max frequency 400KHz. 24C256 in other hand have voltage range only from 4.5V to 5.5V with max frequency of 400KHz.

You can use 5V working voltage for 24LC256 without problem, just like at 24C256.

---------- Post added at 22:18 ---------- Previous post was at 22:08 ----------

Write Protection
The WP pin allows the user to write-protect the entire array (0000-7FFF) when the pin is tied to VCC. If tied to VSS or left floating, the write protection is disabled. The WP pin is sampled at the STOP bit for every write command (Figure 1-1). Toggling the WP pin after the STOP bit will have no effect on the execution of the write cycle.

---------- Post added at 22:19 ---------- Previous post was at 22:18 ----------

Note: Page write operations are limited to writing bytes within a single physical page, regardless of the number of bytes actually being written. Physical page boundaries start at addresses that are integer multiples of the page buffer size (or ‘page size’) and end at addresses that are integer multiples of [page size - 1]. If a page write command attempts to write across a physical page boundary, the result is that the data wraps around to the beginning of the current page (overwriting data previously stored there), instead of being written to the next page, as might be expected. It is, therefore, necessary for the application software to prevent page write operations that would attempt to cross a page boundary.

See page 8
https://learning.media.mit.edu/projects/gogo/parts_pdf/EEPROM - 24LC256.pdf
 

I connected the WP pin to the VSS, so it must be able to write. I couldnt understand what the reason is?
 

I use LPC1700 BUNDLE code for i2c and for the circuit diagram I use 3.3k pull ups for clock and data. And I connect the WP pin to the ground.

what about the address lines? how are they tied gnd or VCC?
 

Adress lines are tied to GND, WP is tied to GND, SCL and SDA pins are pulled up with 3.3k resistors. I have tried with 24C256, 24LC256 and 24LC512 eeproms but i couldnt write anything.
 

At the beginning ,you said the power may have the problem. I think you should read the spec. And be sure the chip's working voltage. If the vcc on the board is 3.3v, but chip requests 4.5-5v ,it may work abnormally.
 

At the beginning ,you said the power may have the problem. I think you should read the spec. And be sure the chip's working voltage. If the vcc on the board is 3.3v, but chip requests 4.5-5v ,it may work abnormally.

And so I have then used 24LC256 that works with 3.3V same as my board , but it didn't work again. Maybe I can't recognize something wrong with my code but i can't find.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top