- LiTime Speicher und Akkus         
Ergebnis 1 bis 10 von 10

Thema: Seltsamer Effekt bei externen EEProm

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710

    Seltsamer Effekt bei externen EEProm

    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:
    Code:
    $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

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    *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 :
    Code:
    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 !
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    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:

    Code:
    $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

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    ups, fehler von mir.....

    Die Routinen sollten so Aussehen:

    Code:
    '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

  5. #5
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    juhu, es geht...danke PicNick.....

    war ein Fehler meiner gedanken. Natürlich muß ich die Overlayadadresse um 2 Verschieben....jetzt gehts!!

    Code:
    $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

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    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
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    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.

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    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.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    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

    Code:
    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

  10. #10
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Na klar, stell es rein, gerade dieses Rad wird ja mit Begeisterung immer wieder neu erfunden.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus