mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega EEPROM beschreiben/lesen


Autor: Andreas H. (heilinger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte Kalibrierwerte (Offset und Steigung) eines Sensors in ein 
EEPROM schreiben. Diese werden nach dem Starten des ATmega168PA dann 
wieder ausgelesen, um sie bei der Berechnung zu benutzen. Um zu prüfen, 
dass ich nicht Mist auslese, speichere ich zusätzlich noch eine einfach 
CRC in das EEPROM und lese die auch jedesmal aus.

Jetzt habe ich mal das EEPROM über AVR Studio ausgelesen. Dabei ist mir 
nun aufgefallen, dass nicht immer die gleiche Adresse beschrieben wird. 
Dementsprechend lese ich nicht die richtigen Werte aus.

Hier die Aufrufe zum Beschreiben:
EEPROM_schreiben (6, sint_Flow_Digits);
sint_crc = (sint_Flow_Digits%CRC_DIV);          //CRC bilden
EEPROM_schreiben (8, sint_crc);

EEPROM_schreiben (2, sint_offsetfehler);
sint_crc = (sint_offsetfehler%CRC_DIV);         //CRC bilden
EEPROM_schreiben (4, sint_crc);

Hier die Aufrufe zum Lesen:
sint_dummy = EEPROM_lesen(2);         //Adresse 2 im EEPROM lesen
sint_crc_check = EEPROM_lesen(4);     //Adresse 4 im EEPROM lesen    
  
  
  if ((sint_dummy%CRC_DIV == sint_crc_check) && ( sint_dummy != 0xFFFF))  //Bereits ein Speichervorgang in EEPROM?
    sint_offsetfehler = sint_dummy;
  else
    sint_offsetfehler = 0x3999;

  sint_dummy = EEPROM_lesen(6);         //Adresse 6 im EEPROM lesen 
  sint_crc_check = EEPROM_lesen(8);     //Adresse 8 im EEPROM lesen    
  
  if ((sint_dummy%CRC_DIV == sint_crc_check) && ( sint_dummy != 0xFFFF))  //Bereits ein Speichervorgang in EEPROM?
    sint_Flow_Digits = sint_dummy;
  else
    sint_Flow_Digits = 6700;    


Hier die Funktionen:
void EEPROM_schreiben (unsigned int uint_Adresse, signed int sint_data)
{
  unsigned int uint_lowbyte;
  unsigned int uint_highbyte;
    
  uint_lowbyte = (sint_data & 0xFF);
  uint_highbyte = (sint_data >> 8);
  
  while (EECR & (1<<EEPE)) ;
  EEARL = uint_Adresse;
  EEDR = uint_highbyte;

  cli();
  EECR |= (1<<EEMPE);
  EECR |= (1<<EEPE);
  sei();
 
  
  while (EECR & (1<<EEPE)) ;  
  EEARL = (uint_Adresse+1);
  EEDR = uint_lowbyte;

  cli();
  EECR |= (1<<EEMPE);
  EECR |= (1<<EEPE);
  sei();
}

signed int EEPROM_lesen (unsigned int uint_Adresse)
{
  signed int Wert;
  unsigned int uint_lowbyte;
  unsigned int uint_highbyte;  
    
  while (EECR & (1<<EEPE)) ;
  EEARL = uint_Adresse;

  EECR |= (1<<EERE);
  uint_highbyte = EEDR;
  

  while (EECR & (1<<EEPE)) ;
  EEARL = (uint_Adresse+1);

  EECR |= (1<<EERE);
  uint_lowbyte = EEDR;
  
  Wert = (uint_highbyte << 8) | uint_lowbyte;  
  
  return Wert;
}

Und so sieht das EEPROM-File aus:

:10000000FFFFFFFFFFFF19AD000DFFFFFFFFFFFF29
:10001000FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFEF
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:10010000FFFF39B5000519720002FFFFFFFFFFFF77
:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
:10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
:10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
:10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
:10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
:10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
:10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
:1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
:1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
:1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
:1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
:1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
:1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
:00000001FF

Normalerweise sollte ja da dann nur die erste Zeile beschrieben sein und 
die 2. und 17. sollte nur FF enthalten. Mit anderen Worten, mein Fehler 
müsste in der Schreibe-Funktion enthalten sein, oder?

Kann mir jemand weiterhelfen?

Autor: Klaus T. (gauchi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreib doch mal eine 0 in EEARH, wenn ich das Datenblatt richtig lese, 
ist der initial value nicht definiert, da könnte also auch eine 1 
drinstehen, dann würdest Du mit dem Schreibbefehl in der zweiten Hälfte 
landen.

Autor: Andreas H. (heilinger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh, Danke!

"The initial value of EEAR is undefined", muss ich wohl übersehen haben.
Bin davon ausgegangen, dass da alle Bits auf 0 gesetzt sind, wenn man 
die net anfasst...

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gernell sollte man aus c die 16bit register als 16-bit Wert ansprechen.

also
EEAR = &x;

Edit:
So kümmert sich auch der Kompiler um die richtige Reihenfolge, in der 
diese beschrieben/gelesen werden müssen.
(siehe Datenblatt unter ADC, Timer)

Autor: Andreas H. (heilinger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okay, habe ich auch gemacht, aber eine Frage:

Warum
"EEAR = &x;"
und nicht
"EEAR = x;"
?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.