- Akku Tests und Balkonkraftwerk Speicher         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 29

Thema: Probleme mit eeprom Speicherchip

  1. #11
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    Anzeige

    LiFePo4 Akku selber bauen - Video
    ach, jetzt verstehe ich. wenn der block überläuft(find grad kein besseren ausdruck), gibts probleme und verursacht das chaos. ok, habs geschnallt. aber wie soll man das verhindern? könnt mir nur vorstellen, wenn vor jedem byte die adresse geschickt wird. shit, das raubt speed und resourcen. ich dank dir hrei, wäre nicht draufgekommen.

  2. #12
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185
    @hrei
    Du hast es besser formuliert, dass I2CSEND in der source tötlich sein kann

  3. #13
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    dann versuch ichs mal so:

    Code:
    $lib "i2c_TWI.lib"
    Config Scl = Portc.0                                        'PIN für I2C Bus
    Config Sda = Portc.1
    I2cinit
    
    Config Twi = 400000
    
    Dim Eehead(2) As Byte
    Dim Ee_adresse01 As Word At Eehead Overlay
    Dim Eebyte(4) As Byte
    Dim Eesingle As Single At Eebyte Overlay
    Dim Eeword(2) As Word At Eebyte Overlay
    Dim Tempeebyte(4) As Byte
    
    Dim Eebanz As Byte
    Dim Eead As Word
    Dim Exteetemp As Byte
    
    Const 24c64w = &B10100000
    Const 24c64r = &B10100001
    
    Const Eetest = 1
    
    '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(byref Ee_daten As Byte , Byval Ee_adresse As Word)
    Declare Sub Saveword(byref Ee_daten As Word , Byval Ee_adresse As Word)
    Declare Sub Savesingle(byref Ee_daten As Single , Byval Ee_adresse As Word )
    
    Goto 001
    
    Sub Savebyte(byref Ee_daten As Byte , Byval Ee_adresse As Word)
    Eebyte(1) = Ee_daten
    Ee_adresse01 = Ee_adresse
    Eebanz = 1 : Gosub Write_ee
    End Sub
    
    Sub Saveword(byref Ee_daten As Word , Byval Ee_adresse As Word)
    Eeword(1) = Ee_daten
    Ee_adresse01 = Ee_adresse
    Eebanz = 2 : Gosub Write_ee
    End Sub
    
    Sub Savesingle(byref Ee_daten As Single , Byval Ee_adresse As Word )
    Eesingle = Ee_daten
    Ee_adresse01 = Ee_adresse
    Eebanz = 4 : Gosub Write_ee
    End Sub
    
    
    Function Loadbyte(byval Ee_adresse As Word) As Byte
    Ee_adresse01 = Ee_adresse
    Eebanz = 1 : Gosub Read_ee
    Loadbyte = Eebyte(1)
    End Function
    
    Function Loadword(byval Ee_adresse As Word) As Word
    Ee_adresse01 = Ee_adresse
    Eebanz = 2 : Gosub Read_ee
    Loadword = Eeword(1)
    End Function
    
    Function Loadsingle(byval Ee_adresse As Word) As Single
    Ee_adresse01 = Ee_adresse
    Eebanz = 4 : Gosub Read_ee
    Loadsingle = Eesingle
    End Function
    
    
    
    
    
    
    'Routine zum schreiben von Daten in das EEPROM ++++++++++++++++++++++++++++++++
    
    Write_ee:
    Eead = Ee_adresse01 + Eebanz
    For Exteetemp = 1 To Eebanz Step 1
    I2cstart
    I2cwbyte 24c64w                                             'send slave address
    I2cwbyte Eehead(1)
    I2cwbyte Eehead(2)
    I2cwbyte Eebyte(exteetemp)                                  'send a value
    I2cstop
    incr Ee_adresse01
    Waitms 10
    Next
    Return
    
    
    'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++
    Read_ee:
        Eead = Ee_adresse01 + Eebanz
        I2csend 24c64w , Eehead(1) , 2
        waitms 1
        I2creceive 24c64r , Eebyte(1) , 0 , Eebanz
    Return
    
    001:
    #if Eetest = 1
    
    Dim Ins As Single
    Dim Inw As Word
    Dim Inb As Byte
    
    Do
    Input "Single: " , Ins
    Call Savesingle(ins , 5)
    Print "gespeicherter Wert: " ; Ins
    Ins = Loadsingle(5)
    Print "geladener Wert: " ; Ins
    
    Input "Word: " , Inw
    Call Saveword(inw , 10)
    Print "gespeicherter Wert: " ; Inw
    Inw = Loadword(10)
    Print "geladener Wert: " ; Inw
    
    Input "Byte: " , Inb
    Call Savebyte(inb , 30)
    Print "gespeicherter Wert: " ; Inb
    Inb = Loadbyte(30)
    Print "geladener Wert: " ; Inb
    Loop
    #endif

  4. #14
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185
    die 'Waitus 10000' in Routine zum Lesen von Daten sind unnötig

  5. #15
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    Ok, danke. hab ich geändert.
    Jetzt versteh ich noch nicht ganz, warum das EEPROM für ein Byte genau so viel Zeit benötigt wie für den Page-Write modus wo mehr Informationen gespeichert werden?
    Byte-Write: Muß man nach jedem Byte ein Stop machen, oder kann man mit einem neuen Start gleich das nächste Byte schreiben?

  6. #16
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.12.2004
    Alter
    71
    Beiträge
    277
    Zitat Zitat von Rage_Empire
    Ok, danke. hab ich geändert.
    Jetzt versteh ich noch nicht ganz, warum das EEPROM für ein Byte genau so viel Zeit benötigt wie für den Page-Write modus wo mehr Informationen gespeichert werden?
    Es braucht schon etwas mehr Zeit, das fällt Dir aber nicht auf. Das Übergeben der Adresse geht so flott, daß es nicht ins Gewicht fällt. Was Zeit braucht (10mS) ist das Schreiben der Daten. Im Gegensatz zu Tomas würde ich daher den Waitbefehl auch drinlassen, aus Übersichtlichkeitsgründen aber Waitms statt Waitus nehmen.
    Damit ist sichergestellt, daß die Daten fehlerfrei geschrieben werden. Es geht wegen des Zeitverbrauchs der restlichen Routine meist auch ohne, nur verlassen kann man sich nicht darauf. Sonst müsste man schulmäßig abfragen, ob das EEprom bereits fertig ist (siehe Datenblatt).
    Byte-Write: Muß man nach jedem Byte ein Stop machen, oder kann man mit einem neuen Start gleich das nächste Byte schreiben?
    Ja, das Stop ist zwingend notwendig, sonst bist Du wieder ganz unfreiwillig im Page/Blockwrite Modus .

    Etwas allgemeines zu Demprogrammen:

    Es ist zweckmäßig bei Demos "Klein Fritzchen"- mäßig vorzugehen. Wir wollen ja nicht beweisen, wie schön wir Schleifen verschachteln können und wie kryptisch Programme sein können, sondern demonstrieren, wie der Quatsch im Prinzip funktioniert.
    Auch aussagekräftige Variablennamen, und geordnete Kommentare sind wichtig.

    Hier mal ein Beispiel zum Wordwrite mit einem anderen Ansatz, das aus eben diesen Gründen so simple gestrickt ist (die Kopfdeklarationen bitte einfach überlesen, die sind nur für meinen Experimenter interessant):

    Code:
    '-------------------------------------------------------------------------------
    '-------------- 24Cxx EEPROM Test für M8 /168 /M32-Experimenter ----------------
    '                             April 2006 - HR
    '-------------------------------------------------------------------------------
    $regfile = "m8def.dat"
    '$regfile = "m168def.dat"
    $regfile = "m32def.dat"
    $crystal = 7372800
    '$crystal = 14745000
    '$crystal = 16000000
    
    $baud = 9600
    
    $hwstack = 64
    $swstack = 64
    $framesize = 64
    
    '-------------------------------------------------------------------------------
    
    '-------------------------------------------------------------------------------
    '$lib "i2c_twi.lbx"                           'Hardware I2C
    'Config Twi = 100000
    Config Scl = Portc.5                         'für Mega8 und 168
    Config Sda = Portc.4
    Portc.5 = 1
    Portc.4 = 1
    'Config Scl = Portc.0                         'für Mega16 und 32
    'Config Sda = Portc.1
    'Portc.0 = 1
    'Portc.1 = 1
    I2cinit
    '-------------------------------------------------------------------------------
    $lib "Lcd_i2c.lib"                           'i2c Treiber für das LCD
    Dim _lcd_e As Byte                           'Nötig für die Enable Auswahl
    _lcd_e = 128                                 'Für LCDs mit 1 Controller
    Waitms 200
    '-------------------------------------------------------------------------------
    Config Lcd = 16 * 2
    Display On
    Cursor Off
    '-------------------------------------------------------------------------------
    
    Config Adc = Single , Prescaler = Auto       'Für Analogtastatur
    Config Portd.3 = Output                      'Für LED1
    Config Portd.4 = Output                      'Für LED2
    
    'Beep Alias Portc.2                           'für Mega32
    Beep Alias Portb.0                           'für Mega8
    
    '-------------------------------------------------------------------------------
    Const Pcf8591 = 144                          'DA-AD-Wandler auf Basis
    Const Eeprom2 = 166                          'Eeprom2 auf Basis
    Const Eeprom1 = 174                          'Eeprom1 oder Ram auf Basis
    Const Eeprom0 = 160                          'externes Cip Card Eeprom0
    Const Pcf8574_1 = 64
    Const Tda8444 = 78                           'DA-Wandler auf Extension-Platine
    Const Pcf8574_lcd = 112                      'Portextension für LCD
    Const Pcf8583_rtc = 162                      'RTC auf Extension-Platine
    
    Const Max520 = 94                            'für MAX520 (extern)
    Const Keyboard = 0                           'ADC-Nr. für Analogtastatur
    
    '-------------------------------------------------------------------------------
    
    
    Declare Function Read_eeprom(byval Dev As Byte , Byref Address As Word)as Byte
    Declare Function Read_eeprom_word(byref Address As Word)as Word
    
    Declare Sub Write_eeprom(byval Dev As Byte , Byref Address As Word , Byval Wert_
    As Byte)
    Declare Sub Write_eeprom_word(byref Address As Word , Byref Value As Word)
    
    Dim Address_low As Byte                      'Address ist hier überlappend
    Dim Address_high As Byte                     'dimensioniert, um High- und Low-
    Dim Address As Word At Address_low Overlay   'Byte einfach ansprechen zu können.
    
    Dim Value_low As Byte                        'Dito mit Value
    Dim Value_high As Byte
    Dim Value As Word At Value_low Overlay
    
    Dim Wert As Byte
    Dim Temp_w As Word
    Dim I As Word
    
    
    '------------------------------ Demodurchlauf ----------------------------------
    
    Cls                                          'Intro
    Lcd "EEPROM TEST"
    Locate 2 , 1
    Lcd "SCHREIBE"
    Wait 2
    
    Value = 1500
    For Address = 250 To 500                     'von Adresse 250 bis 500
      Call Write_eeprom_word(address , Value)    'value  ins EEprom schreiben.
      Value = Value + 20                         'Value zur Abwechslung
    Next                                         'um 20 erhöhen
    
    '-------------------------------------------------------------------------------
    Wait 2
    Cls
    Lcd " LESE"
    
    For Address = 250 To 500                     'die Werte wieder auslesen
      Temp_w = Read_eeprom_word(address)
      Locate 2 , 1
      Lcd "A: " ; Address ; " " ; "W: " ; Temp_w ; "   "
      Wait 1                                     'Pause, damit man was sieht
    Next
    
    Locate 1 , 1
    Lcd "FERTIG"
    '------------------------ Ende Demodurchlauf -----------------------------------
    End
    
    
    '------------------------ Funktionen und Subs ----------------------------------
    
    '-------------------------------------------------------------------------------
    '- Word (value) auf 2 aufeinander folgende EEprom Adressen schreiben
    
    Sub Write_eeprom_word(byref Address As Word , Byref Value As Word)
    Call Write_eeprom(eeprom1 , Address , Value_low)
    Incr Address
    Call Write_eeprom(eeprom1 , Address , Value_high)
    End Sub
    '-------------------------------------------------------------------------------
    '- Word von 2 aufeinanderfolgenden EEprom Adressen lesen
    '- Der gelesene Wert ist der Rückgabewert der Funktion
    
    Function Read_eeprom_word(byref Address As Word)as Word
    Value_low = Read_eeprom(eeprom1 , Address)
    Incr Address
    Value_high = Read_eeprom(eeprom1 , Address)
    Read_eeprom_word = Value
    End Function
    
    '-------------------------------------------------------------------------------
    '- Byte (wert) auf EEprom Adresse (address) speichern
    
    Sub Write_eeprom(byval Dev As Byte , Byref Address As Word , Byval Wert As Byte)
    
    I2cstart
    I2cwbyte Dev
    I2cwbyte Address_high
    I2cwbyte Address_low
    I2cwbyte Wert
    I2cstop
    Waitms 10
    
    End Sub
    '--------------------------------------------------------
    '- Byte von EEprom Adresse (address) lesen
    '- Der gelesene Wert ist der Rückgabewert der Funktion
    
    Function Read_eeprom(byval Dev As Byte , Byref Address As Word)
    Dim Devread As Byte
    Devread = Dev + 1
    
    I2cstart
    I2cwbyte Dev
    I2cwbyte Address_high
    I2cwbyte Address_low
    I2cstop
    I2cstart
    I2cwbyte Devread
    I2crbyte Read_eeprom , Nack
    I2cstop
    
    End Function
    '------------------------------------------------------------------------------
    Viele Grüße
    Henrik

  7. #17
    Erfahrener Benutzer Roboter Experte Avatar von Rage_Empire
    Registriert seit
    10.03.2005
    Ort
    Pforzheim
    Beiträge
    710
    hrei: Schöner Source. Ja, deine Variante ist eleganter, das geb ich zu. Hab das mit dem Wait wieder zugefügt, jedoch nur 1ms.
    Dank euch, ich habs geblickt! \/

  8. #18
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185
    @hrei und @Rage_Empire
    Ihr redet aneinander vorbei:
    Der Waitbefehl wird nur für Write benötigt, ist also im Unterprogramm 'Routine zum lesen von Daten aus dem EEPROM' unnötig.

    Dim Address_low As Byte 'Address ist hier überlappend
    Dim Address_high As Byte 'dimensioniert, um High- und Low-
    Dim Address As Word At Address_low Overlay 'Byte einfach ansprechen zu können.
    Da hoffst Du drauf, dass der Compiler auch zukünftig die Variablen im RAM nicht optimiert
    Ich gehe immer diesen sicheren Weg (erzeugt die gleiche Codelänge):
    Code:
    Dim Address As Word 
    Dim Adress_Raw(2) As Byte at Address Overlay
    Address_low Alias Adress_Raw(1)
    Address_high Alias Adress_Raw(2)
    damit kann man auch wunderbar Long etc. in ein EEPROM schreiben/lesen:

    Dim Address As Long
    Dim Adress_Raw(4) As Byte at Address Overlay

    jetzt beim schreiben der Adresse auf die Blockgröße bei PageWrite achten. Hier die Variante zum lesen von LONG.
    Code:
    Devread = Dev + 1 
    I2cstart 
    I2cwbyte Dev 
    I2cwbyte Address_high 
    I2cwbyte Address_low 
    I2cstop 
    I2cstart 
    I2cwbyte Devread 
    I2crbyte Adress_Raw(1) , Ack 
    I2crbyte Adress_Raw(2) , Ack 
    I2crbyte Adress_Raw(3) , Ack 
    I2crbyte Adress_Raw(4) , Nack 
    I2cstop
    Das ganze lässt sich dann mit For/Next noch schön machen, wobei Bascom-typisch der Code dann anwachsen könnte

  9. #19
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    27.02.2006
    Beiträge
    221
    Leider hatte ich nicht viel Glück mit der Umsetzung der hier vorgeschlagenen Sources.
    Beim source von hrei bekome ich mit dem print-Befehl nach Auslesen der values (Temp_W) für alle adressen den Wert 44975 zurück.
    Während mein 16*2 Display ziemlich verrückt spielt:
    "EEPROM" und "Schreibe" beleiben permanent auf dem Display stehen, die rechten Displayhälften verwandln sich in quasi japanische Schriftzeichen.
    Doch bei den "japanischen Schriftzeichen" ist eine interessante Beobachtung zu machen: beim Auslesen der values im Sekundentakt ändern sich die richtigen Stellen im Display (auf 5 Änderungen im rechten Feld ändert sich das linke Feld daneben usw.).

    Die "Lcd_i2c.lib" Datei wurde vom Compiler nicht gefunden, ist diese Datei von hrei erstellt? Ist sie nötig?

  10. #20
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.12.2004
    Alter
    71
    Beiträge
    277
    Zitat Zitat von xxrider

    Die "Lcd_i2c.lib" Datei wurde vom Compiler nicht gefunden, ist diese Datei von hrei erstellt? Ist sie nötig?
    Nein, die ist nicht von mir, sondern von Kent Anderson. Außerdem darf die natürlich nur dann eingebunden werden, wenn Du auch ein I2C-LCD verwendest! Ansonsten auskommentieren und statt dessen Deine LCD Config dort einbinden. Ich schreibe oben nicht umsonst:

    (die Kopfdeklarationen bitte einfach überlesen, die sind nur für meinen Experimenter interessant):

    Siehe Dir doch bitte einfach die Funktionen und Subs an und binde sie in Dein Programm ein. Zeige uns das Resultat Deiner Bemühungen.

    Wenn Du dann nur noch Murks empfängst, hast Du ein I2C-Bustiming Problem (eher unwahrscheinlich).

    Henrik

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests