Keil Logo

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
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.