|
|
|
![]() |
|
|||||||
|
||||||||
|
|
Thread Tools | Rate Thread | Display Modes |
|
#21
|
|||||
|
|||||
|
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; } |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Saving Data to EEPROM | Phil Roth | Programming | 28 | 27-03-2003 22:29 |