EEPROM lesen funktioniert nicht

Gast #1825976
Lesenswert?

Hallo,

ich habe ein Problem. Ich möchte Daten im EEPROM ablegen und per ISP 
aufspielen. Das klappt auch soweit. Ich definiere einen Array mit 5 
Bytes, die .eep hat diese auch.
Im Programm lade ich mir die Daten aus dem EEPROM in eine Variable aus 
dem Flash. Leider übernimmt diese Variable die Werte aus dem EEPROM 
nicht. Wieso?
Ich lase mir die Werte mit einer LED anzeigen. Das abgespeckte Programm 
ist anbei.
Wenn ich vom meinem Programm aus eeprom_write_block() benutze, übernimmt 
das EEPROM die Werte. Wenn ich diese dann wieder lese aus dem EEPROM und 
in meine Flash Variable schreibe mit eeprom_read_block() liegen diese 
auch richtig in der Flash Variable. Nur zu Beginn liest er mir die Werte 
aus dem EEPROM nicht in die Flash Variable ein... bin ratlos.
1
#ifndef F_CPU
2
#define F_CPU           9600000UL                   // processor clock frequency 9,6Mhz
3
#endif
4

5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <avr/eeprom.h>
8
#include <avr/interrupt.h>
9
#include <inttypes.h>      // Makros für int Datentypen                      
10

11
//Define für EEPROM
12
#ifndef EEMEM
13
// alle Textstellen EEMEM im Quellcode durch __attribute__ ... ersetzen
14
#define EEMEM __attribute__ ((section (".eeprom")))
15
#endif
16

17

18

19
// ------------------------------------------------------------------------------------------
20
// Variabelen im EEPROM
21
// ------------------------------------------------------------------------------------------
22
uint8_t eeArray[] EEMEM = { 2,2,1,1,1 };
23

24

25
uint8_t Array[5] = { 0 };  // Flash Variable
26

27
     
28
// main prog
29
int main(void)
30
{
31
  eeprom_read_block(Array,eeArray,sizeof(Array));
32
  
33
    // Ports initialisieren
34
  init();   
35

36
  while (1)
37
  {
38
  // hier erfolgt eine Ausgabe von Array
39
  } 
40
}
41
 /* 
42
 * Funktion init(): Initialisierung des µC 
43
 */ 
44
void init(void) 
45
{
46
  DDRB = 0; 
47
  return;
48
}
Gast #1826156
Lesenswert?

Folgendes Neues habe ich herausgefunden.
Angenommen ich beschreibe das EPPROM manuell über eeprom_write_block() 
in den eeArray mit den Werten { 2,2,1,1,1 }. Danach lese ich das EPPROM 
über ISP aus.
Ich lösche den µC und spiele das ausgelesene EPROM ein. Das Programm 
funktioniert.
Irgendwie stimmt die Adresse der Zuweisung
1
uint8_t eeArray[] EEMEM = { 2,2,1,1,1 };
 nicht mit dem später zugegriffenen EPPROM Stelle überein. Daher liest 
mir das zunächst wohl nur "Schrott" aus.

Das ausgelesene EEPROM Image entspricht nicht dem, was mir der Compiler 
aus der Zuweisung erzeugt: der Zuweisung
1
uint8_t eeArray[] EEMEM = { 2,2,1,1,1 };
 die HEX-Datei oder die .eep Datei sind unterschiedlich.
Hat einer eine Idee wieso?
Gast #1826171
Lesenswert?

Hallo Peter,

ja, das macht der Compiler auch.
Dieses EEPROM File spiele auch per ISP auf den µC. Nur wenn ich das 
generierte EEPROM File auspiele, stehen dort nicht die Werte drin.

Programmiere ich das EEPROM aber über die Funktion eeprom_write_block() 
direkt im Programm mit gleichen Werten und lese dann die EEPROM Datei 
per ISP aus. Danach lösche ich den µC und spiele die ausgelesene Datei 
auf und das ganze funktioniert.

Kann es damit zusammenhängen, dass bei der direkt vom Compiler erzeugten 
.eep Datei die Werte bei der ersten Adresse im EEPROM anfangen?
Wenn ich die vom Compiler erzeugte Datei lade ist der erste Wert in 
Bascom 3A.
Lade ich mir die ausgelesen durch eeprom_write_block() in Bascom, so 
steht in der ersten Adresse ein 00.
Ich habe nämlich im Tutorial gelesen, dass die erste Adresse nicht 
beschrieben werden sollte, aber scheinbar macht der Compiler das. Kann 
es sein, dass dort der Wurm sich versteckt? Und wenn ja, wie erzeuge ich 
dann direkt vom Compiler eine Datei, die nicht direkt bei der ersten 
Adresse beginnt?
Gast #1826173
Lesenswert?

Melanie schrieb:
> Hallo Peter,
>
> ja, das macht der Compiler auch.
> Dieses EEPROM File spiele auch per ISP auf den µC. Nur wenn ich das
> generierte EEPROM File auspiele, stehen dort nicht die Werte drin.

bzw. die Werte stehen bestimmt drin, bloß er liest nicht nicht korrekt 
aus bzw. die Stelle wird wohl nicht stimmen.
Gast #1826174
Lesenswert?

Dir ist klar, daß es die EESave Fuse bei einigen Controllern gibt, die 
das Löschen des EEProms beim Flashen steuert ? Es wäre doch immerhin 
möglich, daß der Compiler zuerst das EEProm beschreibt, dann das Flsah 
und dabei wieder das EEProm gelöscht wird.
Gast #1826183
Lesenswert?

Die Funktion besagt ja nur, wenn ich den Chip lösche, ob das EEPROM mit 
gelöscht wird oder nicht.
Da ich den Chip lösche, das Flash aufspiele und dann die EEPROM Datei, 
spielt das keine Rolle.
Es wäre nur relevant, wenn ich die EEPROM Datei nicht neu immer auspiele 
und ständig ein geändertes Programm in den Flash schiebe.
Gast #1826191
Lesenswert?

> Es wäre nur relevant, wenn ich die EEPROM Datei nicht neu immer auspiele
> und ständig ein geändertes Programm in den Flash schiebe.

Kommt darauf an, wie das Aufspielen des Codes und des EEproms im 
Einzelnen vor sich geht. Das Beschreiben des EEProms und das Flashen des 
Codes sind zwei unterschiedliche Prozesse, das passiert nicht auf 
einmal. Deswegen einfach mal die Fuse ändern und sehen was passiert ;-)
Gast #1826193
Lesenswert?

> Wenn man die Programmierschritte manuell ausführt, sollte die Fuse kein
> Problem sein. Nur beim automatischen Programmierablauf wird der
> Masserase automatisch durchgeführt.

Das wäre logisch. Nur ist's ein kleiner Klick und schon weis man, ob's 
daran hängt.
Gast #1826624
Lesenswert?

Hallo,

so, ich habe das Program mal wirklich auf ein absolutes Minimum 
reduziert und wie folgt geschrieben:
1
#ifndef F_CPU
2
#define F_CPU           9600000UL                   // processor clock frequency 9,6Mhz
3
#endif
4

5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <avr/eeprom.h>
8
#include <avr/interrupt.h>
9
#include <inttypes.h>      // Makros für int Datentypen                      
10

11
// ------------------------------------------------------------------------------------------------
12
// DEFINES
13
// ------------------------------------------------------------------------------------------------
14

15
//Define für EEPROM
16
#ifndef EEMEM
17
// alle Textstellen EEMEM im Quellcode durch __attribute__ ... ersetzen
18
#define EEMEM __attribute__ ((section (".eeprom")))
19
#endif
20

21
void init(void);
22
// ------------------------------------------------------------------------------------------
23
// Variabelen im EEPROM
24
// ------------------------------------------------------------------------------------------
25
uint8_t eeArray[] EEMEM = { 0,0,1,1,1 }; // Vorgabe Code im EEPROM
26

27

28
     
29
// main prog
30
int main(void)
31
{
32
    // Ports und Interrupts initialisieren
33
  init();   
34
  
35
    while (1)
36
  {
37
  
38
  }
39

40
}
41
 /* 
42
 * Funktion init(): Initialisierung des µC 
43
 */ 
44
void init(void) 
45
{
46
  // --------------------------------------------------------------------------------------------
47
  // PORTB konfigurieren
48
  //
49
  // --------------------------------------------------------------------------------------------
50
  DDRB = 0; 
51
  DDRB |= (1 << PB1) | (1 << PB2) ;    
52
  PORTB |= (1<<PB2) | (1 << PB4);      
53
    
54

55
  // --------------------------------------------------------------------------------------------
56
  // Timer 0 (8-Bit) 
57
  // --------------------------------------------------------------------------------------------
58
  TCCR0A |= (1<<WGM01);   // CTC Mode OC0A
59
  TCCR0B |= (1<<CS01);  // Prescaler 8
60
  TIMSK0 |= (1<<OCIE0A);  // Enable Compare Match A des Timers
61
  OCR0A = 149;      // Compare Register
62
   TCNT0 = 0;         // Counter auf 0 initialisieren
63
 
64
  
65
   sei();          // setzt globales Interrupt Enable Bit
66
  return;
67
}

Das Programm enthält lediglich die Initialisierng meiner benötigten 
Register, sowie die Vorbelegung des EEPROMS Array eeArray mit 5 Werten 
{0,0,1,1,1}.
Die erzeugte EEPROM .eep Datei enthält diese Werte jedoch nicht.
Anbei das Program in in einer .c Datei, die entstandene .eep Datei und 
das Makefile.

Ich hoffe jemand kann helfen.
Angehängte Dateien:
#1826635
Lesenswert?

Melanie schrieb:

> Das Programm enthält lediglich die Initialisierng meiner benötigten
> Register, sowie die Vorbelegung des EEPROMS Array eeArray mit 5 Werten
> {0,0,1,1,1}.
> Die erzeugte EEPROM .eep Datei enthält diese Werte jedoch nicht.

Wie kommst du da drauf?
1
:050000000000010101F8
2
:00000001FF

sieht doch gut aus!

:05           Anzahl der Daten-Bytes, stimmt auffallend mit deinen
              Daten überein

00 00 00      dann kommen 3 Bytes, von denen 2 die Startadresse
              im EEPROM darstellen. Allesamt 0, d.h. auf jeden Fall
              mal Startadresse 0.
              Wo das 3.te Byte hingehört weiß ich jetzt nicht auswendig
              kann auch sein, dass das eigentlich zum Bytezähler
              gehört (das erste der 3). Kann aber auch sein, dass das
              letzte der Bytes so was wie eine Recordtyp Kennung ist,
              denn immerhin ist dieses Byte im anderen Datensatz 1
              und nicht wie hier 0.
              die 0 könnte also "Daten" bedeuten, während die 1 im
              anderen Datensatz "End of File" bedeutet.
              Ist aber nicht soooooo wichtig, das jetzt genau
              auzuschlüsseln

00 00 01 01 01  und hier sind sie: Deine Datenbytes aus dem Source Code

F8            noch eine Prüfsumme drüber und fertig ist der Datensatz



Aber:
Wenn wir uns mal deinen Screenshot ansehen, dann stellen wir fest, dass 
das Programmiertool mit dem EEP File nichts anzufangen wusste. Das hat 
das ganze als stink normales ASCII Textfile eingelesen.
Benutz doch bitte eine vernünftige Programmiersoftware, die auch weiß, 
dass ein EEP File einfach nur ein INTEL-Hex File mit einer anderen 
Dateiendung ist.
Gast #1826703
Lesenswert?

Karl heinz Buchegger schrieb:
> Aber:
> Wenn wir uns mal deinen Screenshot ansehen, dann stellen wir fest, dass
> das Programmiertool mit dem EEP File nichts anzufangen wusste. Das hat
> das ganze als stink normales ASCII Textfile eingelesen.
> Benutz doch bitte eine vernünftige Programmiersoftware, die auch weiß,
> dass ein EEP File einfach nur ein INTEL-Hex File mit einer anderen
> Dateiendung ist.

Dann wird das wohl der Fehler sein. Das Programm ist dann wohl in 
Ordnung, nur die Programmiersoftware ist für diesen Zweck Müll. Dann 
werde ich wohl auf PonyProg umsteigen...

Danke.
Persönliche Seite #1827590
Lesenswert?

>Wenn wir uns mal deinen Screenshot ansehen, dann stellen wir fest, dass
>das Programmiertool mit dem EEP File nichts anzufangen wusste.

Mist, das ist mir auch nicht aufgefallen, gleicher Fehler, bloß nicht 
mit Bascom, sondern mit dem Galep.

Lösung: Die .eep-Datei in .hex umbenennen.

Für weitere Verwirrung hat gesorgt, dass sich die Initialisierung von

uint8_t eeArray[] EEMEM = { 2,2,1,1,1 };

nach

uint8_t eeArray[] EEMEM = { 0,0,1,1,1 }; // Vorgabe Code im EEPROM

geändert hat.


Grüße,

Peter
Gast #1827596
Lesenswert?

> Das Programm ist dann wohl in Ordnung, nur die Programmiersoftware ist für
> diesen Zweck Müll

Naja, Bascom weis schon was es mit dem von ihm selbst erzeugten EEP File 
anzufangen hat, denn es wird dort als Binärddatei erzeugt und im 
Programmer auch so (richtig) geschrieben. Diese Info ist u.A. unter 
$EEPROMHEX zu finden, hättest halt mal auch Hilfe zu Bascom lesen 
sollen, bevor Du es einsetzt.

Versteh' allerdings auch nicht wieso Du Bascom verwendest, wenn Du C 
programmieren willst. Für C würde ich das AVR Studio zum Programmieren 
nehmen, das reicht locker und man braucht kein Pony-Prog, außer 
vielleicht für exotische Programmer-HW.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren