Keil™, An ARM® Company

Technical Support

C51: ATMEL EEPROM PROGRAMMING SUPPORT


Information in this article applies to:

  • C51 All Versions

QUESTION

I have written the following EEPROM access functions for the Amtel AT89C51CC03.

#include <reg51cc03.h>                // CPU register definitions

// Return EEPROM Byte at address 'adr'
unsigned char Read_8bit_EEPROM (unsigned int adr)  {
  unsigned char v;

  EA = 0;
  EECON = 0x02;    //  enable EEPROM
  v = *((unsigned char xdata *)adr);    //  read value
  EECON = 0x00;    //  disable EEPROM
  EA = 1;
  return (v);
}

// Return EEPROM 16-bit value at address 'adr'
unsigned int Read_16bit_EEPROM (unsigned int adr)  {
  unsigned int v;

  EA = 0;
  EECON = 0x02;    //  enable EEPROM
  v = *((unsigned int xdata *)adr);    //  read value
  EECON = 0x00;    //  disable EEPROM
  EA = 1;
  return (v);
}

// Return EEPROM 32-bit value at address 'adr'
unsigned long Read_32bit_EEPROM (unsigned int adr)  {
  unsigned long v;

  EA = 0;
  EECON = 0x02;    //  enable EEPROM
  v = *((unsigned long xdata *)adr);    //  read value
  EECON = 0x00;    //  disable EEPROM
  EA = 1;
  return (v);
}

// Write EEPROM 8-bit 'val' at address 'adr'
void Write_8bit_EEPROM (unsigned int adr, unsigned char val)  {
   EA = 0;
   EECON = 0x02;       // enable EEPROM and set write bit
   *((unsigned char xdata*)adr) = val;   // write value
   EECON = 0x50;
   EECON = 0xA0;
   EECON = 0x00;       //  disable EEPROM
   EA = 1;
}

// Write EEPROM 16-bit 'val' at address 'adr'
void Write_16bit_EEPROM (unsigned int adr, unsigned int val)  {
  EA = 0;
  EECON = 0x02;       // enable EEPROM and set write bit
  *((unsigned int xdata *)adr) = val;   // write value
  EECON = 0x50;
  EECON = 0xA0;
  EECON = 0x00;       //  disable EEPROM
  EA = 1;
}

// Write EEPROM 32-bit 'val' at address 'adr'
void Write_32bit_EEPROM (unsigned int adr, unsigned long val)   {
  EA = 0;
  EECON = 0x02;        // enable EEPROM and set write bit
  *((unsigned long xdata *)adr) = (val);   // write value
  EECON = 0x50;
  EECON = 0xA0;
  EECON = 0x00;        //  disable EEPROM
  EA = 1;
}

All functions work fine in the SMALL memory model, but in the LARGE memory model the 32-bit access functions seem to fail. What can be the reason for that?

ANSWER

The LARGE memory model locates automatic variables to the XDATA memory space. The instruction EECON = 0x02 disables the on-chip XDATA RAM, so it is no longer available. Therefore the code may fetch unpredictable values from the overlaying EEPROM space.

Since 32-bit access functions require additional memory (the other functions allocate all variables to CPU registers), these functions fail only in the LARGE memory model. As a solution to your problem you may use explicit memory model specifications.

// Return EEPROM 32-bit value at address 'adr'
unsigned long Read_32bit_EEPROM (unsigned int adr) small  {
  unsigned long v;

  EA = 0;
  EECON = 0x02;    //  enable EEPROM
  v = *((unsigned long xdata *)adr);    //  read value
  EECON = 0x00;    //  disable EEPROM
  EA = 1;
  return (v);
}

// Write EEPROM 32-bit 'val' at address 'adr'
void Write_32bit_EEPROM (unsigned int adr, unsigned long val) small  {
  EA = 0;
  EECON = 0x02;        // enable EEPROM and set write bit
  *((unsigned long xdata *)adr) = (val);   // write value
  EECON = 0x50;
  EECON = 0xA0;
  EECON = 0x00;        //  disable EEPROM
  EA = 1;
}

MORE INFORMATION

SEE ALSO

Last Reviewed: Friday, January 12, 2007


Did this article provide the answer you needed?
 
Yes
No
Not Sure