- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 15

Thema: mal wieder eine EEPROM Frage

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.11.2004
    Beiträge
    263

    mal wieder eine EEPROM Frage

    Hallo,
    ich habe ein Problem mit dem EEPROM (ATMega32) , und zwar habe möchte ich gerne Daten im EEPROM ablegen, bei jeden neustart des Gerätes sollen diese Daten ausgelesen werden.

    Ich habe bis jetzt im Datenblatt gelesen, auf http://www.mikrocontroller.net/artic...R-GCC-Tutorial und natürlich hier im Roboternetz gesucht. Vor allem der Thread https://www.roboternetz.de/phpBB2/ze...ghlight=eeprom scheint ganz gut zu sein, doch ich habe mit meinen eher mäßigen C Kenntnissen nicht alles verstanden.

    Ich habe bei mir ein "char h_wert[15][4];"
    Bei starten des gerätes sollen daten aus dem EEPROM gelesen werden und in das Feld h_wert geschrieben werden. Wenn das Gerät erstmal läuft, sollen abundzu bestimmte werte aus h_feld wieder in den EEPROM gespeichert werden...

    Könnte jemand versuchen, mit zu erklären wie genau das funktioniert? Schonmal Danke im Voraus

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.11.2004
    Beiträge
    263
    So, habe selber nochmal weitergemacht:

    Code:
    void speicherwerte() {
    	globalInterruptEnable(false);			// Interrupts deaktivieren
    	for (i=0;i<15;i++) {
    		for (j=0;j<4;j++) {
     			while(EECR & (1<<EEWE)) 		// warten bis Schreiben beendet
    			EEAR=(i*4+j);					// adresse setzen
    			EEDR=wert;						// Date
    			EECR |= (1<<EEMWE);			// MWE
    			EECR |= (1<<EEWE);				// Schreiben starten
    		}
    	}
    	globalInterruptEnable(true);			// Interrupts aktivieren
    }
    
    void ladewerte() {
    	int i,j;  
    	
            globalInterruptEnable(false);			// Interrupts deaktivieren
    	for (i=0;i<15;i++) {
    		for (j=0;j<4;j++) {
    			while(EECR & (1<<EEWE)) 		// warten bis Schreiben beendet
    			eear=(i*4+j);
    			EECR |= (1<<EERE);				// Lesen starten
    			h_wert[i][j]=EEDR;				// byte lesen
    		}
    	}
    	globalInterruptEnable(true);			// Interrupts aktivieren
    	
    }
    Habe im Moment aber keinen ISP da, könnte evt, jemand drüberschauen, ob das so funktionieren könnte?

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Nehmem wir mal an, dein h_feld und dein h_feld_EE haben die gleiche Größe, etwa
    Code:
    #include <avr/io.h>
    #include <avr/eeprom.h>
    
    #define EEMEM __attribute__((section(".eeprom")))
    
    char h_feld[15][4];
    const char h_feld_EE[15][4]  EEMEM = 
    {
       {1, 2, 3, 4},
       {5, 6, 7, 8},
       {9, 10, 11, 12},
       {13, 14, 15, 16},
       ...	
    };
    In neueren avr-gcc gibt's schon den Define EEMEM, dann musste das nich mehr selber definen.

    Code:
    void init_h_held()
    {
       eeprom_read_block (h_feld, h_feld_ee, sizeof (h_feld));
    }
    Disclaimer: none. Sue me.

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.655

    Bitte um Hilfe bei EEPROMfragen: EE.., Foo, Arrays ..

    Ich möchte mehrere Vektoren im EEPROM (m)eines Controllers - mega.. - ablegen, Bytes und Words. Ich möchte die auf ganz bestimmten Stellen ablegen, damit ich nach einem Flashen das EEPROM nicht neu beschreiben muss bzw. damit ich nach dem Flashen auf die "alten" EEPROM-Werte auch wieder zugreifen kann, da es sich um Einstell- und Justagedaten dreht.

    Anmerkung: habe den alten Thread wegen des genau passenden Titels wieder aufgewärmt.

    Variable kann ich im EEPROM an einer bestimmten Stelle ablegen und auch wieder auslesen, auch nach dem neu Programmieren, das läuft problemlos. Ein Array der Art

    /* Byte-Array */
    uint8_t eeFooByteArray1[] EEMEM = { 18, 3, 70 };
    uint8_t eeFooByteArray2[] EEMEM = { 30, 7, 79 };

    kommt dann aber möglicherweise an einen Speicherplatz, der variieren kann. So gehts mir jedenfalls bei einem früheren, winzigen Projekt. Von diesem Projekt habe ich etwa diesen Stand:

    Textfeld, das ins EEPROM beim Flashvorgang geschrieben wird.
    unsigned char TestTimedOut[] EEMEM = "Timeout!";

    Definition einer (EINER!) Bytevariablen auf die Adresse 0x004
    #define EE_VALUE2 0x004 // Bytevariable

    Wert dieser Variablen
    [EE_VALUE2] = 0xFF

    und so eine Schreibroutine
    Code:
    // ============================================================================== =
      void DEEsch (int8_t data, uint8_t EEPadd)    // Datum wegschreiben auf Adresse
     {                              // 
    //      Evtl Parameter : (unsigned short address, unsigned char data)
    // - - - - - - - - - - - - - - -//  cli ();
      while (EECR & (1<<EEPE));     // Schreiben möglich ? vorheriger Zugriff zu Ende?
      EEAR           = EEPadd;      // Setze Adresse
      EEDR           = data;        // Schreib Datum ins EEPROM-Data register
      EECR          |= (1<<EEMPE);  // 
      EECR          |= (1<<EEPE);   // Starte Schreibzugriff
      sei ();                       //
    // - - - - - - - - - - - - - - -//
     }                              //
    // ===  Ende DEEsch (uint8_t dat, uint8_t EEPadd)
    // ============================================================================== =

    Bitte jetzt um Hilfe/Erläuterung zu diesen Fragen, der Vollständigkeit halber auch ein paar Anfängerfragen. Danke schon jetzt für die Antworten.

    Wie definiere ich den GENAUEN Ort eines Datenfeldes im EEPROM?

    Was bedeutet dieses ..foo.., ..Foo.. das ich bei EEPROM-Themen immer wieder lese?

    Was bedeutet in den Zeilen
    // schreiben
    eeprom_write_word (&eeFooWord, 2222);
    dieses &eeFooWord? Word verstehe ich (vermute ich), aber & und Foo ? ?
    Geändert von oberallgeier (11.01.2013 um 09:35 Uhr)
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Zu Foo siehe http://de.wikipedia.org/wiki/Metasyntaktische_Variable
    Variablennamen sind der künstlerischen Freiheit und dem Einfal(l/t)sreichtum der Programmierer ausgeliefert. Darüber sollte man nicht allzusehr grübeln.

    Wenn du EEMEM verwendest, dann übergibst du dem Compiler die Obhut über deine EEPROM Variablen. Es geht auch ohne, dann musst du dich nur selbst um die Ablage im Speicher kümmern und, dass du nicht unbeabsichtigte Überschneidungen hast, weil du dann doch mal einen Datentyp änderst.

    Könnte mir allerdings vorstellen, dass bei gleicher Reihenfolge im Code auch das EEPROM immer genau so belegt wird. Aber das hab ich jetzt nur geraten und ich würde meine Hand dafür nicht ins Feuer legen.

    sast

    雅思特史特芬
    开发及研究

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Es gibt für diese "Wo liegt das Zeug im EEPROM"-Problematik auch eine schönere Lösung. Bestehend aus einem Headerfile in das du deine Konfigurationsdatenstruktur reinschreibst, ein Sourcefile und einem Anwendungsbeispiel.

    config.h
    PHP-Code:
    typedef struct {
        
    int foo// Eigene Konfigurationsvariablen hier unterbringen
    Config_Data_t;

    extern Config_Data_t * const config
    config.c
    PHP-Code:
    #include <avr/eeprom.h>

    #define EEPROM_SIZE (E2END + 1)

    typedef struct {
        
    uint8_t firstByteDummy;

        
    Config_Data_t config;

        
    uint8_t aligmentDummy[EEPROM_SIZE sizeof(Config_Data_t) - 1];
    Config_Data_Container_t;

    EEMEM Config_Data_Container_t container = {
                    .
    config = {
                        .
    foo 42 // Beispielinitialisierung
                        
    }, };

    Config_Data_t * const config = &container.config
    Anwendungsbeispiel
    PHP-Code:
    #include "config.h"
    #include <avr/eeprom.h>

    eeprom_read_word(&config->foo
    Erklärung: Config_Data_Container_t belegt den ganzen EEPROM. Vollständig. Das erste Byte wird ausgespart (angeblich kann es ungewollt bei Ausfällen der Stromversorgung o.ä. überschrieben werden), den Rest hinter der eigentlichen Nutzdatenstruktur belegt ein Dummy-Array. Dadurch bleibt die Adresse der Daten immer gleich da der Compiler gar keinen Spielraum zum umorganisieren hat, außer man nimmt selbst Änderungen vor. Auf die Daten zugreifen kann man über einen Pointer der direkt auf den Anfang der Nutzdaten zeigt. Müssen die Daten nicht vorinitialisiert werden, kann auf den entsprechenden Abschnitt in config.c verzichtet werden.

    @sast: Die Reihenfolge in der die Variablen im Speicher liegen kannst du nicht beeinflussen, das gilt für den RAM genauso wie für den EEPROM. Wenn du ein sicheres Speicherlayout haben möchtest, musst du das ganze als struct ablegen.

    mfG
    Markus
    Geändert von markusj (12.01.2013 um 16:22 Uhr) Grund: Hinweis zum Sourcefile entfernt
    Tiny ASURO Library: Thread und sf.net Seite

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Deshalb hatte ich ja auch geschrieben, dass ich meine Hand dafür nicht ins Feuer legen würde.

    Am Ende machst du hier das, was ich vorgeschlagen hatte. Du bestimmst selbst die Ablage der Daten im Speicher.
    Sehr schönes ausführliches Beispiel. Besonders, da du die Möglichkeit von Überschneidungen schon mit abgefangen hast.

    sast

    雅思特史特芬
    开发及研究

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.655
    Zitat Zitat von markusj Beitrag anzeigen
    Es gibt ... eine schönere Lösung ... ein Sourcefile das du nicht anfassen musst und ...
    @sast - danke für die Hilfe, Markus - danke für Deine schöne Aufstellung und Deine Erläuterungen dazu. Dein Vertrauen in meine Kenntnisse ist aber zu groß. Ich habe erstmal gestern das Thema struct im Kernighan&R durchgeackert, stundenlang nach dem Sinn von * und & geinternettet, habe halbwegs begriffen dass "container" nicht nur in C++ vorkommen und laaaangsam erhellt sich der Horizont (aber z.B. "extern Config_Data_t * const config;" kapier ich immer noch nicht). Egal. (Erkenntnis: Interessant, mit wie wenig C-Kenntnissen man funktionierende Programme schreiben kann.)

    Das bisschen, das ich kapiert hatte, hab ich trotzdem mal ausprobiert (experimentelle Softwareentwicklung :-/ ).

    Zum Beispiel:
    PHP-Code:
    uint8_t firstByteDummy EEMEM;
    int16_t eeSeroff[12EEMEM// Offset Servovorgabe 
    dazu noch der Dummy - und das EEPROM ist voll *ggg*.

    Nur wenn ich den Offset für Servo 10 abspeichern will :
    PHP-Code:
    ...
    eeprom_busy_wait();
    eeprom_write_word ((int16_t)eeSeroff[10], );
    ... 
    führt das zu der Warnung "passing argument 1 of '__eewr_word_m328p' makes pointer from integer without a cast" - und egal wo ich ein * oder ein & hinpappe (auch deren Sinn und Zweck war mir bis gestern nicht bekannt) - es klappt nicht.

    Daher schon wieder die Bitte/Frage - wo gehts lang ?
    Ciao sagt der JoeamBerg

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad