ARM Technical Support Knowledge Articles

ATMEL EEPROM PROGRAMMING SUPPORT

Applies to: C51 C Compiler

Answer


Information in this article applies to:


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

Article last edited on: 2007-01-12 13:15:59

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential