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
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_teeArray[]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_teeArray[]EEMEM={2,2,1,1,1};
die HEX-Datei oder die .eep Datei sind unterschiedlich.
Hat einer eine Idee wieso?
Bist du sicher, dass die Initialisierung so funktioniert:
uint8_t eeArray[] EEMEM = { 2,2,1,1,1 };
Wird das wirklich beim Start des Programms in das EEPROM geschrieben?
uint8_t Array[5] = { 0 }; // Flash Variable
Das liegt im Ram, nicht im Flash, ist aber nur ein Fehler im Kommentar.
Grüße,
Peter
Soweit ich das verstehe, muss man die Initialisierung des EEPROMS immer
selber machen, also vom Compiler ein eep. file erzeugen lassen, in dem
die Initialisierungswerte stehen und das nach der Programmierung des
Programmspeichers separat programmieren. Nur so stehen die
Initialisierungswerte korrekt im EEPROM.
Grüße,
Peter
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?
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.
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.
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.
>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.
Das ist aber doch beides falsch?
Nach der Initialisierung:
uint8_t eeArray[] EEMEM = { 2,2,1,1,1 };
sollte doch an der ersten Adresse 2 stehen.
> 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 ;-)
Wenn man die Programmierschritte manuell ausführt, sollte die Fuse kein
Problem sein. Nur beim automatischen Programmierablauf wird der
Masserase automatisch durchgeführt.
Ich würde mir mal gerne das map-file anschauen, kannst du mal schnell
eins erzeugen?
> 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.
Hier noch die beiden EEPROMS im Vergleich.
Einmal das direkt vom Compiler erzeugte und einmal, wenn ich das EEPROM
mit gleichen Werten mauell über eeprom_write_block() beschreibe.
MWS schrieb:> Das wäre logisch. Nur ist's ein kleiner Klick und schon weis man, ob's> daran hängt.
Das habe ich auch versucht, bringt leider keine Änderung.
Also, das stimmt mit dem überein, was deine Programmiersoftware anzeigt.
Aber es passt nicht zum Mapfile und auch nicht zum Quelltext.
Kannst du das ganze Projekt hochladen?
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.
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.
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.
>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
> 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.