C EEPROM vertauscht Werte

Prninz Eisenhertz

Neues Mitglied
16. Juli 2011
7
0
0
Sprachen
Hallo.

Hab lang gelesen und nix gefunden zum Problem.

System:
Atmega 16
AVR-Studio
Vcc = 5V
Brownout bei 4V

Code ist:
Code:
_________________________________________________________________________

globals.h:

uint8_t A1TimeOn[2], A1TimeOff[2], A2TimeOn[2], A2TimeOff[2],
A3TimeOn[2], A3TimeOff[2], A4TimeOn[2], A4TimeOff[2];

_________________________________________________________________________
main.c:

#include <avr/eeprom.h>
#include "globals.h"

int main(){
A1TimeOn[0] = 0;A1TimeOn[1] = 0;A1TimeOff[0] = 0;A1TimeOff[1] =
0;A2TimeOn[0] = 0;A2TimeOn[1] = 0;A2TimeOff[0] = 0;A2TimeOff[1] =
0;A3TimeOn[0] = 0;A3TimeOn[1] = 0;A3TimeOff[0] = 0;A3TimeOff[1] =
0;A4TimeOn[0] = 01;A4TimeOn[1] = 0;A4TimeOff[0] = 0;A4TimeOff[1] = 0;

get_A1TimeOn_EEdata();
get_A1TimeOn_EEdata();
get_A1TimeOff_EEdata();
get_A2TimeOn_EEdata();
get_A2TimeOff_EEdata();
get_A3TimeOn_EEdata();
get_A3TimeOff_EEdata();
get_A4TimeOn_EEdata();
get_A4TimeOff_EEdata();

while (1)
{
hier ist dann z.B. die Ausgabe der EEPROM-Werte
}
________________________________________________________________________
eeprom.c:

uint8_t eeFooByte1 EEMEM;    //TurnSW
uint8_t eeFooByte2 EEMEM;    //A1syn_0
uint8_t eeFooByte3 EEMEM;    //A1syn_1
uint8_t eeFooByte4 EEMEM;    //A2syn_0
uint8_t eeFooByte5 EEMEM;    //A2syn_1
uint8_t eeFooByte6 EEMEM;    //A3syn_0
uint8_t eeFooByte7 EEMEM;    //A3syn_1
uint8_t eeFooByte8 EEMEM;    //A4syn_0
uint8_t eeFooByte9 EEMEM;    //A4syn_1
uint16_t eeFooByte10 EEMEM;    //A1IVOn
uint16_t eeFooByte11 EEMEM;    //A1IVOff
uint16_t eeFooByte12 EEMEM;    //A2IVOn
uint16_t eeFooByte13 EEMEM;    //A2IVOff
uint16_t eeFooByte14 EEMEM;    //A3IVOn
uint16_t eeFooByte15 EEMEM;    //A3IVOff
uint16_t eeFooByte16 EEMEM;    //A4IVOn
uint16_t eeFooByte17 EEMEM;    //A4IVOff
uint8_t eeFooByte18 EEMEM;    //A1TimeOn
uint8_t eeFooByte19 EEMEM;    //A1TimeOn
uint8_t eeFooByte20 EEMEM;    //A1TimeOff
uint8_t eeFooByte21 EEMEM;    //A1TimeOff
uint8_t eeFooByte22 EEMEM;    //A2TimeOn
uint8_t eeFooByte23 EEMEM;    //A2TimeOn
uint8_t eeFooByte24 EEMEM;    //A2TimeOff
uint8_t eeFooByte25 EEMEM;    //A2TimeOff
uint8_t eeFooByte26 EEMEM;    //A3TimeOn
uint8_t eeFooByte27 EEMEM;    //A3TimeOn
uint8_t eeFooByte28 EEMEM;    //A3TimeOff
uint8_t eeFooByte29 EEMEM;    //A3TimeOff
uint8_t eeFooByte30 EEMEM;    //A4TimeOn
uint8_t eeFooByte31 EEMEM;    //A4TimeOn
uint8_t eeFooByte32 EEMEM;    //A4TimeOff
uint8_t eeFooByte33 EEMEM;    //A4TimeOff

Beispielfunktionen:

void get_A1TimeOn_EEdata()
{
  uint8_t v = 0;
  cli();
  v = eeprom_read_byte(&eeFooByte18);
  if (v > 23)v = 0;
  A1TimeOn[0] = v;
  v = 0;
  v = eeprom_read_byte(&eeFooByte19);
  if (v > 59)v = 0;
  A1TimeOn[1] = v;
  sei();
}

void set_A1TimeOn_EEdata()
{
  cli();
  eeprom_write_byte(&eeFooByte18, A1TimeOn[0]);
  eeprom_write_byte(&eeFooByte19, A1TimeOn[1]);
  sei();
}

________________________________________________________________________

So und jetzt mal zum Verhalten des Ganzen:

Ich habe also 33 EEPROM-Speichervariablen benannt und es funktioniert
auch soweit alles. Alle 41 Bytes werden beschrieben und ordnungsgemäß
ausgelesen. Nur &eeFooByte19 vertauscht seinen Wert mit &eeFooByte27.
Besser gesagt wird nicht der Wert von &eeFooByte27 in &eeFooByte27
gespeichert, sondern A3TimeOn[1] ( was den Wert von &eeFooByte27
übernehmen soll ) nimmt den von &eeFooByte19??? Alle anderen Werte sind
korrekt und die Routinen sind alle gleich geschrieben. Deshalb verstehe
ich nicht, weshalb es immer nur bei diesen zwei Werten hapert.

Kennt das Problem jemand? bitte helft mir, da ich keine Erklärung hab
und vieles schon versucht; So z.B. die Speicheradressen fest zu
benennen. Das Prob ist das Gleiche.

Vielen Dank
 
Hallo,

in deinem Code-Auszug kann ich keinen Fehler erkennen, der die Ursache für das Verhalten sein könnte, welches du beschreibst.

Leider sieht man nur eine Routine, die in das Eeprom schreibt, bei den anderen berücksichtigst du byte/word?!

Nur mal testweise: Füge direkt nach main() ein delay_ms(100) ein (#include <util/delay.h>), vielleicht muss die Zeit nach Einschalten größer sein, damit sich die Spannung stabilisiert. Wobei ich den Fehler hier nicht vermute, du hast ja sogar den BOD aktiviert, aber ist ja schnell mal zu testen.

Leider kann ich dir keine weiteren Tipps geben, vielleicht fällt mir oder jemand anderem noch was ein, wenn du mal das Projekt gezippt anhängst, so dass wirklich alle Routinen vorhanden sind.


Noch ein kleiner Hinweis: Nach main() rufst du zweimal get_A1TimeOn_EEdata auf, einmal reicht.

Grüße,
Dirk
 
Hallo und vielen vielen Dank für deine Antwort!

Ich glaubs ja nich und das musst du mir erläutern (BITTE!)

An dem _delay_ms(100) lag es. Jedenfalls sporadisch! bei 150 scheint es jetzt sicher zu funktionieren:::::::::::::::::::)

Ich schätze der EEPROM braucht volle Spannung und wird ohne Pause zu schnell abgefragt, wenn man startet?! Ich wäre dir sehr dankbar für eine fundierte Erläuterung.

Ansonsten wäre ich niemals darauf gekommen und somit erhälst du von mir meinen persönlichen Orden zum Kreuzritter der Bits;) So einfach ist nen Mann glücklich zu machen;)

Den Rest deiner Einwände hab ich natürlich geändert!


Vielen Dank!
 
Hallo,
An dem _delay_ms(100) lag es. Jedenfalls sporadisch! bei 150 scheint es jetzt sicher zu funktionieren:::::::::::::::::::)

Ich schätze der EEPROM braucht volle Spannung und wird ohne Pause zu schnell abgefragt, wenn man startet?! Ich wäre dir sehr dankbar für eine fundierte Erläuterung.

danke für den Orden ;) Ich bin mir noch nicht so ganz sicher, ob es wirklich an der Betriebsspannung liegt. Mich irritiert, dass du ja schon den BOD aktiviert hast.

Hier mal ein Auszug aus dem Datenblatt:

If the user code contains instructions that write the EEPROM, some precautions must be taken. In heavily filtered power supplies, VCC is likely to rise or fall slowly on Power-up/down. This causes the device for some period of time to run at a voltage lower than specified as minimum for the clock frequency used.

During periods of low VCC, the EEPROM data can be corrupted because the supply voltage is too low for the CPU and the EEPROM to operate properly. These issues are the same as for board level systems using EEPROM, and the same design solutions should be applied.

An EEPROM data corruption can be caused by two situations when the voltage is too low. First, a regular write sequence to the EEPROM requires a minimum voltage to operate correctly. Secondly, the CPU itself can execute instructions incorrectly, if the supply voltage is too low.

EEPROM data corruption can easily be avoided by following this design recommendation:
Keep the AVR RESET active (low) during periods of insufficient power supply voltage. This can be done by enabling the internal Brown-out Detector (BOD). If the detection level of the internal BOD does not match the needed detection level, an external low VCC Reset Protection circuit can be used. If a reset occurs while a write operation is in progress, the write operation will be completed provided that the power supply voltage is sufficient.

Eine nicht stabile Betriebsspannung wäre eine mögliche Ursache, jedenfalls scheint es bei dir so zu sein. Kritisch sind besonders die Schreiboperationen. Eine detailliertere Erklärung kann ich dir leider nicht geben, der Auszug aus dem Datenblatt sagt schon einiges aus. Gerade nach dem Einschalten muss sich die Betriebsspannung erst mal stabilisieren, wenn du dann zu schnell schreibst oder liest, kann es passieren, dass die Schreib- und Leseoperationen fehlerhaft sind. In dem Fall wäre es sinnvoll, ein Delay nach main() zu verwenden.

Gruß,
Dirk
 
Hallo,

Gerade nach dem Einschalten muss sich die Betriebsspannung erst mal stabilisieren, wenn du dann zu schnell schreibst oder liest, kann es passieren, dass die Schreib- und Leseoperationen fehlerhaft sind. In dem Fall wäre es sinnvoll, ein Delay nach main() zu verwenden.
ich mache es zB so das ich bei den Fuses den längsten Reset-Prozess wähle. Also nach dem Reset die längste Wartezeit und die meißten Taktzyklen die er warten soll.

Das wären zB bei einem ATmega32 ...
CKSEL0 = 1 , SUT = 11 ==> Start-up Time = 16K Clk , Additional Delay = 65ms
Recommended Usage : Crystal Oscillator, slowly rising power

Bei nem Xmega muß man jetzt mal nachsehen was da möglich ist. Wenn man aber nicht auf eine schnelle Startzeit angewiesen ist (wie zB bei Watchdog und Echtzeit Regleranwendung) liegt man damit immer auf der sicheren Seite.
Man hat auf jeden Fall schon mal etwas mehr Luft.

Gruß
Dino
 
Ok - bei mir scheint nach intensiverem Testen alles ok mit meinen Eepromfunktionen. Es war wohl wirklich das delay. Ich hatte nicht gedacht, dass diese "Stabilisierung" eine derartige Rolle spielt.

Also. Ich danke sehr und informiere dich, wenn es doch nicht am delay gelegen haben sollte. Es wird laaaang getestet;)

lG
 
Hallo,

Die Headerdatei "avr/eeprom.h" stellt ein "Macro" zur Verfügung das Prüft ob der "EEPROM" Bereit ist.



CodeBox C
eeprom_is_ready()


Solltest du auch verwenden.
Solch ein ähnliches Problem hatte ich auch, da ich den "BrownOutDetector" nicht aktiviert hatte.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)