|
|
View previous topic :: View next topic |
Author |
Message |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
New EEPROM question |
Posted: Wed Jul 28, 2004 1:20 pm |
|
|
I am using a 24C01 EEPROM to store some cal constants. I only use a small portion of the chips memory. At calibration I write a few bytes and do a checksum of the whole chip, writing the result in the last byte. On boot I do a checksum of the whole chip and the result should be 0.
Its not working.
The cal constants are correct but the checksum is bad.
Could it be that unwritten bits are unstable until they are definately written as a 0 or 1? Do I have to write the whole chip, or only checksum the bytes that are written? It seems far fetched, but maybe people who have worked with these chips before know.
Here are the functions to set the checksum, and to verify it:
Code: | int set_eeprom_checksum() { //returns final checksum, should be 0
int chksum;
chksum = read_ext_eeprom(0x7f);
chksum -= checksum_ext_eeprom();
write_ext_eeprom(0x7f, chksum);
chksum = checksum_ext_eeprom();
return(chksum);
}
int checksum_ext_eeprom() {
int data = 0;
int count;
i2c_start();
i2c_write(0xa0);
i2c_write(0);
i2c_start();
i2c_write(0xa1);
for(count = 0; count < 128; count++)
data+=i2c_read(0);
i2c_stop();
return(data);
} |
_________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 28, 2004 1:38 pm |
|
|
Quote: | Could it be that unwritten bits are unstable until they are definately written as a 0 or 1? | I don't know. I always just checksum the byte or bytes that I use. Here is a sample program.
Code: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud = 9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// Eeprom Addresses (PIC's internal eeprom).
#define EEPROM_NUM_UNITS_ADDR_0 0
#define EEPROM_NUM_UNITS_ADDR_1 1
// Min and Max number of units.
#define MIN_NUM_UNITS 2
#define MAX_NUM_UNITS 5
char read_num_units_from_eeprom(void);
//====================================
main()
{
char num_units;
num_units = read_num_units_from_eeprom();
while(1);
}
//=====================================
// This function returns the number of units
// that were saved in eeprom (2 to 5).
// It does a checksum on the value, and if
// there is an error, it will return 2 as the
// number of units.
char read_num_units_from_eeprom(void)
{
char units;
char checksum;
units = read_eeprom(EEPROM_NUM_UNITS_ADDR_0);
checksum = read_eeprom(EEPROM_NUM_UNITS_ADDR_1);
// XOR the units byte and the checksum byte together.
// If the result is 0xFF, then it's OK. If not, there's
// an error, so return 2 as the number of units.
if((units ^ checksum) != 0xFF)
{
units = MIN_NUM_UNITS;
write_eeprom(EEPROM_NUM_UNITS_ADDR_0, units);
write_eeprom(EEPROM_NUM_UNITS_ADDR_1, ~units);
}
return(units);
} |
|
|
|
Guest
|
|
Posted: Fri Jul 30, 2004 7:38 am |
|
|
Your problem is about i2c_read(0) what means a byte transfer without acknowledge. You should use i2c_read() or i2c_read(1) unless you have reached the last byte address.
Your current code says to EEPROM to terminate the transfer after the 1st byte. Just run your cycle for 127 and add an extra line with that i2c_read(0). |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|