mikrocontroller.net

Forum: Compiler & IDEs unverstänliche Effekte beim Schreiben ins EEPROM


Autor: Egon Müller (kpc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Daten ins EEPROM zu schreiben gelingt mir mit den Funktionen aus 
eeprom.h nicht so recht:
wenn ich einen Wert schreibe, geht es noch gut, aber mit zweien klappt 
es nicht mehr:
void zumeeprom(uint16_t wert, uint16_t i)  
{
  eeprom_write_word(&adr[i],700);  //700 - beliebige Zahl (Test)    
//  while (EECR & (1<<EEPE))    // wait for completion
                               // of previous write
//  ;

    eeprom_write_word(&adr[i+2], 555);  //555 - beliebige Zahl (Test)
//    while (EECR & (1<<EEPE))    // wait for completion
                          // of previous write
//    ;
  
return ;
}
Die Funktion eeprom_write_(....) stammt aus der Headerdatei, wie ich 
gelesen, aber nicht nachgeprüft habe, sollte die Funktion die nötigen 
Verzögerungen für den Schreibvorgang schon enthalten.
Die while-Schleifen (aus dem Manual) sollten also entbehrlich sein. Wie 
dem auch sei, es funktioniert mit und ohne while und auch mit reinem 
_delay_ms(xx) nicht.

Zu erwarten wäre ein EEPROM-Inhalt
188,2,255,255,43,2,188,255,255,2,43,2  ... usw (Endlsoschleife)
(188,2 = 700,     255,255 weil i+2,    43,2 = 555)

Ich bekomme aber
188,2,188,2,188,2,... gelgentlich mal 43,2,43,2,188,2....

Anfangs hatte ich den Eindruck, den Code richtig an meine Bedürfnisse 
angepaßt zu haben, da es funktionierte. Nach den Versuchen, mehrere 
Zahlen ins EEPROM zu schreiben, bin ich mir nicht mehr sicher.
Den Code aus dem Manual habe ich noch nicht ausprobiert, weil ich meine, 
mit dem aus eeprom.h müßte man mehrere Werte hintereinander  schreiben 
können.
Was mache ich falsch?
Gruß
Egon

Autor: →ø← (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>188,2,188,2,188,2,... gelgentlich mal 43,2,43,2,188,2....
hmm, gelegentlich.
vielleicht mal brown out detector anschalten um sicher zu sein das es 
nicht an der schaltung liegt.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Egon Müller schrieb:
> Was mache ich falsch?

Das, was viele hier falsch machen: zu wenig Code zu posten.

Wie ist adr deklariert?
Wie sieht diese Endlosschleife aus, in der die Funktion aufgerufen wird?

Denn die erste Vermutung bei diesem hier
> Ich bekomme aber
> 188,2,188,2,188,2,
ist schlicht, dass du in der Schleife den Index nicht korrekt weiter 
zählst.

Autor: Egon Müller (kpc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Egon Müller schrieb:
>> Was mache ich falsch?
>
> Das, was viele hier falsch machen: zu wenig Code zu posten.
>
Dabei hatte ich mir so viel Mühe gegeben, die nur wichtigsten Passagen 
zu zitieren und den übrigen Wust, durch den sich jemand, der mir 
freundlicherweise helfen will, nicht durchwühlen sollte, wegzulassen.

Hier also der nicht so stark gekürzte Code, der alleine "läuft". Laufen 
soll heißen, er stürzt nicht gerade ab, aber er produziert den erwähnten 
Mist.
#include <avr/io.h>           
#include <stdint.h>    
#include <stdio.h>
#include <util/delay.h>  
#include <stdlib.h>
#include <avr/iom644p.h>   
#include <avr/eeprom.h>


uint16_t adr[1000] EEMEM;       // EEPROM-Adressen


// testweise sollen zwei x-beliebige Zahlen u. die letzte
// Adresse ins EEPROM geschrieben werden - mit zwei Bytes Zwischenraum

void zum_eeprom(uint16_t wert, uint16_t k)  
{
  eeprom_write_word(&adr[k],700);      

    eeprom_write_word(&adr[k+2], 555); 
  
  eeprom_write_word(&adr[k+4], adr[k+2]);

  return ;
} 


int main(void)                     
{      
        
  uint16_t n=0;        // Index für eeprom-Adresse adr            
 
      while(1)         // Endlosschleife für EEPROM-Einträge
  {
        _delay_ms(1000);
        zum_eeprom(999,n);
        n=n+1;
    if (n > 1000)
    n=0;

  } /* Ende while   */

    return (0) ;
}


Viele Grüße
Egon

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und da haben wir doch schon das von mir befürchtete. Wenn du n in der 
Schleife immer nur um 1 erhöhst, wie kannst du dann irgendetwas anderes 
erwarten, als
> Ich bekomme aber
> 188,2,188,2,188,2,
?

1. Schreiben:  188,   2,   x,   x,  43,   2
2. Schreiben:            188,   2,   x,   x,  43,   2
3. Schreiben:                      188,   2,   x,   x,  43,   2
4. Schreiben:                                188,   2,   x,   x,
...
Ergebnis:      188,   2, 188,   2,  188,  2, 188, ...

Autor: Egon Müller (kpc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Und da haben wir doch schon das von mir befürchtete. Wenn du n in der
> Schleife immer nur um 1 erhöhst, wie kannst du dann irgendetwas anderes
> erwarten, als .....

Ja, natürlich, ich war auf das Unterprogramm fixiert und habe übersehen, 
daß ich in main den Index wieder zurückstelle.

Ich kann mich dem hierzulande gebräuchlichen Gebet anschließen: "Herr, 
wirf Hirn runter".

Eine Verständnisfrage hätte ich noch, weil ich den Tutorials keine 
Antwort gefunden habe: überlasse ich es eigentlich mit dem Zusatz EEMEM 
zu meiner Variablen dem Compiler, sich irgendwelchen absoluten Adressen 
kreuz und quer im EEPROM herauszusuchen, oder legt er die fortlaufend 
an?

Ich habe das Programm korrigiert und hatte erwartet, daß die dritte 
eeprom_write-Zeile wenigstens  m e i n e  Adress-Indices in 
aufsteigender Folge zusammenhängend wiedergibt, was durchaus nicht der 
Fall ist.

Egon

Autor: Hoppla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lesen musst Du aus dem EEPROM auch mit einer der avr-libc-Funktionen.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Egon Müller schrieb:

> Ich habe das Programm korrigiert und hatte erwartet, daß die dritte
> eeprom_write-Zeile wenigstens  m e i n e  Adress-Indices in
> aufsteigender Folge zusammenhängend wiedergibt, was durchaus nicht der
> Fall ist.

Die dritte Zeile schreibt nur Müll ins EEPROM. "adr[k+2]" ist der Inhalt 
eines Array-Elements. Da du dieses Array-Element aber nicht mit den 
EEPROM-Funktionen liest, kommt der geschriebene Wert aus dem RAM, nicht 
dem EEPROM.

Den Kommentaren nach vermute ich mal, dass du in der dritten Zeile auch 
gar nicht ein Array-Element (adr[k+2]) in ein anderes (adr[k+4]) 
kopieren willst, sondern wohl eher die Adresse eines Array-Elements 
schreiben willst, also:
eeprom_write_word(&adr[k+4], (uint16_t)&adr[k+2]);

Autor: Egon Müller (kpc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Den Kommentaren nach vermute ich mal, dass du in der dritten Zeile auch
> gar nicht ein Array-Element (adr[k+2]) in ein anderes (adr[k+4])
> kopieren willst, sondern wohl eher die Adresse eines Array-Elements
> schreiben willst, also:eeprom_write_word(&adr[k+4], (uint16_t)&adr[k+2]);

In der Tat, ich wollte die letzte Adresse erfassen und sie in eine 
ansonsten unbenutzte Ecke des EEPROM's schreiben, wo sie einen 
Stromausfall überstehen und nach Neustart das Weiterschreiben an der 
richtigen Stelle erlauben sollte.
Bei meiner Aufzeichnungsfrequenz reicht das für 5000 Betriebsstunden, 
dann müßte ich zur nächsten Adresse umziehen.

Schöner wäre es natürlich, wenn man man einer EEPROM-Adresse ansehen 
könnte, ob die Zelle "leer" ist (=0xFF) oder ob der Wert 0xFF 
hineingeschrieben wurde. So, wie ich das verstehe, ist das aus EECR 
nicht herauszulesen.

Gruß
Egon

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Schöner wäre es natürlich, wenn man man einer EEPROM-Adresse ansehen
>könnte, ob die Zelle "leer" ist (=0xFF) oder ob der Wert 0xFF
>hineingeschrieben wurde. So, wie ich das verstehe, ist das aus EECR
>nicht herauszulesen.

Das geht nicht. Den Wert 0xFF musst du irgendwie vermeiden.

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.