PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : "WORD" aus EEPROM lesen/schreiben



BASTIUniversal
04.11.2004, 15:10
Hallo,
ich hab seit Freitag dieses µC Testboard von Rolan Walter (inkl. Buch) und seit Dienstag nen DS18S20.
Nun ist es mir schon gelungen die Temperatur auszulesen und über UART an meinen PC zu schicken (den Code hab ich von jemandem aus diesem Forum geklaut *schäm*).
Nun hab ich mich gestern dazu aufgemacht die Temperatur Variable ins interne EEPROM meines Mega8 zu schreiben und wieder zu lesen.
Nur leider klappt das lesen nich 100%ig. Es kommt im Terminal immer
4096
16
4096
16
etc... (16 entspricht dabei der Temperatur in °C)

Zum schreiben hab ich mir folgenden Code geschrieben:

Sub Save

'Disable Timer1 ; Disable Interrupts 'Timer1 und Interrupts bereits Disabled von Sub Temp!
L = 0 'Variable L auf 0 setzen
Writeeeprom Temperatur , Adr 'Variable Temperatur nach Adresse Adr ins EEPROM schreiben
Incr Adr 'Variable Adr um 2 erhöhen, da Temperatur 2 Byte speicher benötigt!
Incr Adr
If M = 30 Then Writeeeprom Adr , K 'Nach 10 Minuten aktuelle Adresse auf Adresse 0 schreiben ("Backup")
If M = 30 Then M = 0 'M auf 0 setzen, damit nach 10 Minuten ein Backup gemacht wird
If Adr = 255 Then Adr = 1 'Wenn Adressbyte Adr 255 ist, Adr auf 1 setzen

Enable Timer1
Enable Interrupts 'Timer1 und Interrupts wieder aktivieren!

End Sub
Timer1 mit Prescale=1024 löst den Interrupt aus welcher die Variablen L und M um 1 erhöht. Wenn die Variable 1 den Wert 3 erreicht hat wird die Temperatur ausgelesen und als Variable "Temperatur" gespeichert. Danach wird die Variable ins EEPROM geschrieben und L auf 0 gesetzt. Wenn M 30 erreicht wird die aktuelle Adresse nach Adresse 0 ins EEPROM geschrieben (will da später ggf. noch was draus machen).
Ganz zu beginn wird das EEPROM von der Adresse 0 bis 255 gelöscht (wird überall 0 geschrieben).

Zum lesen wird folgender Code von mir verwendet:

Sub Send

Disable Timer1
Disable Interrupts 'Deaktivieren von Timer1 und Interrupts da aktion Zeitkritisch!

For Adr2 = 1 To 255 'Adressen 1 bis 255 auslesen und an UART ausgeben
Readeeprom Tempread , Adr2 'Lese Eeprom aus
Print Tempread 'Temperatur an UART ausgeben
Next Adr2

Enable Timer1
Enable Interrupts 'Timer1 und Interrupts wieder aktivieren!

End Sub

Die Adresse 1 bis 255 (dort wird die Variable "Temperatur" gespeichert) werden ausgelesen und in die Variable "Tempread" gespeichert. Die Variable wird dann an die UART ausgegeben.
Die Interrupts und der Timer1 werden sicherheitshalber deaktiviert, damit kein Interrupt dazwischen kommt.
Die Sub Send wird durch einen Taster aktiviert, oder wenn ich den Buchstaben "S" an den µC schicke.

Was mache ich falsch, das ich nicht nur die Temperatur angezeigt bekomme, sondern auch noch anderen Müll (In dem Fall die 4096)? Kann mir da jemand weiterhelfen?
Kann ich als Adresse auch ein "WORD" nehmen anstatt eines "BYTE"? Muss ich dabei etwas besonderes beachten?

Sorry für diesen langen Aufsatz, aber ich wäre froh wenn mir jemand weiterhelfen kann!

MfG
Basti

x-ryder
04.11.2004, 15:27
ich glaub deine lesen sub iss falsch da lieste immer das erste byte, gibst es aus und dann das zweite und gibst es aus und so weiter


Sub Send

Disable Timer1
Disable Interrupts 'Deaktivieren von Timer1 und Interrupts da aktion Zeitkritisch!

For Adr2 = 1 To 255 'Adressen 1 bis 255 auslesen und an UART ausgeben
Adr3 = Adr2 + 1
Readeeprom Tempread , Adr2 'Lese Eeprom aus
Readeeprom Tempread2 , Adr3 'Lese Eeprom aus
Tempread3 = Makeint(Temread , Tempread2)
Print Tempread3 'Temperatur an UART ausgeben
Next Adr2

Enable Timer1
Enable Interrupts 'Timer1 und Interrupts wieder aktivieren!

End Sub

So iss nicht getestet aber sollte funzn

Martin

BASTIUniversal
04.11.2004, 15:59
Du hast ne kleinigkeit übersehen:
Für die erste Adresse stimmt die berechnung wohl (Adr2 + 1), für Adr3 kommt 2 raus. Für die nachfolgenden Adressen ist die berechnung aber unzulässig:
Adr2 wird immer um 1 hochgezählt. Für die erste Adresse gilt also: 1+1=2 -> Adr3 wird 2 (was die Adresse für's MSB darstellt). Für die zweite Adresse gilt dann aber 2+1=3 -> Adr3 wird 3, was logischerweise aber die LSB adresse darstellen sollte (die LSB Adresse wäre hier 2 was nicht stimmen kann!).

Wenn man die Variable Adr2 immer um 2 hochzählen lässt stimmt die ganze Sache :-)

Hoffe du bist nicht böse das ich dich verbessert hab...!

MfG

x-ryder
04.11.2004, 16:04
Sub Send

Disable Timer1
Disable Interrupts 'Deaktivieren von Timer1 und Interrupts da aktion Zeitkritisch!

For Adr2 = 1 To 255 step 2 'Adressen 1 bis 255 auslesen und an UART ausgeben
Adr3 = Adr2 + 1
Readeeprom Tempread , Adr2 'Lese Eeprom aus
Readeeprom Tempread2 , Adr3 'Lese Eeprom aus
Tempread3 = Makeint(Temread , Tempread2)
Print Tempread3 'Temperatur an UART ausgeben
Next Adr2

Enable Timer1
Enable Interrupts 'Timer1 und Interrupts wieder aktivieren!

End Sub

Nönö garnicht wollt ich eigentlich auch machn habs aba denn doch vergessen 8-[

BASTIUniversal
04.11.2004, 16:10
Was ich noch bemerkt hab: Wenn man jetzt die Werte abruft geht der AVR in ne Art Endlosschleife über...der erreicht nie 255 wenn man ihn immer um 2 erhöhen lässt! Mit 254 funktioniert das wunderbar *g*

Nochmal zu der anderen Sache: Geht das wenn ich Adr als Word dimensioniere anstatt als Byte? Muss ich was beachten?

x-ryder
04.11.2004, 16:18
Ich habs nur mal grad compiliert und es scheint zu gehen...

Martin

BASTIUniversal
04.11.2004, 16:21
Danke @x-ryder! Hast mir sehr geholfen!

MfG

Marco78
18.03.2005, 23:31
Nochmal eine Frage zu Word im EEPROM ablegen.
Den Code von BASTIUniversal kann ich noch nicht ganz nachvollziehen.
Wenn ich z.B. 12345 in eine EEPROM-Adresse (z.B. 10) schreibe, wird der Wert dann automatisch auf 2 Bytes aufgeteilt?
Also habe ich das Word dann in 10 und 11 ohne was dafür gemacht zu haben und kann es mit makeint wieder zusammenführen?