Hallo,
ich benutze das myAVRStudio und versuche mich gerade daran den EEPROM
des Atmega8 zu beschreiben und wieder auszugeben. Ich hab folgenden Code
aus der Hilfe geladen, jedoch bekomme ich nur Kaudawelsch als
Textausgang. Ich bin mir sicher das ich die Einstellung der Baudrate und
der Fuses richtig habe, ich weiß aber nicht wo der Fehler liegt. Hat
jemand eine Idee ???
1
#define F_CPU 3686400 // Taktfrequenz des myAVR-Boards
Funktioniert dein UART, wenn du Daten sendest, die nicht aus dem UART
stammen (simples "Hello World" z.B.). Im Moment kann UART und/oder
EEPROM die Problemursache sein. Die Problemursache EEPROM kannst du auch
ausschliessen, wenn du die bewährten EEPROM Routinen aus der avr-libc
nimmst, so wie sie im AVR-GCC-Tutorial erklärt sind...
Funktioniert deine EEPROM Schreibroutine im Simulator? Den EEPROM Inhalt
nach dem Schreiben kannst du im Simulator auslesen.
Funktioniert deine EEPROM Leseroutine im Simulator? Den EEPROM Inhalt
zum Lesen kannst du im Simulator vorgeben.
PS: Ich spanne dich so auf die Folter, weil ich 2012 keine Sourcecodes
ohne symbolische Bitnamen mehr reviewe.
Ok, wir kommen der Sache schon näher. Das auslesen scheint das problem
zu sein. Hab jetzt folgenden ausprobiert:
> Funktioniert deine EEPROM Schreibroutine im Simulator? Den EEPROM Inhalt> nach dem Schreiben kannst du im Simulator auslesen.
[c]
eeWrite:
EEDR=daten;
putChar('#');
putChar(daten);
putChar('#');
[c/]
Ausgabe:
#H##a##l##l##o## ## ##E##E##P##R##O##M##!##
> Funktioniert deine EEPROM Leseroutine im Simulator? Den EEPROM Inhalt> zum Lesen kannst du im Simulator vorgeben.
[c]
eeRead:
daten=EEDR;
putChar('*');
putChar(daten);
putChar('*');
[c/]
Ausgabe:
*ÿ*ÿ*ÿ*ÿ*ÿ*ÿ*ÿ*ÿ*ÿ
Was machst du da?
Ich gehe mal davon aus, dass das Argument daten an die Funktion
eeWrite richtig übergeben wird. Das braucht man nicht mit putchar zu
debuggen.
Lass dein Programm bis zur Stelle #1 laufen und schau im
Debugger/Simulator Im Memory-View (Speicherdump) nach, was im EEPROM
Speicher drin steht.
Rüttiger schrieb:> du hast doch das Schreiben gar nicht getestet!
Hab ih ich doch damit:
[c]
eeWrite:
EEDR=daten;
putChar('#');
putChar(daten);
putChar('#');
[c/]
Ausgabe:
#H##a##l##l##o## ## ##E##E##P##R##O##M##!##
Krapao schrieb:> Lass dein Programm bis zur Stelle #1 laufen und schau im> Debugger/Simulator Im Memory-View (Speicherdump) nach, was im EEPROM> Speicher drin steht.
Ich hab nicht die Möglichkeit in den Speicher zu gucken. Das einzige was
ich machen kann ist Werte über putChar oder putString zu senden.
Peter F. schrieb:> Rüttiger schrieb:>> du hast doch das Schreiben gar nicht getestet!>> Hab ih ich doch damit:> [c]> eeWrite:> EEDR=daten;> putChar('#');> putChar(daten);> putChar('#');> [c/]>> Ausgabe:> #H##a##l##l##o## ## ##E##E##P##R##O##M##!##
Das überprüft aber nicht, was du tatsächlich ins EEPROM geschrieben
hast.
Krapao hat es oben schon mal angesprochen:
Schau dir doch die EEPROM Funktionen aus der avr-libc an.
Oder benutze sie zum debuggen:
da die Schreibroutine dort auf jeden Fall erst mal funktioniert,
schreibst du mit der deinen String ins EEPROM und liest ihn mit deiner
eigenen aus. Damti weißt du schon mal, dass das Problem in dem Fall nur
bei deiner Leseroutine liegen kann.
Oder umgekehrt: du benutzt deine Schreibroutine und nimmst die
libc-Routine zum Lesen. Da du weißt, dass diese Funktion korrekt
funktioniert, kann in dem Fall das Problem nur bei deiner Schreibroutine
liegen.
So aber, so weißt du nicht ob deine Schreib oder deine Leseroutine
fehlerhaft ist.
Das Motto lautet: Divide et impera (teile und herrsche).
Mehrere mögliche Problemkreise so auszuschliessen, dass nur noch 1
Problemkreis übrigbleibt, der dann bearbeitet wird.
Ein Problem der Lese-Funktion ist schon mal, dass sie nicht testet ob
noch ein Schreibvorgang im Gange ist.
Dann hängt das Funktionieren der Schreib-Funktion auch noch davon ab, ob
die Optimierung aktiviert ist. Ist sie es?
PS: Wieso überhaupt eigene EEPROM-Funktionen?
Wie gesagt ich hab keine andere Möglichkeit die Daten zu überprüfen.
Karl Heinz Buchegger schrieb:> Schau dir doch die EEPROM Funktionen aus der avr-libc an
Ich bin gerade etwas überfragt, wie ich diese sinnvoll nutzen kann. Ich
hab mir schonmal das AVR-GCC-Tutorial angeguckt und versucht die
EEPROM-Routine zu nutzen. Bekomme die bei mir aber nicht zum laufen, da
bei mir einen Haufen Fehler ausgespuckt werden. Deswegen hab ich ja auch
das Codebeispiel von myAVR benutz, das Prinzip hab ich nämlich
verstanden.
Stefan Ernst schrieb:> Dann hängt das Funktionieren auch noch davon ab, ob die Optimierung> aktiviert ist. Ist sie es?
Was denn für eine Optimierung ?
> PS: Wieso überhaupt eigene EEPROM-Funktionen?
Gibt es denn eine fertige ?
Dein Code hat ein Problem, jedenfalls in meinem WinAVR 20100110
In der Sequenz
EECR=0x04; // set EEPROM Write Enabled
EECR=0x06; // set EEPROM Write
Muss das EEWE Bit (EEPROM Write) innerhalb von 4 Taktzyklen nach dem
Setzen des EEMWE (EEPROM Memory Write Enabled) Bits erfolgen.
Das kannst man mit deinem Code nicht garantieren.
Bei fehlender Optimierung (-O0) ist der erzeugte Assemblercode
deutlich zu lang! Hier wird dann sogar mit den memory mapped SFR
Adressen (Offset 0x20) und den länglichen LOAD/STORE Befehlen
gearbeitet...
Mit Optimierung -Os funktioniert der Code in diesem Programm. es wird
mit LDI/OUT gearbeitet.
Es kann (nach Murphy: wird) aber Probleme geben, wenn der kritische Code
durch einen Interrupt unterbrochen wird!
Deshalb rate ich dazu, die bewährten Routinen aus der avr-libc zu
benutzen. Die gehen beiden Problemen aus dem Weg:
1
#define F_CPU 3686400 // Taktfrequenz des myAVR-Boards
Peter F. schrieb:> Stefan Ernst schrieb:>> Die des Compilers, aktiviert mit der Option -O? (mit 1, 2, 3 oder s für>> das ?).>> So eine Option steht mir nicht zur Verfügung.
Welchen Compiler benutzt du denn?
Das hier
1
#define F_CPU 3686400 // Taktfrequenz des myAVR-Boards
2
#include<avr\io.h>
sieht sehr nach WinAVR-gcc aus. Also hast du auch die Optimierungen zur
Verfügung. Du musst nur noch die Stelle in deiner Entwicklungsumgebung
finden, in der du sie einstellst.
> Ich hab nicht die Möglichkeit in den Speicher zu gucken. Das einzige was> ich machen kann ist Werte über putChar oder putString zu senden.
Du hast kein AVR-Studio, um dem Code zu Simulieren und um
Register/Speicher anzuschauen? Ups dann ist Entwickeln übel!
Gasd schrieb:> Seid wann läuft ein Mega8 mit 36 MHz?
Wieso 36 MHz, 3,6MHz !
Krapao schrieb:> Du hast kein AVR-Studio, um dem Code zu Simulieren und um> Register/Speicher anzuschauen? Ups dann ist Entwickeln übel!
Ne, ich arbeite mit der myAVR Software.
Krapao schrieb:> Deshalb rate ich dazu, die bewährten Routinen aus der avr-libc zu> benutzen. Die gehen beiden Problemen aus dem Weg:
Ich probier das mal. Danke erstmal.
> myAVR Software
Unter Windows? Dann installier dir unbedingt das AVR-Studio parallel auf
deinem Rechner. Das gibt es kostenlos von Atmel. Dann kannst du
wenigstens deine Programme simulieren. Das ist wirklich Gold wert beim
Entwickeln, wenn man im Einzelschritt sehen kann, was passiert. Wenn das
Programm dann funktioniert, kannst du ja wieder die myAVR Software zum
Flashen benutzen. Zweiter Vorteil: Du kannst mehr Hilfe hier im Forum
benutzen. Nur wenige benutzen die myAVR Software aber relativ viele
AVR-Studio.
Krapao schrieb:> Das ist wirklich Gold wert beim> Entwickeln, wenn man im Einzelschritt sehen kann, was passiert.
Ich hba das schonmal versucht und bin daran gescheitert das AVR-Studio
meinen Programmer nicht erkannt hat (mysmartusb-mk2). Ich probiers
nochmal, vielleicht hab ich was übersehen.
Selbst wenn das so bleibt, installier es trotzdem. Allein das Simulieren
im AV-Studio bringt dir einen Riesengewinn. Zum Flashen von Hexfiles
musst du dann eventuell die myAVR Software benutzen. Aber da kenne ich
mich nicht gut aus. Vielleicht helfen andere myAVR User hier weiter.
Gasd schrieb:>> Wieso 36 MHz, 3,6MHz !> Na da streiche eine Null bei F_CPU 3686400 !!
Warum sollte er? Nur weil du dich verzählt hast?
Der Wert stimmt doch für 3,6864 MHz.
So.....hab den kram jetzt installiert. Ich kann damit jetzt simulieren,
er schreibt den Text ordentlich ins EEPROM, weiter bin ich noch nicht
gekommen. In "Quickwatch" kann ich mir die Wert nicht angucken (not in
scpope). Kann mit der Software auch debuggen oder nur simulieren ???
Karl Heinz Buchegger schrieb:> Liest du hier>> Beitrag "Unknown identifier bei Funktionsaufruf">> gleiches Problem
Ok, danke hat geklappt (Optimiertungsproblem).
So jetzt zum eigentlichen Problem...ich teste nochmal die übertragenen
Werte.
Also er schreibt den String sauber ins EEPROM. Das Problem liegt wie
erwartet im auslesen, in der Variable steht nichts drin, also kann bei
der UART-Ausgabe auch nichts kommen. Ich hab aber keine Idee warum !!!
Kommst du aber bald drauf :-)
EECR |= (1<<0);
sbi ... Set Bit in Register
oder in reiner C-Schreibweise: Register |= ( 1 << Bit );
cbi ... Clear Bit in Register
oder in reiner C-Schreibweise Register &= ~( 1 << Bit );
hat natürlich den Nachteil, dass dieses Konstrukt wieder den Optimizer
braucht um tatsächlich als 1 Assembler Instruktion generiert zu werden.
Womit sich die Katze in den Schwanz beißt.
Sagten wir schon mal, dass es fix&fertige EEPROM Funktionen gibt?
Karl Heinz Buchegger schrieb:> EECR |= (1<<0);
Hab ich ersetzt, danke.
Hab jetzt alle Fehler beseitigt. Er überträgt über die UART die
richtigen Zeichen (in der Simulation) bis char "l" und dann bleibt er in
der Zeile
1
while(!(UCSRA&32));//warte bis UDR bereit für nächstes byte ist
hängen.
Jetzt hab ich 2 Fragen:
1. Warum bleibt er an der Stelle hängen ?
2. Ich müsste dann zumindest die Buchstaben "Hal..." in der Ausgabe
sehen oder nicht ?
Hilfe...
Peter F. schrieb:> Karl Heinz Buchegger schrieb:>> EECR |= (1<<0);> Hab ich ersetzt, danke.>> Hab jetzt alle Fehler beseitigt. Er überträgt über die UART die> richtigen Zeichen (in der Simulation) bis char "l" und dann bleibt er in> der Zeile>
1
>while(!(UCSRA&32));//warte bis UDR bereit für nächstes byte ist
2
>
> hängen.> Jetzt hab ich 2 Fragen:>> 1. Warum bleibt er an der Stelle hängen ?
Weil der Simulator keine UART simuliert.
Die Register sind zwar da, aber sie arbeiten nicht so wie in der
Realität.
-> ab auf den richtigen Prozessor.
Karl Heinz Buchegger schrieb:> -> ab auf den richtigen Prozessor.
Hab ich ausprobiert. Da wird immernoch der kauderwelsch vom Anfang
angezeigt. Lt. Avr-Studio ist alles ok.
Peter F. schrieb:> Karl Heinz Buchegger schrieb:>> -> ab auf den richtigen Prozessor.>> Hab ich ausprobiert. Da wird immernoch der kauderwelsch vom Anfang> angezeigt. Lt. Avr-Studio ist alles ok.
Dann fang mal an, mit dem richtigen Prozessor zu debuggen.
Das EEPROM vom µC zurücklesen und nachsehen, ob der Text drinnen steht.
Der Simulator simuliert dann eben doch nicht alle Belange des richtigen
µC zu 100%
Peter F. schrieb:> Peter F. schrieb:>> Kann mit der Software auch debuggen oder nur simulieren ???>> Hab ich ja gefragt. Wie geht das mit mySmartUsb MK2?
Nix Debugger.
Dein Brennprogramm kann das EEPROM bechreiben UND ... es kann auch das
EEPROM wieder lesen und dir am PC ein File erstellen mit dem momentanen
Inhalt des EEPROMS.
Ich hab jetzt mal die Funktion probiert die schon existiert. Ich krieg
es einfach nicht gebacken die Funktionen aufzurufen. Wie muss denn der
Aufruf der Funktion "eeRead" aussehen (Testweise erstmal nur für den 2.
Buchstaben) ???
1
#define F_CPU 3686400 // Taktfrequenz des myAVR-Boards
Welches Argument will sie haben? Speziell: welchen Datentyp?
Wie rufst du sie auf?
1
eeRead(1)
Nun: eeRead will einen uint8_t * haben. Also eine Adresse. 1 ist aber
keine Adresse. 1 ist erst mal nur ein Integer. Du weißt aber, dass du
die Adresse 1 haben willst. Also kannst du die 1 zum richtigen Datenytp
umcasten und so den Datentyp wechseln.
Ach super danke, das hat ja schonmal funktioniert. Und wie Ffunktioniert
das mit der Write-Funktion ? So speichert er anscheinend nur den ersten
Buchstaben:
1
main()
2
{
3
initUART();
4
5
// Zeichenkette aus dem Programmspeicher in den EEPROM kopieren
Peter F. schrieb:> Ach super danke, das hat ja schonmal funktioniert. Und wie Ffunktioniert> das mit der Write-Funktion ? So speichert er anscheinend nur den ersten> Buchstaben:
Logisch.
Das ist ja auch genau das, was deine Funktion eeWrite macht: ein Byte
ins EEPROM schreiben. Ein Byte - ein Buchstabe
Wenn du also einen kompletten String ins EEPROM schreiben willst, wirst
du wohl die Funktion eeWrite für einen Buchstaben nach dem anderen
aufrufen müssen.
Genau gleich, wie wenn du einen String per UART ausgeben willst oder
einen String aufs LCD schreiben willst.
Bein einer Schreibmaschine macht ein Tastendruck immer nur einen
Buchstaben aufs Papier. Wie also kriegt man da einen ganzen Roman aufs
Papier. Einfach: Ein Buchstabe nach dem anderen.
Peter F. schrieb:> void eeWrite(uint8_t * adresse, char daten)> {> eeprom_write_byte(adresse, daten);> }
spar dir das doch einfach und rufe
eeprom_write_byte(adresse, daten);
direkt auf, zum Schreiben von mehren Bytes gibts übrigens auch eine
fertige Routine eeprom_write_block oder so ähnlich
Karl Heinz Buchegger schrieb:> Wenn du also einen kompletten String ins EEPROM schreiben willst, wirst> du wohl die Funktion eeWrite für einen Buchstaben nach dem anderen> aufrufen müssen.
Danke, hat geklappt.
Rüttiger schrieb:> spar dir das doch einfach und rufe> eeprom_write_byte(adresse, daten);>> direkt auf, zum Schreiben von mehren Bytes gibts übrigens auch eine> fertige Routine eeprom_write_block oder so ähnlich
Danke schön, werde ich auch mal in angriff nehmen.