Datum:
Hallo, Ich habe ein Programm für ein PWM-Modul geschrieben, bei dem verschedene Lernwerte im EEPROM gesichert werden sollen. Dazu benutze ich die AVR-GCC-EEPROM-Bibliothek. Das sind die EEPROM Variablen und die enstprechenden SRAM Daten:
uint16_t *ee_pwm_value = (uint16_t*) 0x01;// = {0,63,127,127,195,195,195,195,255,255,255,255,255,255,255,255}; uint16_t *ee_pwm_freq = (uint16_t*) 0x21; uint16_t *ee_water_value = (uint16_t*) 0x25; uint16_t pwm_value[16] = {0,255,511,511,786,786,786,786,1023,1023,1023,1023,1023,1023,1023,1023}; //preset for four concrete stages uint16_t pwm_freq = 32000; uint16_t water_value = 65; |
Diese Funktion liest die Daten aus dem EEPROM und prüft sie auf Plausibilitat:
/***********************************************************************************************/ void load_pwm_values(void){ uint16_t temp_pwm_value[16]; eeprom_read_block(temp_pwm_value,ee_pwm_value,sizeof(pwm_value)); if(test_eeprom_string(temp_pwm_value,sizeof(pwm_value))){ for(i=0;i<16;i++){ pwm_value[i] = temp_pwm_value[i]; } }else{ pwm_value[0] = 0; pwm_value[1] = 255; pwm_value[2] = 511; pwm_value[3] = 511; pwm_value[4] = 786; pwm_value[5] = 786; pwm_value[6] = 786; pwm_value[7] = 786; pwm_value[8] = 1023; pwm_value[9] = 1023; pwm_value[10] = 1023; pwm_value[11] = 1023; pwm_value[12] = 1023; pwm_value[13] = 1023; pwm_value[14] = 1023; pwm_value[15] = 1023; } uint16_t temp_pwm_freq = eeprom_read_word(ee_pwm_freq); if(temp_pwm_freq<32768){ pwm_freq = temp_pwm_freq; }else{ pwm_freq = 32768; } uint8_t temp_water_value = eeprom_read_word(ee_water_value); if(temp_water_value<101){ water_value = temp_water_value; }else{ water_value = 65; } } /***********************************************************************************************/ |
Diese Funktion schreibt die alktuellen Werte in das EEPROM:
/***********************************************************************************************/ void save_pwm_values(void){ // write pwm_values into eeprom if they changed ;) uint16_t temp[16]; eeprom_read_block(temp,ee_pwm_value,16); //_delay_ms(5); uint16_t temp_freq = eeprom_read_word(ee_pwm_freq); //_delay_ms(5); uint8_t temp_water_value = eeprom_read_word(ee_water_value); //_delay_ms(5); if(!compare_string(temp,pwm_value,16)){ eeprom_write_block(pwm_value,ee_pwm_value,(size_t) 16); //_delay_ms(5); } if(temp_freq != pwm_freq){ eeprom_write_word(ee_pwm_freq,pwm_freq); //_delay_ms(5); } if(temp_water_value != water_value){ eeprom_write_word(ee_water_value,water_value); //_delay_ms(5); } } /***********************************************************************************************/ |
Kommentiere ich bei
save_pwm_values() |
einzelne eeprom-Funktionen aus, kompiliert das Programm fehlerfrei, wenn ich aber alles drin habe, kommt mehrfach - jedoch für mich nicht nachvollziehbar dieser fehler: Error: R_AVR_13_PCREL against symbol `__eerd_block_m168' defined in .text.avr-libc section in c:/program files/atmel/avr studio 5.0/avr toolchain/bin/../lib/gcc/avr/4.5.1/../../../../avr/lib/avr5\libc.a(eerd_ block_atmega168.o) F:\Documents\AVRStudioFiles\PWM_V1.2\PWM_V1.2\Debug/.././PWM_V1.2.c Ich benutze AVR-Studio5 und das aktuelle WinAVR. Weder im Datenblatt noch im GCC-Tutorial habe ich irgendeine Lösung gefunden und ich glaube nicht, dass es ein Bug im GCC ist. Ich danke euch schonmal für eure Hilfe.
Datum:
1. Fehlt da was in der Fehlermeldung? z.B. ein "relocation truncated to fit" 2. Hilft vielleicht ein Hinzufügen der math-lib? 3. http://www.avrfreaks.net/index.php?name=PNphpBB2&f...
Datum:
Klaus Wachtler schrieb: > 1. Fehlt da was in der Fehlermeldung? > z.B. ein "relocation truncated to fit" Nein, die Fehlermeldung habe ich direkt aus dem Studio rauskopiert. > 2. Hilft vielleicht ein Hinzufügen der math-lib? Nein, falls du damit die math.h meinst, nicht. > 3. > http://www.avrfreaks.net/index.php?name=PNphpBB2&f... Das hat mir 'weitergeholfen'. Ich habe die in der Fehlermeldung angegebene libc.a mit gelinked (das schreibt man sicher anders). Jetzt geht's. Danke Klaus.
Datum:
robert-p schrieb: > Nein, falls du damit die math.h meinst, nicht. nein, meinte ich nicht :-) Aber wenn's geht, geht's ja.
Datum:
Was meintest du dann?
Datum:
Die math.h wird per #include beim Compilieren eingefügt. Ich sprach dagegen vom Linken, dort ist das eine libm.a, die dazu gelinkt werden kann. Das geht je nach Umgebung z.B. durch Anklicken in der IDE irgendwo bei den Linkeroptionen oder auf Kommandozeilenebene durch die Option -lm. Bei Verwendung eines Makefiles halt irgendwo bei den Linkeroptionen, so daß -lm an den Linker mit übergeben wird.
Datum:
Mit welchen Optionen wird übersetzt?
Datum:
-funsigned-char -funsigned-bitfields -Os -ffunction-sections -fpack-struct -fshort-enums -mshort-calls -g2 -Wall -c -std=gnu99 -mmcu=atmega168
Datum:
Linker-Optionen: -Wl,-lc -Wl,-lm -mmcu=atmega168 Ich habe mal ein Debug-LED-Blinken in der load_pwm_values() eingefügt, dann war der Fehler wieder da.
Datum:
robert-p schrieb: > Linker-Optionen: > -Wl,-lc -Wl,-lm Stattdessen einfach ein -lm als letzte Option beim Linken. Und avr-gcc als Linker(Treiber) verwenden, was du offenbar schon machst.
Datum:
Johann L. schrieb: > robert-p schrieb: >> Linker-Optionen: >> -Wl,-lc -Wl,-lm > > Stattdessen einfach ein -lm als letzte Option beim Linken. Leider Nichts. -lm als letzte Option bringt mich wieder auf Anfang. Werde mal ein bisschen mit den Linker-Optionen im Studio spielen.
Datum:
Danke, das hat geholfen. Jetzt brauche ich auch das -lm und -lc nichtmehr. Aber jetzt mach' ich nichts mehr! Gute Nacht!
Datum:
Es gibt diesen fehler jetzt nichtmehr. Aber ich habe nochmal eine (vermutlich dämliche) Frage: Lege ich eine Variable im EEPROM mit
uint16_t variable EEMEM; |
an, wird die EEPROM Speicherzelle dann schon geschrieben oder nur der Speicherort gemerkt?
Datum:
Frage war tatsächlich dämlich: Es wird bei der Variablendeklaration ein eep-File erzeugt, welches man in den EEPROM schreiben kann.