I've been trying to use EEPROM in my current ATmega328P project. To make sure it's working, I start with a uint32_t value of 180,000,000, write a slightly different value to EEPROM and read it back. I'm not getting back what I've written. As an experiment, I dropped the EEMEM usage and went to absolute addresses. Now I get the correct result. But I don't know why.
Original code (copied from a couple different files):
Here I define the original value of sysclk and the new value I want to write / recall from EEPROM. Then statements to do that. In reality, I did the write statement in one run, commented it out, and did the read statement.
uint32_t sysclk = 180000000UL; // uint32_t newsys = 179995960UL; // for testing (snip ...) DDS_write_osc_ee(); // A TEST WRITE TO EEPROM DID ONCE DDS_read_osc_ee(); // GET SYS CLOCK FREQ FROM EEPROM
Here I define an EEPROM location and have two short routines to write and read back my value ...
/* I'm declaring EEPROM names here. EEPROM will be handled in DDS.c because its main use is the calibration routine. */ uint32_t EEMEM sysclk_ee; // ************ Save current reference freq to EE memory **************** void DDS_write_osc_ee() { eeprom_write_dword(&sysclk_ee, newsys); // newsys is for testing } // *********** Read stored reference clock freq from EE memory ************* void DDS_read_osc_ee() { sysclk = eeprom_read_dword(&sysclk_ee); }
Changes I made to get expected results:
What I did was just hard code the read and write functions to use EEPROM address 0 instead of using the address assigned by EEMEM. It's still in the source code but I don't reference the label sysclk_ee anywhere.
// ************ Save current reference freq to EE memory **************** void DDS_write_osc_ee() { // eeprom_write_dword(&sysclk_ee, newsys); // newsys is for testing eeprom_write_dword((uint32_t*) 0, newsys); // newsys is for testing } // *********** Read stored reference clock freq from EE memory ************* void DDS_read_osc_ee() { // sysclk = eeprom_read_dword(&sysclk_ee); sysclk = eeprom_read_dword((uint32_t*) 0); }
Now that I've got it working I'm tempted to just move on, but I'd like to know what I'm doing wrong when I use EEMEM.
Thanks,
Nick