Log in

View Full Version : read/write EEPROM on 18F8520


WizardOfAz
11-11-2003, 18:04
Anybody that knows how to do it want to summarize how to read and write the EEPROM on the 18F8520?

There are some functions in the C18 libraries for EE access, but looks like they use I2C and I don't thinks that's needed for the on-chip EEPROM. The compiler also has provision for declaring variables in EEPROM (the rom storage qualifier) and says it generates the TBLWT instruction to write to it, but warns that there may be more code than that requires. Indeed, the 18F8520 data sheet gives all the details, using special regs EECON1, EECON1, TABLAT and TBLPTR. So do we drop into assembly to use EEPROM or is there some library support for it? Anybody want to provide the functions?

EDIT: it's actually EECON1, EECON2, EEDATA, EEADRH, EEADR that are used for EEPROM access. The regs noted above are for accessing program flash memory.

Also - the data sheet says we have 1024 bytes of EEPROM. Why does IFI say we only have 255 bytes? Is the rest of it reserved for their use or is it a typo or what?

Thanks for any help.

Bill Bennett

Random Dude
11-11-2003, 21:02
As to why they claim you only have 255 bytes? I don't know. There appears to be nothing in there at all. And I can write to bytes >0xFF so not really sure


This should suit you needs:



unsigned char readEE(unsigned char addrH,unsigned char addrL) {
EEADRH = addrH;
EEADR =addrL;


EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.RD =1;


return EEDATA;
}

void writeEE(unsigned char addrH,unsigned char addrL,unsigned char data)
{
EEADRH = addrH;
EEADR =addrL;
EEDATA = data;

//following as per spec. sheet
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
}

WizardOfAz
12-11-2003, 00:22
Thanks for the code.

I suppose the reason you don't have to block interrupts throughout both functions is that interrupt state save process saves and restores the registers, but you have to make sure the write process itself is not interrupted, which could corrupt the slow write if the address or data was changed before it completed.

Thanks again.

IrisLab
16-12-2003, 02:22
Couple of questions...

1. Can you explain addrH, addrL, and data a little more? For readEE, are these the locations of the high and low byte in the EEPROM where you want to write? What are typical values for these addresses, if so? For writeEE same thing?

2. I read in another thread that you (or someone) is developing a copyCat (?) where you'd record user input into the EEPROM. How big (bytes) is the EEPROM? Do you have sample code for the CopyCat?

I'm new to the forum...so I hope I'm asking the right questions in the right place.

Thanks!


As to why they claim you only have 255 bytes? I don't know. There appears to be nothing in there at all. And I can write to bytes >0xFF so not really sure


This should suit you needs:



unsigned char readEE(unsigned char addrH,unsigned char addrL) {
EEADRH = addrH;
EEADR =addrL;


EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.RD =1;


return EEDATA;
}

void writeEE(unsigned char addrH,unsigned char addrL,unsigned char data)
{
EEADRH = addrH;
EEADR =addrL;
EEDATA = data;

//following as per spec. sheet
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
}

Random Dude
16-12-2003, 13:13
Couple of questions...

1. Can you explain addrH, addrL, and data a little more? For readEE, are these the locations of the high and low byte in the EEPROM where you want to write? What are typical values for these addresses, if so? For writeEE same thing?


Here is a slightly improved version of the read/write function. I've combined addrH and addrL into address. Valid values for address should be 0-1024 (since the size of the EEPROM is 1KB). (IFI originally said that it was only 256 but they have since corrected their mistake)

data can be any char value (0:255 for unsigned; -128:127 for signed)

This is applicable to both readEE() and writeEE()


char readEE(unsigned short address) {

// Load address into address register
EEADRH = ((address>>8)&0x03); //Bits 2-7 are masked off since EEPROM is only 1KB
EEADR =(address&0xFF);

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.RD =1;


return EEDATA;
}

void writeEE(unsigned short address, char data)
{
EEADRH = ((address>>8)&0x03);
EEADR =(address&0xFF);
EEDATA = data;

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
}




2. I read in another thread that you (or someone) is developing a copyCat (?) where you'd record user input into the EEPROM. How big (bytes) is the EEPROM? Do you have sample code for the CopyCat?


EEPROM size is 1024 bytes (1KB)

I am not the person working on the CopyCat program. Post in this thread (http://www.chiefdelphi.com/forums/showthread.php?t=22928) for any questions on CopyCat.


I'm new to the forum...so I hope I'm asking the right questions in the right place.

Thanks!


Welcome! And, yes you are in the right location.

mightywombat
20-12-2003, 13:16
I am still learning and acquainting myself with all these crazy ideas about EEPROM and ROM and RAM and memory locations and all that stuff. I know how to program in C and have written some code for the eduBOts but its nothing too advanced. I want to load a table/list of sin values (0:90 degrees, to maybe 3 or 4 place accuracy) into ROM so that I can access it from my main program loop. When and how do I read it in? I understand that you use the above read and write functions but WHERE and WHEN do you use them?

WizardOfAz
20-12-2003, 19:25
Although you might want to finish understanding how to manage the ram, program memory, and eeprom, eeprom is probably not the best choice for your sine table. The C compiler allows putting read-only data in program memory. The loader will automatically put your table in program rom, and the compiler will automatically generate the appropriate code to access it there. This would be the easiest way to do your sin table. You wouldn't have to read it in or anything special. Just declare it to be in rom, like this:

unsigned char /* or whatever you want */ rom sinTable[256] = {0, 5, 10, 15, ... more table values...};

The rom keyword will cause this table to be stored in rom rather than ram, the latter being the much more limited resource. Declared this way, you can access it in C just like any other array. Just don't try to store to it.

Now, if you really want to put it in EEPROM, the simplest way would be to declare the table as above, run a for loop to copy the table to EEPROM using writeEE provided by Random Dude in the prior post. Download the program and run it, just once, and the EEPROM will be saved until changed by some other program. After that download a program that accesses the table using readEE.

A more typical use for the EEPROM would be, for example, calibration of a resistive sensor. If for some reason the sensor calibration changes often, you could have code that is always loaded that can run a calibration sequence and store the resulting data in EEPROM, and the normal runtime could access the current calibration from that table.

Have fun.

Bill

mightywombat
20-12-2003, 20:00
AH-HA. I had misunderstood what the EEPROM was. As I understand it now it is 1KB of space where you put code that is run every time the bot is powered on?? No. That doesn't seem quite right. I'm not sure. I guess I thought that EEPROM was just the ROM, but its something different. Is there any threads out there or webpages that I can read that deal with RAM ROM EEPROM and memory storage to clarify my young mind?
thanks. you rock.
Bill

WizardOfAz
20-12-2003, 20:36
You can't put code in the EEPROM, there's no provision for executing it there. It's 1K of space where you can put "stuff" that you want to be there even after the power is turned off and back on. In that sense, it's not very different than program rom. The main distinction is that it's a little harder to read than data stored in program memory, but easier for your program to write.

To elaborate a bit on the sensor calibration, as an example of what the EEPROM is good for: We are building a prototype that has steering sensors on the wheels. The mechanical alignment of the sensors is hard to predict accurately, and likewise the proportional relationship between the sensor readout and the angular position is hard to know in advance. So we have a calibration routine that can be run at any time by a switch at the OI. During this calibration routine, the operator can put the wheels at several specific positions and "click" the joystick trigger to store the sensor reading at those positions in EEPROM. These readings are later used to interpolate the angle to a reasonable accuracy during regular operation of the 'bot.

A reasonable rule of thumb for the ram, program rom, and eeprom is:
- program rom for code, and for data known at compile time
- ram for read/write variables at run time
- eeprom for data that is determined at run time and needs to be stored permanently so it is known at next run of the 'bot

Hope this helps clarify.

Bill

mightywombat
21-12-2003, 11:14
Those last three lines made it soooo clear. Thanks so much for your help and assistance. One last question. If I read something into ROM will it still be there the next time I turn on the bot?

WizardOfAz
21-12-2003, 17:03
Program rom and EEPROM are both non-volatile memory - they will be there, even through a power off/on sequence, until re-written with new data. Variables in ram go away of course.

Bill

mightywombat
21-12-2003, 21:19
Alrighty. With any luck this will be my final question. We have 1800 bytes of variable space. Is there any set space for RAM and ROM? Or can you declare any amount of RAM and ROM as long as it isn't more that 1800 bytes?

WizardOfAz
21-12-2003, 22:37
Program rom is 32k. This is all the all the program you write, plus any data you declare as rom, plus any library code you link in (in the default code, this is clib.lib and 18f8520user.lib). The default framework takes about 8k, so if you don't change that, you've got about 24k for your program and rom data.

The program rom usage can be examined in the .map file produced after you do a build. It's not real nice to read, but look for the lines after "program memory usage" for a simple summary of how much you're using.

Your non-rom variables go in the 1800 bytes of ram. I don't see any nice summary of total usage for this, but look at the lines for "DATA". I also haven't figured out why the number is 1800, the chip has 2048 bytes. Maybe what they're saying is library code needs 200 bytes, and there's 1800 bytes left. Not sure.

The EEPROM is 1024 bytes, and usage won't show up in the link map, since the addresses are all generated at run time. The linker doesn't know anything about this. Your program has to determined what is stored at 0, what at 1, and so on.

Bill

WizardOfAz
10-01-2004, 18:40
A little more info about writing the EEPROM - it takes time. To write one byte takes about 4 ms. Since the loop time is 26 ms (or 17 on the EDU-RC), if you try to write a few bytes at once, you use up more than all of the time. Even worse, if you don't wait for the write to finish, only the first write will work.

I am working on some code to keep a small queue of bytes to write that will wait for each to write before writing the next. Will post when I think it's working. Anybody else have thoughts on how best to manage this issue?

Bill

Larry Barello
10-01-2004, 22:21
Section 7.2 of the data sheet mentions an EEwrite complete interrupt.

WizardOfAz
12-01-2004, 15:00
I don't yet have EEPROM read and write working reliably. It works erratically, and I've not yet figured out what I'm doing wrong. I found this couple of paragraphs in the 18Fxx20 data sheet, which I can't make sense of. I doubt it's related to my problem, but would anyone like to try to interpret it?

This is it:
7.8 Using the Data EEPROM
The data EEPROM is a high endurance, byte addressable
array that has been optimized for the storage of
frequently changing information (e.g., program variables
or other data that are updated often). Frequently
changing values will typically be updated more often
than specification D124. If this is not the case, an array
refresh must be performed. For this reason, variables
that change infrequently (such as constants, IDs, calibration,
etc.) should be stored in FLASH program
memory.

A simple data EEPROM refresh routine is shown in
Example 7-3.

Note: If data EEPROM is only used to store constants
and/or data that changes rarely, an
array refresh is likely not required. See
specification D124.

(specification D124 is missing from the 18Fxx20 data sheet, but is included in the errata)

Param=D124 Sym=TREF Characteristic=Number of Total Erase/Write Cycles before Refresh(4)
min=1M typ=10M (no max) unit=E/W Conditions -40°C to +85°C

BananaMango777
12-01-2004, 15:19
Typically what you do is have a buffer (a location in conventional flash memory) which stores data in a que structure to be written to the eeprom. Then you write a procedure for the "on finish eeprom write" interrupt to check whether there is anything in the que and then write it if there is. By using interrupts you do not waste processing time using loops etc for things to be written to the eeprom as you can execute a lot of code in a few ms.
Am I right in assuming you are writing the majority of you're code using the c compiler? Our team will be writing in assembler as most of us have experience using the pic microcontrollers for various projects etc. I can write some working code in assembler which will do what I have described above and get it on the forum asap.

The pic datasheets really are very useful, I would advise that you read the eeprom section which explains about the special registers associated with writing to the internal eeprom and the interrupts available.

Hope this helps.. and good luck

WizardOfAz
12-01-2004, 15:33
Hi, thanks. I did read the data sheet about EEPROM, and mostly understand it, but the section I pasted from the data sheet in my previous post was pretty confusing. I'm looking for someone else's interpretation.

Also, I am working on a queued method of writing the EEPROM and have it mostly working. So unless you really want to, no need to write one for me. I will post mine when I think it's done and working.

BananaMango777
12-01-2004, 18:23
to be honest... unless you want to store data for analysis later, its far easier just to use the flash memory as its far quicker and easier to use within the code quickly. As it is the control board has a backup battery which keeps the pic powered all the time, in sleep mode whic requires somethink like <10uA If I remember correctly. Although I supose It depends on what you are doing, best of luck anyway, I hadn't intended writing the code yet so I wont bother writing the library file if you are already in the process. Don't hesitate to post questions etc as I'm a bit of a Hex basher and like doing this kind of thing for fun in my spare time and can normally shed some light on most problems :D

Have fun

BananaMango777
12-01-2004, 18:37
basically what that extract says in plain english:

- you can store data in byte addressable locations.. i,e. a memory address FF
- it is non volatile and you can have many reads/writes using eeproms - typically they have a lifetime of around 10,000 writes/flashes
- for data that does not change indefinately such as constants, flash memory should be used, or you can refresh the eeprom to varify the data integrity... (this really doesnt apply for first :D... data in eeprom is good for a few years or so, depending on the technology).. Refreshing eeprom basically puts a voltage accross the array such that all the data is completely erased and then rewritten to verify the integrity of the data. This should be done every X writes (stated in the datasheet) to remove stray charges that may build up after multiple writes, which could corrupt the data written.

The figures at the bottom state the environment for which the time stated in D124... (which is a microchip app note common for pics using the same eeprom technology) is true for... i.e. at this temp, humidity etc you need t refresh you'r e eeprom every Xmonths/years/whatever (this will be a long time... way way beyond the actual event if you were to program the pic now for a single write ;)... or how many writes you have before you need to refresh to be safe)


For more info look up "refreshing" and RAM... computers do this all the time to keep your ram in your computer happy as its volatile, i.e. the data is only good for so long before you need to refresh it otherwise you lose the data...
Hope this is useful

WizardOfAz
13-01-2004, 02:14
What we're using the EEPROM for is to store calibration data for steering sensors. If we do any adjustment on the wheel mechanism, the alignment of the wheel to the sensor can change, and I want a way to collect and save away the sensor angle offset from the wheel angle without requiring a programmer's help to modify the constants in the code and recompile/reload it.

I've got this code working now as far as I can tell. Here it is for anybody interested. I'm wide open to feedback if anybody finds a problem with it or wants to suggest an improvement.

readEE returns the result immediately, since there is no required delay for reading. But you can't change the ee address register while a write is in progress, so readEE returns 0 if a write is in progress. This doesn't help of course, you really need to just make sure you don't do this.

writeEE puts the byte to be written on a 16 byte queue in ram, then calls processEEQueue which starts the EE write sequence. If you then call writeEE more times without some delay, the byes get added to the queue but processEEQueue does not write them since the first one is not finished writing. You have to call processEEQueue again later, multiple times with some delay between to get them all written. It doesn't hurt to call processEEQueue too much, it returns quickly if the queue is empty. What I did it call processEEQueue every time around in the main loop.

(sorry for the lack of indentation - the cut/paste into the forum threw them away)

file eeprom.h
------------
#ifndef _eeprom_h
#define _eeprom_h
#include "ifi_picdefs.h"
unsigned char readEE(unsigned short address);
void writeEE(unsigned short address, unsigned char data);
void processEEQueue(void);
#endif

file eeprom.c
------------
#include <string.h>
#include "eeprom.h"

/************************************************** ******************************/
/* read and write eeprom */
/* basic code donated by "random dude" and obtained from chiefdelphi forums */
/* queing mechanism added by bill */
/************************************************** ******************************/
typedef struct {
unsigned writeInProgress:1;
unsigned bufferNotEmpty:1;
unsigned bufferFull:1;
unsigned :4;
unsigned bufferPtr:4;
unsigned bufferEnd:4;
unsigned char dataBuffer[16];
unsigned short addressBuffer[16];
} eeControlStruct;
static eeControlStruct eeControl = {0,0,0,0,0,0,}; // initialize control bits and pointers to false

unsigned char readEE(unsigned short address) {

// should not change EEADR/EEADRH while a write is happening
if(eeControl.writeInProgress) return 0;

// Load address into address register
EEADRH = (unsigned char)(address>>8);
EEADR = (unsigned char)(address&0xFF);

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.RD =1;
return EEDATA;
}

void writeEE(unsigned short address, unsigned char data)
{
if(eeControl.bufferFull) return;
eeControl.dataBuffer[eeControl.bufferEnd] = data;
eeControl.addressBuffer[eeControl.bufferEnd++] = address;
eeControl.bufferFull = (eeControl.bufferEnd==eeControl.bufferPtr);
eeControl.bufferNotEmpty = 1;
processEEQueue();
}

// call this once each main loop, or more often, to process the queue
// of bytes to be written to eeprom. Note that there is no buffer
// overrun detection. Enlarge the buffer and change the size of bufferPtr
// and bufferEnd if you need more buffer space to avoid overrun.
void processEEQueue(void) {

if(eeControl.writeInProgress && !PIR2bits.EEIF) return; // previous write not complete
PIR2bits.EEIF = 0; // reset EE write done interrupt flag
if(!eeControl.bufferNotEmpty) {
eeControl.writeInProgress = 0;
return;
}

// OK, previous write is done and something is in the buffer, write it
eeControl.writeInProgress = 1;

// Load address into address register
EEADR = (unsigned char)(eeControl.addressBuffer[eeControl.bufferPtr]&0xff);
EEADRH = (unsigned char)(eeControl.addressBuffer[eeControl.bufferPtr]>>8);
EEDATA = eeControl.dataBuffer[eeControl.bufferPtr++];
eeControl.bufferNotEmpty = (eeControl.bufferPtr != eeControl.bufferEnd);

// with a little more work, we could check for error on previous write and redo it

// write sequence as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
}

Paul
20-01-2004, 16:55
:confused: I was going over the code given on this post and I was wondering what memory address's are avalible to write to? And how much information can be fit into a single address when using unsigned chars? Any help would be appreciated.

Mike Betts
20-01-2004, 17:41
:confused: I was going over the code given on this post and I was wondering what memory address's are avalible to write to? And how much information can be fit into a single address when using unsigned chars? Any help would be appreciated.

I have not looked at the Wizard's code, but traditionally, one byte (8 bit or (un)signed char) is one address location. Words, AKA 16 bit values such as integers) will take up two adjacent addresses. Most processors will require words to be aligned on even address boundries.

Astronouth7303
20-01-2004, 17:48
A few questions:
a. What's EEADRH, EEADR, EEDATA, EECON2, and the rest of it? :confused:
b. what's the >> in "EEADRH = ((address>>8)&0x03);"? :confused: :o

And yes, I should probably know already.

Random Dude
20-01-2004, 18:21
A few questions:
a. What's EEADRH, EEADR, EEDATA, EECON2, and the rest of it? :confused:
b. what's the >> in "EEADRH = ((address>>8)&0x03);"? :confused: :o

And yes, I should probably know already.


a: those are registers in the micro. See the doc linked someplace earlier in this thread for a little more detail.

b: (address>>8) bit shifts 'address' 8 bits to the right ( the << operator does shifts to the left )

WizardOfAz
21-01-2004, 00:30
:confused: I was going over the code given on this post and I was wondering what memory address's are avalible to write to? And how much information can be fit into a single address when using unsigned chars? Any help would be appreciated.

Addresses 0 through 1023 are available in EEPROM. Each stores one byte, which is a char or unsigned char, whatever you like. 8 bits. If the data you're trying to store is already 8 bits like you say, it's pretty easy. Just do
writeEE(someAddress, someChar);

If you want to store a value that is more than 8 bits, like a 16 bit short or int, or a 32 bit long, you have to break it up into bytes first. And be careful with sign management. The cleanest way, I think, to store both bytes of an int would be like this:
int i;
...
writeEE(someAddress, (unsigned char)(((unsigned int)i)>>8)); // write high byte
writeEE(someAddress+1, (unsigned char)(((unsigned int)i)&0xff)); // write low byte

To get that int back out of EEPROM later, use this sequence:
i = (int)(((unsigned short)readEE(someAddress)<<8)
+ readEE(someAddress+1));

But also read what I said about delays in writing. If you want to use my code above and have more than 16 bytes to write, you'll have to either make the buffer bigger or figure out some other way to time it.

Did that help or add confusion?

Bill

WizardOfAz
21-01-2004, 00:36
A few questions:
a. What's EEADRH, EEADR, EEDATA, EECON2, and the rest of it? :confused:
b. what's the >> in "EEADRH = ((address>>8)&0x03);"? :confused: :o

And yes, I should probably know already.

Those EE names are defined in ifi_picdefs.h.
EEADRH is the high byte of the EEPROM address to be read or written
EEADR is the low byte of the address
EEDATA is the data going in or out of EEPROM
EECON1 and EECON2 are control registers used to do EEPROM operations

>> is shift right, << is shift left
((address>>8)&0x03 says divide address by 256 (that's the shift right 8 part) and zero out all but the lowest two bits (that's the &0x03 part).

Bill

Astronouth7303
21-01-2004, 07:33
Got it.

WizardOfAz
21-01-2004, 09:59
I noticed there are (at least) two minor flaws in the code above, neither of which would break it.
(1) string.h is not needed. It's there because I had a memset in the code at one point, then got rid of it and didn't remove the include
(2) in the eeControlStruct structure, the line "unsigned :4;" should be "unsigned :5;". The purpose is to get the 4 bit numbers aligned so that the compiled code to access them will be efficient. Maybe the compiler aligned it anyway, I don't know.

Anyway, the code works w/o these changes, since our system uses it with correct results. But I saw them and wanted to pass along the changes to the thousands of you that are using this by now [;-)

Bill

Paul
21-01-2004, 22:06
Addresses 0 through 1023 are available in EEPROM. Each stores one byte, which is a char or unsigned char, whatever you like. 8 bits. If the data you're trying to store is already 8 bits like you say, it's pretty easy. Just do
writeEE(someAddress, someChar);

If you want to store a value that is more than 8 bits, like a 16 bit short or int, or a 32 bit long, you have to break it up into bytes first. And be careful with sign management. The cleanest way, I think, to store both bytes of an int would be like this:
int i;
...
writeEE(someAddress, (unsigned char)(((unsigned int)i)>>8)); // write high byte
writeEE(someAddress+1, (unsigned char)(((unsigned int)i)&0xff)); // write low byte

To get that int back out of EEPROM later, use this sequence:
i = (int)(((unsigned short)readEE(someAddress)<<8)
+ readEE(someAddress+1));

But also read what I said about delays in writing. If you want to use my code above and have more than 16 bytes to write, you'll have to either make the buffer bigger or figure out some other way to time it.

Did that help or add confusion?

Bill

It did help out, however there is one problem. When I write to the eeprom and try to play back from it using the readEE function it doesn't seem to work. I think my memory addresses are off. Would this be an acceptable way of using the writeEE function?
writeEE(0x00,somechar);
or would i have to write it like this?
write(&0x00,somechar);
Thanks for clearing some of the other stuff for me.

Random Dude
21-01-2004, 22:21
It did help out, however there is one problem. When I write to the eeprom and try to play back from it using the readEE function it doesn't seem to work. I think my memory addresses are off. Would this be an acceptable way of using the writeEE function?
writeEE(0x00,somechar);
or would i have to write it like this?
write(&0x00,somechar);
Thanks for clearing some of the other stuff for me.


The former:

writeEE(0x00,somechar);

WizardOfAz
21-01-2004, 23:29
It did help out, however there is one problem. When I write to the eeprom and try to play back from it using the readEE function it doesn't seem to work. I think my memory addresses are off. Would this be an acceptable way of using the writeEE function?
writeEE(0x00,somechar);
or would i have to write it like this?
write(&0x00,somechar);
Thanks for clearing some of the other stuff for me.

Like RandomDude says, it's writeEE(0x00, somechar);

But a couple more comments.

Make sure you've included eeprom.h, since without the function prototype, the 0x00 may push a byte on the stack for the address parameter.

Also, note that doing the write takes time, several milliseconds. If you do a writeEE immediately followed by readEE it won't work. If you'd like to send a bigger code sample I'll be happy to look at it.

Bill

Paul
22-01-2004, 14:49
Like RandomDude says, it's writeEE(0x00, somechar);

But a couple more comments.

Make sure you've included eeprom.h, since without the function prototype, the 0x00 may push a byte on the stack for the address parameter.

Also, note that doing the write takes time, several milliseconds. If you do a writeEE immediately followed by readEE it won't work. If you'd like to send a bigger code sample I'll be happy to look at it.

Bill
Thanks, I'll continue working on the problem I'm having. If I still don't have any luck I'll be sure to post that part of the code.

zeep25
14-02-2004, 15:38
I used the code that Wizard posted in the second page and im having a little problem ... i added the eeprom.c and eeprom.h ... and included them ... this is my code right now :


int i=0;
int g=999;
void Default_Routine(void)
{
if (i==0)
{
writeEE(0x00, "23");
i=1;
printf("----- %d \n",i);
}
else
{
g=readEE(0x00);
printf("----- %d \n",g);
}

} /* END Default_Routine(); */


i even tried changing the code into :


int i=0;
void Default_Routine(void)
{
if (i==0)
{
writeEE(0x00, "23");
i=1;
printf("----- %d \n",i);
}
else
{
printf("----- %d \n",readEE(0x00));
}

} /* END Default_Routine(); */


in the console window i see the i = 1 meaning that it went over the writing code and hopefully wrote the value in 0x00 ... but when it tries to read ... it shows the output as 0 ... for some reason its not writing to 0x00 block ... thats what im thinking .. any suggestions ?? comments

gnormhurst
15-02-2004, 20:44
I used the code that Wizard posted in the second page and im having a little problem ... i added the eeprom.c and eeprom.h ... and included them ... this is my code right now :


...
writeEE(0x00, "23");



writeEE expects an "unsigned char" type for the data item, but you are passing a string literal (due to the quotations). Try this:

writeEE(0x00, 23 );
Note also that writing to flash is not instantaneous -- the value won't be ready to read for some period of time. You should also included a call to

processEEqueue();
somewhere in the main 26.2 ms loop.

-Norm

gnormhurst
15-02-2004, 20:50
A HUGE THANKS! to Random Dude and Wizard of AZ for this code. It works great, and it saved me HOURS, nay, DAYS of work. And I really needed it. I bet a lot of people do.

-Norm

Paul
15-02-2004, 21:45
Wow... I just wanna say thank you for including that little part about the processEEqueue(); I know from experience what happens when you don't include that little bit of code lol.... my edubot went in circles randomly haha. Thanks for the nifty little bit of code. :D

WizardOfAz
16-02-2004, 01:12
Glad the code is of use to some teams. And sorry I didn't respond sooner. I actually went 24+ hours w/o reading email.

The "23" as a parameter will have caused a problem. That causes a pointer (address) to the string to be passed, not even close to what you want. And the first byte of the address was probably a zero, resulting in writing zero to that EE address.

Make sure to use
#include "eeprom.h"
which would have caught that mistake, since the compiler would have know that an unsigned char should be passed and you passed a pointer to char.

If you're going to write just one byte per 26 ms loop, you actually don't need to call processEEQueue, since writeEE itself calls it. Only if you call writeEE multiple times in quick succession (in a single loop) should you have to call processEEQueue. In your example, since you called writeEE in one loop then readEE in subsequent loops, except for the issue with "23" it should have worked.

Bill

nov787
21-03-2004, 16:40
Are you guys using EEPROM for CopyCat or other purposes?

WizardOfAz
22-03-2004, 13:32
Are you guys using EEPROM for CopyCat or other purposes?

We use it this year for two things. First, the way our steering position sensors are set up, we have to know how the wheels were steered when the bot was turned off in order to avoid a recalibration sequence when we power on. So we store the steering position in EEPROM every 5 seconds when it is changing.

Second, we have an 8 bit code that indicates how we want to run autonomous mode in the upcoming game, and an OI interface for setting it. This mode byte gets stored in EEPROM so we can power down after setting it but still remember run the correct autonomous mode in the game.

Last year we had a program that would save driver inputs to EEPROM during a driver period and play it back autonomously, but didn't rewrite that one this year.

Bill