![]() |
Re: read/write EEPROM on 18F8520
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 |
Re: read/write EEPROM on 18F8520
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 |
Re: read/write EEPROM on 18F8520
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. |
Re: read/write EEPROM on 18F8520
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 |
Re: read/write EEPROM on 18F8520
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 |
Re: read/write EEPROM on 18F8520
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; } |
Re: read/write EEPROM on 18F8520
: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.
|
Re: read/write EEPROM on 18F8520
Quote:
|
Re: read/write EEPROM on 18F8520
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. |
Re: read/write EEPROM on 18F8520
Quote:
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 ) |
Re: read/write EEPROM on 18F8520
Quote:
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 |
Re: read/write EEPROM on 18F8520
Quote:
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 |
Re: read/write EEPROM on 18F8520
Got it.
|
Re: read/write EEPROM on 18F8520
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 |
Re: read/write EEPROM on 18F8520
Quote:
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. |
| All times are GMT -5. The time now is 21:47. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi