Archiv verlassen und diese Seite im Standarddesign anzeigen : Seltsamer Effekt bei externen EEProm
Rage_Empire
07.01.2006, 13:12
Hallo,
ich hab nen Source geschrieben, welcher mir als Subs erleichtern soll Variabeln in ein 24C64 zu speichern und zu lesen. Möglich sind bei mir damit auch word uns Singles zu verarveiten.
Jedoch tritt hier ein seltsamer Effekt auf. Wenn ich z.B. die Single 12.65 speichr möchte geschieht folgendes:
Die Single im Ram wird zu 12.649999....
Ok, kann ja sein, da es sich um Singles und nich um Doubles handelt....wäre für mich ok. Aber wenn ich diesen Wert wieder aus dem EEprom lese ist er 12.625!
Wie kommt das? Ich selbst kam dem rätsel noch nicht auf die Spur, aber vieleicht kann mmir von euch jemand sagen, was hier passiert.
Source auf Single-Variabeln gekürzt:
$lib "i2c.lib"
Config Scl = Portc.0 'PIN für I2C Bus
Config Sda = Portc.1
I2cinit
Config I2cdelay = 3
Dim Eesingle As Single
Dim Eeword(2) As Word At Eesingle Overlay
Dim Eebyte(6) As Byte At Eesingle Overlay
Dim Eebanz As Byte
Dim Ee_adresse As Word
Const 24c64w = &B10100000
Const 24c64r = &B10100001
'Definition der Funktionen ++++++++++++++++++++++++++++++++++++++++++++++++++ ++
Declare Function Loadsingle(byval Ee_adresse As Word) As Single
Declare Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word )
Goto 001
Sub Savesingle(byval Ee_daten As Single , Byref Ee_adresse As Word )
Eesingle = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 4 : Gosub Write_ee
End Sub
Function Loadsingle(byref Ee_adresse As Word) As Single
Ee_adresse = Ee_adresse
Eebanz = 4 : Gosub Read_ee
Loadsingle = Eesingle
End Function
'Routine zum schreiben von Daten in das EEPROM ++++++++++++++++++++++++++++++++
Write_ee:
Eebanz = Eebanz + 2
Eebyte(1) = High(ee_adresse)
Eebyte(2) = Low(ee_adresse)
I2csend 24c64w , Eebyte(1) , Eebanz
Waitms 30
Return
'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++
Read_ee:
Eebyte(1) = High(ee_adresse)
Eebyte(2) = Low(ee_adresse)
I2csend 24c64w , Eebyte(1) , 2
Waitms 5
I2creceive 24c64r , Eebyte(3) , 0 , Eebanz
Waitms 25
Return
001:
Dim Ins As Single
Dim Inw As Word
Dim Inb As Byte
Do
Input "Single: " , Ins
Call Savesingle(ins , 100)
Print "gespeicherter Wert: ";ins
Ins = 0
Ins = Loadsingle(100)
Print "geladener Wert: " ; Ins
Loop
*murmel* Ich versteh' deine Definition nicht so ganz:
1 ... eesingle.....eeword(1)....eebyte(1)............ overlay adresse
2.... eesingle.....eeword(1)....eebyte(2)
3.... eesingle.....eeword(2)....eebyte(3)
4.....eesingle.....eeword(2)....eebyte(4)
5........................................eebyte(5)
6........................................eebyte(6)
7.....eebanz
8.....eeaddr1
9.....eeaddr2
Beim write-ee zerschmetterst du ja zwei bytes vom single
Eebyte(1) = High(ee_adresse)
Eebyte(2) = Low(ee_adresse)
Vorschlag, wenn ich richtig interpretiere, was du wohl meinst :
Dim Eehead(2) As Byte
Dim Eedata(4) As Byte
Dim Eesingle As Single At Eedata Overlay
Dim Eeword(2) As Word At Eedata Overlay
Write_ee:
Eebanz = Eebanz + 2
Eehead(1) = High(ee_adresse)
Eehead(2) = Low(ee_adresse)
I2csend 24c64w , Eehead(1) , Eebanz
return
Read_ee:
Eehead(1) = High(ee_adresse)
Eehead(2) = Low(ee_adresse)
I2csend 24c64w , Eehead(1) , 2
Waitms 5
I2creceive 24c64r , Eedata(1) , 0 , Eebanz
Waitms 25
return
Versuch' mal !
Rage_Empire
07.01.2006, 15:03
Hallo PicNick,
gedacht war es so:
eesingle....eeword(2)......eebyte(6)
eesingle....eeword(2)......eebyte(5)
eesingle....eeword(1)......eebyte(4)
eesingle....eeword(1)......eebyte(3)
....................................eebyte(2)----------für Adresse(HighByte)
....................................eebyte(1)----------für Adresse(LowByte)
Mit Words funktionierts ganz gut, nur mit singles nicht:
$lib "i2c.lib"
Config Scl = Portc.0 'PIN für I2C Bus
Config Sda = Portc.1
I2cinit
Config I2cdelay = 3
Dim Eesingle As Single
Dim Eeword(2) As Word At Eesingle Overlay
Dim Eebyte(6) As Byte At Eesingle Overlay
Dim Eebanz As Byte
Dim Ee_adresse As Word
Dim Ee_adr(2) As Byte At Ee_adresse Overlay
Const 24c64w = &B10100000
Const 24c64r = &B10100001
'Definition der Funktionen ++++++++++++++++++++++++++++++++++++++++++++++++++ ++
Declare Function Loadbyte(byval Ee_adresse As Word) As Byte
Declare Function Loadword(byval Ee_adresse As Word) As Word
Declare Function Loadsingle(byval Ee_adresse As Word) As Single
Declare Sub Savebyte(byval Ee_daten As Byte , Byval Ee_adresse As Word)
Declare Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word)
Declare Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word )
Goto 001
Sub Savebyte(byval Ee_daten As Byte , Byval Ee_adresse As Word)
Eebyte(3) = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 1 + 2 : Gosub Write_ee
End Sub
Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word)
Eeword(2) = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 2 + 2 : Gosub Write_ee
End Sub
Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word )
Eesingle = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 4 + 2 : Gosub Write_ee
End Sub
Function Loadbyte(byval Ee_adresse As Word) As Byte
Ee_adresse = Ee_adresse
Eebanz = 1 : Gosub Read_ee
Loadbyte = Eebyte(3)
End Function
Function Loadword(byval Ee_adresse As Word) As Word
Ee_adresse = Ee_adresse
Eebanz = 2 : Gosub Read_ee
Loadword = Eeword(2)
End Function
Function Loadsingle(byval Ee_adresse As Word) As Single
Ee_adresse = Ee_adresse
Eebanz = 4 : Gosub Read_ee
Loadsingle = Eesingle
End Function
'Routine zum schreiben von Daten in das EEPROM ++++++++++++++++++++++++++++++++
Write_ee:
Eebyte(1) = Ee_adr(1)
Eebyte(2) = Ee_adr(2)
I2csend 24c64w , Eebyte(1) , Eebanz
Waitms 30
Return
'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++
Read_ee:
Eebyte(1) = Ee_adr(1)
Eebyte(2) = Ee_adr(2)
I2csend 24c64w , Eebyte(1) , 2
Waitms 5
I2creceive 24c64r , Eebyte(3) , 0 , Eebanz
Waitms 25
Return
001:
Dim Ins As Single
Dim Inw As Word
Dim Inb As Byte
Do
Input "Single: " , Ins
Call Savesingle(ins , 100)
Print "gespeicherter Wert: ";ins
Ins = Loadsingle(100)
Print "geladener Wert: " ; Ins
Input "Word: " , Inw
Call Saveword(inw , 100)
Print "gespeicherter Wert: " ; Inw
Inw = Loadword(100)
Print "geladener Wert: " ; Inw
Input "Byte: " , Inb
Call Savebyte(inb , 100)
Print "gespeicherter Wert: " ; Inb
Inb = Loadbyte(100)
Print "geladener Wert: " ; Inb
Loop
Rage_Empire
07.01.2006, 15:07
ups, fehler von mir.....
Die Routinen sollten so Aussehen:
'Routine zum schreiben von Daten in das EEPROM ++++++++++++++++++++++++++++++++
Write_ee:
Eebyte(1) = Low(ee_adresse)
Eebyte(2) = High(ee_adresse)
I2csend 24c64w , Eebyte(1) , Eebanz
Waitms 30
Return
'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++
Read_ee:
Eebyte(1) = Low(ee_adresse)
Eebyte(2) = High(ee_adresse)
I2csend 24c64w , Eebyte(1) , 2
Waitms 5
I2creceive 24c64r , Eebyte(3) , 0 , Eebanz
Waitms 25
Return
Rage_Empire
07.01.2006, 15:14
juhu, es geht...danke PicNick.....
war ein Fehler meiner gedanken. Natürlich muß ich die Overlayadadresse um 2 Verschieben....jetzt gehts!!
$lib "i2c.lib"
Config Scl = Portc.0 'PIN für I2C Bus
Config Sda = Portc.1
I2cinit
Config I2cdelay = 3
Dim Eesingle As Single
Dim Eeword(2) As Word At Eesingle Overlay
Dim Eebyte(6) As Byte At Eesingle + 2 Overlay '<------um 2 verschoben!!!
Dim Eebanz As Byte
Dim Ee_adresse As Word
Const 24c64w = &B10100000
Const 24c64r = &B10100001
Const Eetest = 0
'Definition der Funktionen ++++++++++++++++++++++++++++++++++++++++++++++++++ ++
Declare Function Loadbyte(byval Ee_adresse As Word) As Byte
Declare Function Loadword(byval Ee_adresse As Word) As Word
Declare Function Loadsingle(byval Ee_adresse As Word) As Single
Declare Sub Savebyte(byval Ee_daten As Byte , Byval Ee_adresse As Word)
Declare Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word)
Declare Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word )
Goto 001
Sub Savebyte(byval Ee_daten As Byte , Byval Ee_adresse As Word)
Eebyte(3) = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 1 + 2 : Gosub Write_ee
End Sub
Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word)
Eeword(2) = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 2 + 2 : Gosub Write_ee
End Sub
Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word )
Eesingle = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 4 + 2 : Gosub Write_ee
End Sub
Function Loadbyte(byval Ee_adresse As Word) As Byte
Ee_adresse = Ee_adresse
Eebanz = 1 : Gosub Read_ee
Loadbyte = Eebyte(3)
End Function
Function Loadword(byval Ee_adresse As Word) As Word
Ee_adresse = Ee_adresse
Eebanz = 2 : Gosub Read_ee
Loadword = Eeword(2)
End Function
Function Loadsingle(byval Ee_adresse As Word) As Single
Ee_adresse = Ee_adresse
Eebanz = 4 : Gosub Read_ee
Loadsingle = Eesingle
End Function
'Routine zum schreiben von Daten in das EEPROM ++++++++++++++++++++++++++++++++
Write_ee:
Eebyte(1) = Low(ee_adresse)
Eebyte(2) = High(ee_adresse)
I2csend 24c64w , Eebyte(1) , Eebanz
Waitms 30
Return
'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++
Read_ee:
Eebyte(1) = Low(ee_adresse)
Eebyte(2) = High(ee_adresse)
I2csend 24c64w , Eebyte(1) , 2
Waitms 5
I2creceive 24c64r , Eebyte(3) , 0 , Eebanz
Waitms 25
Return
001:
Dim Ins As Single
Dim Inw As Word
Dim Inb As Byte
Do
Input "Single: " , Ins
Call Savesingle(ins , 100)
Print "gespeicherter Wert: ";ins
Ins = Loadsingle(100)
Print "geladener Wert: " ; Ins
Input "Word: " , Inw
Call Saveword(inw , 100)
Print "gespeicherter Wert: " ; Inw
Inw = Loadword(100)
Print "geladener Wert: " ; Inw
Input "Byte: " , Inb
Call Savebyte(inb , 100)
Print "gespeicherter Wert: " ; Inb
Inb = Loadbyte(100)
Print "geladener Wert: " ; Inb
Loop
Ja, aber eebyte(1) ist direkt im single drinnen.
und beim lesen: eebyte(3) ist ja schon das dritte byte vom single.
also, die Sub's sind nicht das Schlimme, die definition ist ungünstig.
Schau genau, was ich anders ge"dim"t habe
Daß der Fehler so seltsam scheint, liegt daran, daß du nur die beiden Low bytes von single vernichtet hast. dadurch sind es immer ~12.6 geblieben
Rage_Empire
07.01.2006, 15:24
Aber PicNick, ich bin mir nicht sicher ob deine Senderoutine noch laufen würde, da du ja nur die Adresse schicken würdest und keine Daten Mehr.
Wenn du von irgendein x-beliebigen addresse 4+2 byte schicken tust, dann kennt er keine Feldgrenzen mehr (das single steht ja direkt hinter head )
I2csend 24c64w , Eehead(1) , Eebanz
Aber egal, du hast hast das Problem ja erkannt, und wenn's jetzt funzt, dann funzt's
Und wenn's nicht funzt, dann zeichne deine Datenfeldern und Bytes so richtig auf kariertem Papier auf. Mir z.B. hilft das, ich bin ein visueller Typ.
Rage_Empire
07.01.2006, 18:01
Hab das ganze mal nach deinen Vorgaben umgestrickt und es funktioniert wunderbar. Werden den Source evtl. ins Download-Verzeichnis stellen, da vieleicht noch der eine oder andere sich sonst den kopf darüber zerbricht....man muß das Rad ja nich immer neu erfinden ;-)
Config Scl = Portc.0 'PIN für I2C Bus
Config Sda = Portc.1
I2cinit
Dim Eehead(2) As Byte
Dim Eebyte(4) As Byte
Dim Eesingle As Single At Eebyte Overlay
Dim Eeword(2) As Word At Eebyte Overlay
Dim Eebanz As Byte
Dim Ee_adresse As Word
Const 24c64w = &B10100000
Const 24c64r = &B10100001
'Definition der Funktionen ++++++++++++++++++++++++++++++++++++++++++++++++++ ++
Declare Function Loadbyte(byval Ee_adresse As Word) As Byte
Declare Function Loadword(byval Ee_adresse As Word) As Word
Declare Function Loadsingle(byval Ee_adresse As Word) As Single
Declare Sub Savebyte(byval Ee_daten As Byte , Byval Ee_adresse As Word)
Declare Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word)
Declare Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word )
Goto 001
Sub Savebyte(byval Ee_daten As Byte , Byval Ee_adresse As Word)
Eebyte(3) = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 1 + 2 : Gosub Write_ee
End Sub
Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word)
Eeword(2) = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 2 + 2 : Gosub Write_ee
End Sub
Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word )
Eesingle = Ee_daten
Ee_adresse = Ee_adresse
Eebanz = 4 + 2 : Gosub Write_ee
End Sub
Function Loadbyte(byval Ee_adresse As Word) As Byte
Ee_adresse = Ee_adresse
Eebanz = 1 : Gosub Read_ee
Loadbyte = Eebyte(3)
End Function
Function Loadword(byval Ee_adresse As Word) As Word
Ee_adresse = Ee_adresse
Eebanz = 2 : Gosub Read_ee
Loadword = Eeword(2)
End Function
Function Loadsingle(byval Ee_adresse As Word) As Single
Ee_adresse = Ee_adresse
Eebanz = 4 : Gosub Read_ee
Loadsingle = Eesingle
End Function
'Routine zum schreiben von Daten in das EEPROM ++++++++++++++++++++++++++++++++
Write_ee:
Eehead(1) = High(ee_adresse)
Eehead(2) = Low(ee_adresse)
I2csend 24c64w , Eehead(1) , Eebanz
Waitus 40000
Return
'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++
Read_ee:
Eehead(1) = High(ee_adresse)
Eehead(2) = Low(ee_adresse)
I2csend 24c64w , Eehead(1) , 2
Waitus 20000
I2creceive 24c64r , Eebyte(1) , 0 , Eebanz
Waitus 40000
Return
001:
Dim Ins As Single
Dim Inw As Word
Dim Inb As Byte
Do
Input "Single: " , Ins
Call Savesingle(ins , 100)
Print "gespeicherter Wert: ";ins
Ins = Loadsingle(100)
Print "geladener Wert: " ; Ins
Input "Word: " , Inw
Call Saveword(inw , 100)
Print "gespeicherter Wert: " ; Inw
Inw = Loadword(100)
Print "geladener Wert: " ; Inw
Input "Byte: " , Inb
Call Savebyte(inb , 100)
Print "gespeicherter Wert: " ; Inb
Inb = Loadbyte(100)
Print "geladener Wert: " ; Inb
Loop
Na klar, stell es rein, gerade dieses Rad wird ja mit Begeisterung immer wieder neu erfunden.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.