PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Werte in EEPROM schreiben



Lichti01
30.01.2018, 18:35
Hallo zusammen.

Ich stehe mal wieder vor einem neuen Problem.

Ich möchte im EEPROM mehrere Werte an verschiedenen Adressen speichern.

Ich arbeite im Moment mit dem ATtiny2313A. Im folgendem Code soll, nachdem der Taster an PD0 gedrückt ist, der Wert 5 an Adresse EEAR0 und der Wert 10 an Adresse EEAR1 geschrieben werden.
Wird der µC neu gestartet sollen diese beiden Werte wieder ausgelesen werden. Anhand des Programmteiles in dem die LED blinkt kann der Wert überprüft werden.

Leider ist es so, dass nur der Wert der in der Adresse EEAR0 steht richtig wiedergegeben wird. Die LED2 blinkt dauerhaft weiter.

Hier einmal der


#define F_CPU 1600000UL
#define S1 (PIND&0x01) //Taster definiert an PORTD bit0

#include <avr/eeprom.h>
#include <util/delay.h>

//"Einstellung" für das Blinken der LED
#define LED1 2
#define LED2 3
int i = 1;
int j = 1;

uint8_t myWriteByte = 1; //Variable myWriteByte anlegen und den Wert 1 laden.
uint8_t myReadByte; //Variable für den Wert der dann aus EEPROM gelesen wird.

uint8_t myWriteByte2 = 1;
uint8_t myReadByte2;

int main(void)
{
DDRB = 0b000001100; //PORT B2/3 als Ausgang setzen

DDRD= 0b11111111; //PORTD auf Output
myReadByte = eeprom_read_byte ((unsigned char *)EEAR0); //Wert aus EEAR0 lesen und in myReadByte schreiben
PORTD=myReadByte; //Wert aus myReadByte an PORTD übergeben
myReadByte2 = eeprom_read_byte((unsigned char *)EEAR1);
PORTD=myReadByte2;

while (1)
{
if (S1)
{
myWriteByte=5;
eeprom_write_byte((unsigned char *)EEAR0, myWriteByte); //Wert aus Variable myWriteByte in EEAR0 schreiben
myWriteByte2=10;
eeprom_write_byte((unsigned char *)EEAR1, myWriteByte2);
}

if (i<=myReadByte)
{
PORTB |= (1<<LED1);
_delay_ms(500);
PORTB &= ~(1<<LED1);
_delay_ms(500);
i = i + 1;
}
if (j <= myReadByte2);
{
PORTB |= (1<<LED2);
_delay_ms(500);
PORTB &= ~(1<<LED2);
_delay_ms(500);
j=j+1;
}

}
}


Hoffe ihr könnt mir auch in diese Fall wieder weiterhelfen.

Vielen Dank im voraus
Lichti01

wkrug
31.01.2018, 08:34
Also so richtig kapier ich nicht was Du da machst.
Das EEAR ist üblicherweise das EEPROM Adress Register.
Dort wird üblicherweise die Adresse dezu lesenden / schreibenden EEPROM Speicherplatzes abgelegt.
Glücklicherweise musst Du Dich bei C darum nicht kümmern.
Du musst eine VAriable definieren und dafür sorgen, das diese im EEPROM angelegt wird.
Das sollte so funktionieren:
uint8_t ee_wert EEMEM = 110;
Dabei wird hier auch gleich der Startwert definiert, in diesem Fall 110.
Diesen Wert wird bei der Programmierung des Chips mit übertragen, wenn Du auch das EEPROM gleich mit programmierst.

Dieser Wert ist in deinem Programm beliebig überschreibbar.
Bedenke aber, das ein EEPROM Speicherplatz nur 10000 bis 100000 mal ( Chipabhängig ) überschrieben werden kann.
Ein Überschreiben pro Einschalten dürfte passen.
Ein Überschreiben des Werte bei jedem Programmdurchlauf wird den Speicherplatz in kurzer Zeit killen.
Lesen kann man beliebig oft.

Guck Dir die Speicherverwaltung mal auf einer der zahlreichen Tutorials von AVR GCC an.
Da wird alles gut erklärt.

Lichti01
02.02.2018, 16:03
Danke für deine schnelle Antwort.

Leider hat es mit "uint_8 ee_Wert EEMEM = 110;" auch nicht funktioniert. Werde mir die Tutorials einmal anschauen.

LG Lichti01

oberallgeier
02.02.2018, 18:16
.. schnelle Antwort .. auch nicht funktioniert. Werde mir die Tutorials einmal anschauen ..Ach Leute - vielleicht erst Tutorial lesen, dann Versuch?

Hier (klick) (https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Bytes_lesen.2Fschreiben) ist eigentlich "alles" erklärt, erläutert und bebeispielt. Hier hatte ich (m)ein EEPROM-Problem (https://www.roboternetz.de/community/threads/19453-mal-wieder-eine-EEPROM-Frage?p=568764&viewfull=1#post568764) und Markus hatte geholfen. Und so siehts bei mir aus (einfach zufällig aus meiner Codekiste) in einer *.h-Datei:

// ================================================== =========================== =
// Speicher im EEPROM
// ================================================== =========================== =
//Strings im EEPROM
// Zum Schreiben und Auslesen vom EEPROM vgl.
// https://www.roboternetz.de/community/threads/19453-mal-wieder-eine-
// EEPROM-Frage?p=568764&viewfull=1#post568764
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ###>>> Byte-Array, das erste Byte des EEPROMS gilt als nicht vertrauenswürdig
uint8_t firstByteDummy EEMEM;
uint8_t eeDUMMYbytes [100] EEMEM; // Dummies
uint8_t eeBytes [12] EEMEM; // ?? Allzweckbytes ??
uint16_t eeSrvoff[12] EEMEM; // (Dummy?)Servo-Position - Offset
//u8 SVT[12][11] EEMEM; // Servotexte

// ================================================== =========================== =

Und dann die Anwendung:

// - - - - - - -
case 66: // hex x42 => Schreib Datum ins EEPROM
i2cdata[109] = 85; // Markiere Daten als "übernommen"

uputs0("\tEw "); //
itoa(npntr, wortabc, 10); // Servopointer
uputs0(wortabc); // ... ausgeben
uputs0("\r"); //

//void DEEsch (uint8_t data, uint8_t EEPadd) // Datum wegschreiben auf Adresse
eeprom_write_byte ( &eeBytes[npntr], 50 );// Schreib Offset 50 auf Adresse 100
uputs0("\teEw\r"); //
break;

// - - - - - - -
case 67: // hex x43 => Schreib Datum "-2) ins EEPROM
i2cdata[109] = 85; // Markiere Daten als "übernommen"

uputs0("\tEw "); //
itoa(npntr, wortabc, 10); // Servopointer
uputs0(wortabc); // ... ausgeben
uputs0("\r"); //

// BEEsch ( -2, 100); // Schreib Offset -2 auf Adresse 100
eeprom_write_byte ( &eeBytes[npntr], 50 );
uputs0("\teEw\r"); //
break;

// - - - - - - -
case 70: // hex x46 => Nur LESEN Word aus EEPROM
i2cdata[109] = 85; // Markiere Daten als "übernommen"

uputs0("\tEw lesen "); //

muell = 9;
eeprom_busy_wait();
muell = eeprom_read_word ( &eeSrvoff[10] );
uputs0("\teEw "); //
itoa(muell, wortabc, 10); // Datum
uputs0(wortabc); // ... ausgeben
uputs0("\r"); //
break;

// - - - - - - -

Vielleicht hilfts?