| Details | Message |
|---|
Read-Only Author Crist Lime Posted 17-Oct-2004 18:12 GMT Toolset C51 |  ReadWrite EEPROM in 89S8252 Crist Lime I got a code, and modified it to run.. But i can't seem to get the code correct. it has to do with XDATA but i can't seem to get it right.
#include <AT898252.H>
#include "lcd.c"
BYTE ReadEEPROM(int addr)
{
char EEdata;
WMCON |= 0x08; // Enable EEPROM memory space
EEdata = addr; // --> how do u write here?
WMCON &= 0xF7; // Disable EEPROM memory space
return(EEdata);
}
// To write a single byte to a location in EEPROM.
void WriteEEPROM(int addr, char EEdata)
{
WMCON |= 0x08; // Enable EEPROM memory space
WMCON |= 0x10; // Enable EEPROM memory write
addr = EEdata; --> how do u write here?
msdelay(15);
WMCON &= 0xEF; // Disable EEPROM memory write
WMCON &= 0xF7; // Disable EEPROM memory space
}
here's the assembly version..it worked.. but didn't manage to convert it into C.
WMCON DATA 96h ; watchdog and memory control register
EEMEN EQU 00001000b ; EEPROM access enable bit
EEMWE EQU 00010000b ; EEPROM write enable bit
WDTRST EQU 00000010b ; EEPROM RDY/BSY bit
ADDRESS EQU 10H
DATAS EQU 0AAH
; EEPROM read example.
;orl WMCON, #EEMEN ; enable EEPROM accesses
;mov dptr, #ADDRESS ; address to read
;movx a, @dptr ; read EEPROM
;xrl WMCON, #EEMEN ; disable EEPROM accesses
; EEPROM write example, utilizing fixed delay for write cycle.
; Delay is worst case (10 ms). Code for delay is not shown.
; Write is followed by verify (read and compare), but code to handle
; verification failure is not shown.
orl WMCON, #EEMEN ; enable EEPROM accesses
orl WMCON, #EEMWE ; enable EEPROM writes
mov dptr, #ADDRESS ; address to write
mov a, #DATAS ; data to write
movx @dptr, a ; write EEPROM
xrl WMCON, #EEMWE ; disable EEPROM writes
xrl WMCON, #EEMEN ; disable EEPROM accesses
|
|
Read-Only Author Andy Neil Posted 17-Oct-2004 21:11 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Andy Neil "the assembly version ... worked. but didn't manage to convert it into C."
Then leave it in assembler! There is absolutely no point whatsoever in converting it to 'C' - just to break it!!
It is perfectly acceptable & normal to have a project containing both 'C' and assembler modules.
There is no problem calling assembler from 'C' and vice-versa - there is a whole section in the C51 manual that tells you how to do it! |
|
Read-Only Author Drew Davis Posted 17-Oct-2004 22:34 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Drew Davis // --> how do u write here?
You have an address in xdata space at which you wish to read and write. A C pointer is an address. I'd use a pointer rather than an int. To turn a pointer into the thing at which it points, you "dereference" the pointer with the "*" operator:
char* p; *p = myChar;
typedef
volatile BYTE xdata
Eeprom;
BYTE ReadEEPROM(Eeprom* addr)
{
char EEdata;
WMCON |= 0x08; // Enable EEPROM memory space
EEdata = *addr; // Note the '*'
WMCON &= 0xF7; // Disable EEPROM memory space
return(EEdata);
}
I'd make the style suggestion that your control bit constants should have symbolic definitions. And it's idiomatic to clear bits with an "&= ~flag", which falls naturally out of those symbolic constants. Add a little bit of consistency in the parameter and return types, and:
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 '*'
WMCON &= ~EepromEnable; // Disable EEPROM memory space
return eeData;
}
void WriteEEPROM(Eeprom* addr, BYTE eeData)
{
WMCON |= (EepromEnable |
EepromWriteEn);
*addr = eeData; // Note the '*'
msdelay(15);
WMCON &= ~(EepromEnable |
EepromWriteEn);
}
I'm tempted to define macros for the enable/disable as well, just to clean it up a bit more.
#define EepromEnableRead WMCON |= EepromEnable
#define EepromEnableWrite WMCON |= (EepromEnable | EepromWriteEn)
#define EepromDisable WMCON &= ~(EepromEnable | EepromWriteEn)
BYTE ReadEEPROM(Eeprom* addr)
{
BYTE eeData;
EepromEnableRead;
EEdata = *addr; // Note the '*'
EepromDisable;
return eeData;
}
void WriteEEPROM(Eeprom* addr, BYTE eeData)
{
EepromEnableWrite;
*addr = eeData; // Note the '*'
msdelay(15);
EepromDisable;
}
No comments needed if the names are sufficiently self-explanatory. |
|
Read-Only Author Crist Lime Posted 18-Oct-2004 04:01 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Crist Lime Ok. I did the adjustments as u suggested.. Seems there is no syntax error.. However I can't seem to build it.. Alot of errors while building it..
Heres the
Eeprom.c
#include <AT898252.H>
#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 &= ~(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--)
;
}
}
And here's the main test to run it Eeprom.c
test.c
#include <AT898252.H>
#include "eeprom.c"
void main()
{
Eeprom* addr=0;
BYTE b=0,eeData=0x3F;
for(b=0;b<9;b++)
{
WriteEEPROM(*(addr+b),eeData);
}
}
|
|
Read-Only Author Crist Lime Posted 18-Oct-2004 04:46 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Crist Lime Forget that question.. I've found a working version... Thanks for your help.. It really helped me alot..
here's a sample if anyone wants it..
#include <AT898252.H>
#include <absacc.h>
/*
* Return EEPROM Byte at address 'adr'
*/
unsigned char ReadEEPROM (unsigned int adr)
{
unsigned char v;
WMCON |= EEMEN_; // enable EEPROM
v = XBYTE[adr]; // read value
WMCON &= ~EEMEN_; // disable EEPROM
return (v);
}
/*
* Write EEPROM Byte 'val' at address 'adr'
*/
void WriteEEPROM (unsigned int adr, unsigned char val)
{
WMCON |= (EEMEN_ | EEMWE_); // enable EEPROM and set write bit
XBYTE[adr] = val; // write value
while ((WMCON & EERDY_) == 0); // wait until value programmed
WMCON &= ~(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);
}
|
|
Read-Only Author Drew Davis Posted 18-Oct-2004 18:00 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Drew Davis If you peek in absacc.h, you'll see:
#define XBYTE ((unsigned char volatile xdata *) 0)
This macro is handy if you like to think of memory as an array of bytes and don't want to deal with pointers. |
|
Read-Only Author Andrew Neil Posted 18-Oct-2004 21:39 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Andrew Neil Or just look at the _at_ keyword extension. |
|
Read-Only Author Drew Davis Posted 19-Oct-2004 02:09 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Drew Davis I thought about that -- but figured I might as well stick with generic techniques that work on any compiler. I'll happily use the extensions needed to take advantage of the architecture (bit, using, etc).
But _at_ doesn't seem to me to add any real convenience over standard C features unless you're pointer-phobic. And it risks losing another thread to the complaint about how you can't use _at_ with initializers :) |
|
Read-Only Author Stefan Duncanson Posted 19-Oct-2004 09:50 GMT Toolset C51 |  RE: ReadWrite EEPROM in 89S8252 Stefan Duncanson "But _at_ doesn't seem to me to add any real convenience over standard C features unless you're pointer-phobic."
It allows you to locate 'constant variables' in code space at known addresses without having to muck about with the linker.....
"And it risks losing another thread to the complaint about how you can't use _at_ with initializers :)"
.....but doesn't let you initialise them.
What's the point of an uninitialised constant? |
|