Tip on storing initial values in EEPROM

AVR microcontroller have EEPROM memory built in which adds a lots of abilities storing constant values, calibration data, and other data that may be read and changed at any time during program flow. Ion couple projects I have used EEPROM for storing last device configuration, eg. in TDA7313 volume, BASS, TREBLE input and output channel information is updated each time when it has been changed. After device si turned ON it reads last saved settings from EEPROM memory and restores last device state. But what happens when you turn device for the first time. It has to read initial values that has to be stored or it wil read 'FF' what may lead to crash or something else. One way is to prepare separate *.eep file with initial EEPROM data and then burn it separately to microcontrollers EEPROM. But this may not be always handy.

So this is simple trick how to store initial values to EEPROM at very first microcontroller run and skip this part later without additional files need to be flashed in. Probably other are doing a bit differently, this is how I do.

#include <avr/eeprom.h>

//Define EEPROM locations for restoring state

#define E_VOLUME 0

#define E_LF 1

#define E_RF 2

#define E_LR 3

#define E_RR 4

#define E_ch 5

#define E_BASS 6

#define E_TREBLE 7

#define E_INIT 8

After main() I add following code

//------EEPROM initial values-------------

if (eeprom_read_byte((uint8_t*)E_INIT)!='T')

{

eeprom_write_byte((uint8_t*)E_VOLUME,0x0F);//0dB

eeprom_write_byte((uint8_t*)E_LF,0x80);//0dB

eeprom_write_byte((uint8_t*)E_RF,0xA0);//0dB

eeprom_write_byte((uint8_t*)E_LR,0xC0);//0dB

eeprom_write_byte((uint8_t*)E_RR,0xE0);//0dB

eeprom_write_byte((uint8_t*)E_ch,0x58);//ch1 0dB, Loudness OFF

eeprom_write_byte((uint8_t*)E_BASS,0x6F);//0dB

eeprom_write_byte((uint8_t*)E_TREBLE,0x7f);//0dB

eeprom_write_byte((uint8_t*)E_INIT,'T');//marks once that eeprom init is done

//once this procedure is held, no more initialization is performed

}

//--------Restore values from EEPROM------

ST.value[0]=eeprom_read_byte((uint8_t*)E_VOLUME);

ST.value[1]=eeprom_read_byte((uint8_t*)E_BASS);

ST.value[2]=eeprom_read_byte((uint8_t*)E_TREBLE);

ST.value[3]=eeprom_read_byte((uint8_t*)E_ch);

ST.value[4]= ST.value[3]&0b00011000;//restore gain

ST.LD=ST.value[3]&0b00000100;//restore Laudness

ST.MT=0;//default Mute OFF

ST.value[5]=eeprom_read_byte((uint8_t*)E_LF);

ST.value[6]=eeprom_read_byte((uint8_t*)E_RF);

ST.value[7]=eeprom_read_byte((uint8_t*)E_LR);

ST.value[8]=eeprom_read_byte((uint8_t*)E_RR);

-EEPROM initial values- block is executed only once. It initializes first values for the first time and sets 'T' flag at E_INIT EEPROM address. Second block - Restore values from EEPROM- now can read values initialized and continue normal program flow. So next time program is started it skips EEPROM initialization block as there si already E_INIT flag set to 'T'. This way EEPROM data can be initialized for any situation from a single source file if needed.

Comments

#include <avr/io.h>#include "avr\iom8.h"#define F_CPU 8000000UL#include <util/delay.h>
int main(void){DDRA=0XFF;                                            while(1){ PORTA=0; _delay_ms(500);PORTA=255; _delay_ms(500);}}
this program not run on atmega32a and this is massege error
 
rm -rf test3.o  test3.elf dep/* test3.hex test3.eep test3.lss test3.mapBuild succeeded with 0 Warnings...avr-gcc  -mmcu=atmega32a -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT test3.o -MF dep/test3.o.d  -c  ../test3.cunknown MCU 'atmega32a' specifiedKnown MCU names:   avr2   at90s2313   at90s2323   at90s2333   at90s2343   attiny22   attiny26   at90s4414   at90s4433   at90s4434   at90s8515   at90c8534   at90s8535   avr25   attiny13   attiny2313   attiny24   attiny44   attiny84   attiny25   attiny45   attiny85   attiny261   attiny461   attiny861   attiny43u   attiny48   attiny88   at86rf401   avr3   atmega103   at43usb320   at43usb355   at76c711   avr35   at90usb82   at90usb162   avr4   atmega8   atmega48   atmega48p   atmega88   atmega88p   atmega8515   atmega8535   atmega8hva   at90pwm1   at90pwm2   at90pwm2b   at90pwm3   at90pwm3b   avr5   atmega16   atmega161   atmega162   atmega163   atmega164p   atmega165   atmega165p   atmega168   atmega168p   atmega169   atmega169p   atmega32   atmega323   atmega324p   atmega325   atmega325p   atmega3250   atmega3250p   atmega328p   atmega329   atmega329p   atmega3290   atmega3290p   atmega32hvb   atmega406   atmega64   atmega640   atmega644   atmega644p   atmega645   atmega6450   atmega649   atmega6490   atmega128   atmega1280   atmega1281   atmega1284p   atmega16hva   at90can32   at90can64   at90can128   at90pwm216   at90pwm316   at90usb646   at90usb647   at90usb1286   at90usb1287   at94k   avr6   atmega2560   atmega2561   avr1   at90s1200   attiny11   attiny12   attiny15   attiny28../test3.c:1: error: MCU 'atmega32a' supported for assembler onlyIn file included from ../test3.c:1:c:/winavr-20071221/bin/../avr/include/avr/io.h:301:6: warning: #warning "device type not defined"../test3.c: In function 'main':../test3.c:12: error: 'DDRA' undeclared (first use in this function)../test3.c:12: error: (Each undeclared identifier is reported only once../test3.c:12: error: for each function it appears in.)../test3.c:16: error: 'PORTA' undeclared (first use in this function)make: *** [test3.o] Error 1Build failed with 5 errors and 1 warnings...