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
proplem and i need solve
#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...
Add new comment