<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/17380/readwrite-eeprom-in-89s8252</link><description> I got a code, and modified it to run.. 
But i can&amp;#39;t seem to get the code correct. 
it has to do with XDATA but i can&amp;#39;t seem to get it right. 
 
#include &amp;lt;AT898252.H&amp;gt;
#include &amp;quot;lcd.c&amp;quot;


BYTE ReadEEPROM(int addr)
{
	char EEdata;
	WMCON |= 0x08; // Enable</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/122546?ContentTypeID=1</link><pubDate>Tue, 19 Oct 2004 03:50:32 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:cf560b27-becf-4a2b-ae91-7e4bf99d7d13</guid><dc:creator>John Donaldson</dc:creator><description>&lt;p&gt;&amp;quot;But _at_ doesn&amp;#39;t seem to me to add any real convenience over standard C features unless you&amp;#39;re pointer-phobic.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It allows you to locate &amp;#39;constant variables&amp;#39; in code space at known addresses without having to muck about with the linker.....&lt;br /&gt;
&lt;br /&gt;
&amp;quot;And it risks losing another thread to the complaint about how you can&amp;#39;t use _at_ with initializers :)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.....but doesn&amp;#39;t let you initialise them.&lt;br /&gt;
&lt;br /&gt;
What&amp;#39;s the point of an uninitialised constant?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/111121?ContentTypeID=1</link><pubDate>Mon, 18 Oct 2004 20:09:26 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:f2f36ec8-0028-4b8a-8205-113d9d3f68b4</guid><dc:creator>Drew Davis</dc:creator><description>&lt;p&gt;I thought about that -- but figured I might as well stick with generic techniques that work on any compiler.  I&amp;#39;ll happily use the extensions needed to take advantage of the architecture (&lt;b&gt;bit&lt;/b&gt;, &lt;b&gt;using&lt;/b&gt;, etc).&lt;br /&gt;
&lt;br /&gt;
But &lt;b&gt;_at_&lt;/b&gt; doesn&amp;#39;t seem to me to add any real convenience over standard C features unless you&amp;#39;re pointer-phobic.  And it risks losing another thread to the complaint about how you can&amp;#39;t use &lt;b&gt;_at_&lt;/b&gt; with initializers :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/96655?ContentTypeID=1</link><pubDate>Mon, 18 Oct 2004 15:39:18 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:86aac3c7-4dbc-4344-a9e2-3ca700271cda</guid><dc:creator>Andy Neil</dc:creator><description>&lt;p&gt;Or just look at the &lt;b&gt;_at_&lt;/b&gt; keyword extension.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/86972?ContentTypeID=1</link><pubDate>Mon, 18 Oct 2004 12:00:56 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:b2e5b168-8613-4cae-9f83-1752f989ab1c</guid><dc:creator>Drew Davis</dc:creator><description>&lt;p&gt;If you peek in absacc.h, you&amp;#39;ll see:&lt;br /&gt;
&lt;br /&gt;
#define XBYTE ((unsigned char volatile xdata *) 0)&lt;br /&gt;
&lt;br /&gt;
This macro is handy if you like to think of memory as an array of bytes and don&amp;#39;t want to deal with pointers.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/43003?ContentTypeID=1</link><pubDate>Sun, 17 Oct 2004 22:46:48 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:6fa8c9fd-fc1e-4fe9-aa68-244347435a48</guid><dc:creator>Crist Lime</dc:creator><description>&lt;p&gt;Forget that question..&lt;br /&gt;
I&amp;#39;ve found a working version...&lt;br /&gt;
Thanks for your help..&lt;br /&gt;
It really helped me alot..&lt;br /&gt;
&lt;br /&gt;
here&amp;#39;s a sample if anyone wants it..&lt;br /&gt;
&lt;pre&gt;
#include &amp;lt;AT898252.H&amp;gt;
#include &amp;lt;absacc.h&amp;gt;

/*
 * Return EEPROM Byte at address &amp;#39;adr&amp;#39;
 */
unsigned char ReadEEPROM (unsigned int adr)
{
  unsigned char v;

  WMCON |= EEMEN_;   //  enable EEPROM
  v = XBYTE[adr];    //  read value
  WMCON &amp;amp;= ~EEMEN_;  //  disable EEPROM
  return (v);
}


/*
 * Write EEPROM Byte &amp;#39;val&amp;#39; at address &amp;#39;adr&amp;#39;
 */
void WriteEEPROM (unsigned int adr, unsigned char val)
{
  WMCON |= (EEMEN_ | EEMWE_);     // enable EEPROM and set write bit
  XBYTE[adr] = val;               // write value
  while ((WMCON &amp;amp; EERDY_) == 0);  // wait until value programmed
  WMCON &amp;amp;= ~(EEMWE_ | EEMEN_);    // disable EEPROM and write strobe
}


unsigned char v;

void main (void)
{
  v = ReadEEPROM (0x200);         // read EEPROM address 0x200
  WriteEEPROM (0x200, 6);         // write 6 to EEPROM address 0x200
  while (1);
}

&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/43002?ContentTypeID=1</link><pubDate>Sun, 17 Oct 2004 22:01:45 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:8703a69b-7f75-49ff-985b-86ed4e27c383</guid><dc:creator>Crist Lime</dc:creator><description>&lt;p&gt;Ok. I did the adjustments as u suggested..&lt;br /&gt;
Seems there is no syntax error..&lt;br /&gt;
However I can&amp;#39;t seem to build it..&lt;br /&gt;
Alot of errors while building it..&lt;br /&gt;
&lt;br /&gt;
Heres the&lt;br /&gt;
&lt;br /&gt;
Eeprom.c&lt;br /&gt;
&lt;pre&gt;
#include &amp;lt;AT898252.H&amp;gt;

#ifndef BYTE
#define BYTE unsigned char
#endif

typedef
    volatile BYTE xdata
    Eeprom;

#define EepromEnable     0x08
#define EepromWriteEn    0x10
#define EepromEnableRead  WMCON |=  EepromEnable
#define EepromEnableWrite WMCON |=  (EepromEnable | EepromWriteEn)
#define EepromDisable     WMCON &amp;amp;= ~(EepromEnable | EepromWriteEn)

BYTE ReadEEPROM(Eeprom* addr);
void WriteEEPROM(Eeprom* addr, BYTE eeData);
void msdelay(unsigned x);

BYTE ReadEEPROM(Eeprom* addr)
{
	BYTE eeData;
    EepromEnableRead;

	eeData = *addr;

 	EepromDisable;
	return eeData;
}

void WriteEEPROM(Eeprom* addr, BYTE eeData)
{
	EepromEnableWrite;

	*addr = eeData;

	msdelay(15);
	EepromDisable;
}

void msdelay(unsigned int x)
{
    BYTE delval;
    while(x--)
    {
        delval = 123; /* Modify thisvalue to tune delay for 1mS */
        while(delval--)
            ;
    }
}
&lt;/pre&gt;
&lt;br /&gt;
And here&amp;#39;s the main test to run it Eeprom.c&lt;br /&gt;
&lt;br /&gt;
test.c&lt;br /&gt;
&lt;pre&gt;

#include &amp;lt;AT898252.H&amp;gt;
#include &amp;quot;eeprom.c&amp;quot;

void main()
{
	Eeprom* addr=0;
	BYTE b=0,eeData=0x3F;

	for(b=0;b&amp;lt;9;b++)
	{
		WriteEEPROM(*(addr+b),eeData);
	}

}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/42990?ContentTypeID=1</link><pubDate>Sun, 17 Oct 2004 16:34:47 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:9fac225e-8462-4363-81d6-40a665a4facc</guid><dc:creator>Drew Davis</dc:creator><description>&lt;p&gt;&lt;i&gt;// --&amp;gt; how do u write here?&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
You have an address in xdata space at which you wish to read and write.  A C pointer is an address.  I&amp;#39;d use a pointer rather than an int.  To turn a pointer into the thing at which it points, you &amp;quot;dereference&amp;quot; the pointer with the &amp;quot;*&amp;quot; operator:&lt;br /&gt;
&lt;br /&gt;
char* p;&lt;br /&gt;
*p = myChar;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
typedef
    volatile BYTE xdata
    Eeprom;

BYTE ReadEEPROM(Eeprom* addr)
{
	char EEdata;
	WMCON |= 0x08; // Enable EEPROM memory space

	EEdata = *addr; // Note the &amp;#39;*&amp;#39;

	WMCON &amp;amp;= 0xF7; // Disable EEPROM memory space
	return(EEdata);
}

&lt;/pre&gt;
&lt;br /&gt;
I&amp;#39;d make the style suggestion that your control bit constants should have symbolic definitions.  And it&amp;#39;s idiomatic to clear bits with an &amp;quot;&amp;amp;= ~flag&amp;quot;, which falls naturally out of those symbolic constants.  Add a little bit of consistency in the parameter and return types, and:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
typedef
    volatile BYTE xdata
    Eeprom;

#define EepromEnable     0x08
#define EepromWriteEn    0x10

// Address copied from asm example


BYTE ReadEEPROM(Eeprom* addr)
{
	BYTE eeData;

	WMCON |= EepromEnable; // Enable EEPROM memory space

	EEdata = *addr; // Note the &amp;#39;*&amp;#39;

	WMCON &amp;amp;= ~EepromEnable; // Disable EEPROM memory space

	return eeData;
}

void WriteEEPROM(Eeprom* addr, BYTE eeData)
{
	WMCON |= (EepromEnable |
                  EepromWriteEn);

	*addr = eeData; // Note the &amp;#39;*&amp;#39;
        msdelay(15);

	WMCON &amp;amp;= ~(EepromEnable |
                   EepromWriteEn);
}

&lt;/pre&gt;
&lt;br /&gt;
I&amp;#39;m tempted to define macros for the enable/disable as well, just to clean it up a bit more.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
#define EepromEnableRead  WMCON |=  EepromEnable
#define EepromEnableWrite WMCON |=  (EepromEnable | EepromWriteEn)
#define EepromDisable     WMCON &amp;amp;= ~(EepromEnable | EepromWriteEn)

BYTE ReadEEPROM(Eeprom* addr)
{
	BYTE eeData;

        EepromEnableRead;

	EEdata = *addr; // Note the &amp;#39;*&amp;#39;

        EepromDisable;

	return eeData;
}

void WriteEEPROM(Eeprom* addr, BYTE eeData)
{
        EepromEnableWrite;

	*addr = eeData; // Note the &amp;#39;*&amp;#39;
        msdelay(15);

	EepromDisable;
}


&lt;/pre&gt;
&lt;br /&gt;
No comments needed if the names are sufficiently self-explanatory.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: ReadWrite EEPROM in 89S8252</title><link>https://community.arm.com/thread/42989?ContentTypeID=1</link><pubDate>Sun, 17 Oct 2004 15:11:24 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:099a6893-54a0-4443-82ef-d9a5f07e6322</guid><dc:creator>Andy Neil</dc:creator><description>&lt;p&gt;&lt;i&gt;&amp;quot;the assembly version ... worked.&lt;br /&gt;
but didn&amp;#39;t manage to convert it into C.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Then leave it in assembler!&lt;br /&gt;
There is absolutely no point whatsoever in converting it to &amp;#39;C&amp;#39; - just to break it!!&lt;br /&gt;
&lt;br /&gt;
It is perfectly acceptable &amp;amp; normal to have a project containing both &amp;#39;C&amp;#39; and assembler modules.&lt;br /&gt;
&lt;br /&gt;
There is no problem calling assembler from &amp;#39;C&amp;#39; and &lt;i&gt;vice-versa&lt;/i&gt; - there is a whole section in the C51 &lt;b&gt;manual&lt;/b&gt; that tells you how to do it!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>