- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 4 von 4

Thema: Probleme mit 24C65

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706

    Probleme mit 24C65

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Liebe Experten,

    seit ein paar Tagen mache ich erste Experimente mit externen EEPROMs, und habe mir hierzu einen 24C65 gekauft.

    Um mit dieser neuen Materie vertraut zu werden, wollte ich als erstes einfach nur ein einziges Byte an einem bestimmten Speicherplatz ablegen, es anschließend wieder auslesen und auf einem LCD anzeigen.

    Mein Code hierfür sieht so aus:

    Code:
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.6 , Db5 = Portd.5 , Db6 = Portb.7 , Db7 = Portb.6 , E = Portd.7 , Rs = Portb.0
    Initlcd
    Cursor = Off
    Cls
    
    Config Sda = Portd.3
    Config Scl = Portd.2
    I2cinit
    
    Dim Z As Byte
    
    Do
    
    Cls
    Locate 1 , 1
    Lcd "Schreiben:"
    Waitms 500
    
    I2cstart
    I2cwbyte &B10100000                                         '24C65, A2-A0 = 0, Schreiben
    I2cwbyte &B00000000                                         'H-byte Speicheradresse
    I2cwbyte &B00000010                                         'L-Byte Speicheradresse
    I2cwbyte 5
    I2cstop
    
    Locate 1 , 1
    Lcd "Lesen:"
    Waitms 500
    
    I2cstart
    I2cwbyte &B10100000                                         '24C65, A2-A0 = 0, Schreiben
    I2cwbyte &B00000000                                         'H-byte Speicheradresse
    I2cwbyte &B00000010                                         'L-Byte Speicheradresse
    I2cstart
    I2cwbyte 10100001                                           '24C65, A2-A0 = 0, Lesen
    I2crbyte , Z , Nack
    I2cstop
    
    Cls
    Locate 1 , 1
    Lcd Z
    Wait 1
    
    Loop
    Allerdings läuft alles in extremster Zeitlupe ab - Zwischen den LCD-Meldungen "Lesen" und "Schreiben" vergehen Minuten (!), und für die ausgelesene Variable Z wird 255 angezeigt (obwohl der Wert "5" in den Speicher geschrieben werden soll).

    Die Taktfrequenz stimmt, ich habe versuchsweise mal eine LED-Blinksequenz mit 1Hz vor die Do-Loop-Schleife gesetzt, die läuft korrekt ab.

    Beim 24C65 habe ich die Adresseingänge A2-A0 auf GND gelegt, und die SDA-Leitung über 2k2 auf +5V. Interessanterweise sehe ich mit dem Oszi keinerlei "Traffic" auf den SDA- und SCL-Leitungen. Ich habe SDA und SCL auch schon mal auf andere Ports des Mega8 gelegt - genau das gleiche. Das DDR-Register des SCL-Ausganges habe ich auch versuchsweise mal auf 1 gesetzt (obwohl das ja mit "I2CINIT" schon erledigt sein sollte) - ebenfalls ohne Erfolg.

    Hat jemand irgendeine Idee, was ich falsch mache??

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    49
    Beiträge
    381
    Moin!

    Ich habe erfolgreich einen TWI EEprom so angesteuert:

    Code:
    $regfile = "m32def.dat"
    $crystal = 14745600
    $baud = 9600
    $hwstack = 228
    $swstack = 228
    $framesize = 128
    $lib "i2c_twi.lbx"                                                                                                                                    'TWI-Lib für Hardware I2C
    
    Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2                                      ' Pinbelegung "LCD-Port)"
    Config Lcd = 16 * 2
    '(----------------- LCD Display an Port c =>Conector SV9 ------------------------
    Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7                                      ' Pinbelegung "LCD-Port)"
    '                SV9          6                5               4              3              7              8           ' Pinbelegung SV9 Board
    Config Lcd = 20 * 4
    Cursor Off Noblink
    ')
    '------------------ DS1820 on pinA 0 (pull up)----------------------------------
    
    Config 1wire = Portd.4                                                                                                                                '
    
    Declare Sub Read1820
    Declare Sub Crcit
    Declare Sub Temperature
    
    Dim Bd(9) As Byte
    Dim I As Byte , Tmp As Byte
    Dim Crc As Byte
    Dim T As Integer , Temp As Single
    Dim V As Byte , A As Word
    '
    
    '----------------- Config TWI --------------------------------------------
    Config Twi = 400000                                                                                                                                   ' Init TWBR und TWSR
    ' TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !
    Twcr = &B00000100                                                                                                                                     ' nur TWEN setzen
    '----------------- Eeprom Anschlüße --------------------------------------------
    Config Sda = Portc.1                                                                                                                                  'SDA und SCL als Hardware-TWI definieren
    Config Scl = Portc.0
    Portb.2 = 1                                                                                                                                           'Pullups für Taster ein
    Portb.3 = 1
    Const E_prom_w = &HA0                                                                                                                                 'Epromadresse 160 (A1/2/3 auf GND) schreiben
    Const E_prom_r = &HA1                                                                                                                                 'Epromadresse 160+1 für schreiben der Daten
    
    'EEprom 24C32,24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte.
    'Weil grösserer Speicherbereich im EEprom vorhanden ist Darum muss man den Adressbereich in High und Low Adressbereich
    'trennen. (Zuerst High-Adressbereich schreiben und dann Low-Adressbereich)
    Dim E_ah As Byte                                                                                                                                      'höherwertiges Byte der SpeicherAdresse (Adresse=Word)
    Dim E_al As Byte                                                                                                                                      'niederwertiges Byte der SpeicherAdresse (Adresse=Word)
    Dim E_addr As Word                                                                                                                                    'SpeicherAdresse EEprom
    Dim E_dat_r As Byte                                                                                                                                   'Daten der zu lesenen Daten aus EEprom
    Dim E_dat_w As Byte                                                                                                                                   'Daten der zu schreibenen Daten ins EEprom
    Dim Temperature As Single
    Dim Storetemp(4) As Byte At Temperature Overlay                                                                                                       'Maske: weise die 4Byte aus dem Single(Temperature) dem
                                                                                                'Storetemp(1-4) zu
    
    Declare Sub E_write(byval E_addr As Word , E_dat_w As Byte)                                                                                           'Sub zum schreiben in EEprom mit Übergabe einer Kopie der Variable (Eaddr/E_dat_w)
    Declare Sub E_read(byval E_addr As Word , E_dat_r As Byte)                                                                                            'Sub zum lesen aus EEprom
    Declare Sub 24lc256_test
    
    
    '------------------ Startbildschirm --------------------------------------------
    
    
    
    
    Cls                                                                                                                                                   'clear the LCD display
    Locate 1 , 1
    Lcd "Speicherung 1xTemp."                                                                                                                             'display this at the 1.line
    
    Locate 2 , 1                                                                                                                                          'display this at the 2. line
    Lcd " im EEprom 24c65  "
    
    Locate 3 , 1                                                                                                                                          'display this at the 3.line
    Lcd "Taster S7 speichern"
    
    Locate 2 , 1                                                                                                                                          'display this at the 4.line
    Lcd "Taster S8 auslesen"
    
    Wait 5
    Cls
    '------------------ Hauptprogramm ----------------------------------------------
    Do
     Temperature
    
     If Pinb.3 = 0 Then Call 24lc256_test
     If Pinb.2 = 0 Then
    
      Cls
      Locate 2 , 1
       Lcd Storetemp(1) ; " " ; Storetemp(2) ; " " ; Storetemp(3) ; " " ; Storetemp(4) ; "";                                                              'Anzeige der 4 einzelnen Bytes aus dem Overlay der Temperatur
      Locate 3 , 1
       Call E_read(&H10 , E_dat_r)                                                                                                                        'Aufruf der Subroutine zum lesen der einzelnen Bytes
       Call E_read(&H11 , E_dat_r)                                                                                                                        'E_read(&H10 , E_dat_r)
       Call E_read(&H12 , E_dat_r)                                                                                                                        '       &H10 - zu lesende Adresse aus EEprom
       Call E_read(&H13 , E_dat_r)                                                                                                                        '              E_dat_r - Daten aus dem Speicherort
       Lcd "Speicherwert= " ; Temperature ; ""                                                                                                            'Anzeige der Temperature zusammengesetzt aus dem Overlay: Storetemp(4)
      Locate 2 , 1 : Lcd "Read I2C error= " ; Err                                                                                                         'Err: Daten korrekt gesendet? 0=i.o.; 1=bad
     End If
    
    
    
    
    Loop
    
    End
    
    
    '////////////////// Subroutinen ////////////////////////////////////////////////
    Sub Temperature                                                                                                                                       ' actual measuring
    
       1wwrite &HCC : 1wwrite &H44                                                                                                                        ' start measure
       Waitms 300                                                                                                                                         ' wait for end of conversion
       Read1820
       Deflcdchar 0 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32                                                                                                   ' replace ? with number (0-7)                                                                                                             ' read 9 bytes
       Locate 1 , 1 : Lcd "Temp= "
                                            ' sensor present, check CRC
       Locate 1 , 7 : Lcd Fusing(temp , "#.##") ; Chr(0) ; "C"
    
    End Sub
    
    '//////////////////////////////////////////////////////////////////////////////
    Sub Read1820                                                                                                                                          ' reads sensor ans calculate
                                                       ' T for 0.1 C
       1wreset                                                                                                                                            ' reset the bus
       1wwrite &HCC                                                                                                                                       ' read internal RAM
       1wwrite &HBE                                                                                                                                       ' read 9 data bytest
       Bd(1) = 1wread(9)                                                                                                                                  ' read bytes in array
       1wreset                                                                                                                                            ' reset the bus
    
    
          T = Makeint(bd(1) , Bd(2))
          T = T / 2
          Temp = Bd(8) - Bd(7)
          Temp = Temp / Bd(8)
          Temp = T + Temp
          Temp = Temp - 0.25
    
    End Sub
    '///////////////////////////////////////////////////////////////////////////////'
    Sub 24lc256_test
    
    
          Temperature = Temp
          Call E_write(&H10 , Storetemp(1))                                                                                                               'Call I2C Routine zum schreiben und übergebe dabei die Adresse
          Call E_write(&H11 , Storetemp(2))                                                                                                               ' im EEprom und den Wert der zu speichern ist
          Call E_write(&H12 , Storetemp(3))
          Call E_write(&H13 , Storetemp(4))
    
    End Sub
    '///////////////////////////////////////////////////////////////////////////////
    ' Routine to write the 24C65
    
    Sub E_write(byval E_addr As Word , E_dat_w As Byte )
        E_ah = High(e_addr)                                                                                                                               'E_ah = EEprom high Adressbyte der jeweiligen Word-Adresse (H&10)
        E_al = Low(e_addr)                                                                                                                                'E_ah = EEprom low Adressbyte der jeweiligen Word-Adresse (H&10)
        I2cstart                                                                                                                                          'Start I2C
        I2cwbyte E_prom_w                                                                                                                                 'Sende Slave Adresse
        I2cwbyte E_ah                                                                                                                                     'Sende Speicheradresse High
        I2cwbyte E_al                                                                                                                                     'Sende Speicheradresse Low
        I2cwbyte E_dat_w                                                                                                                                  'Sende Daten Werte
        I2cstop                                                                                                                                           'Stop I2C
        Waitms 10
    End Sub
    
    '///////////////////////////////////////////////////////////////////////////////
    ' Routine to read the 24C65
    
    Sub E_read(byval E_addr As Word , E_dat_r As Byte)
        E_ah = High(e_addr)
        E_al = Low(e_addr)
        I2cstart
        I2cwbyte E_prom_w
        I2cwbyte E_ah
        I2cwbyte E_al
        I2cstart
        I2cwbyte E_prom_r
        I2crbyte E_dat_r , Nack
        I2cstop                                                                                                                                           '
    End Sub
    probier es mal damit.
    Gruß MAT

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    55
    Beiträge
    1.258
    Hallo Sauerbruch,

    Beim 24C65 habe ich die Adresseingänge A2-A0 auf GND gelegt, und die SDA-Leitung über 2k2 auf +5V.
    Bei mir funktioniert I2C nur, wenn auch die SCL Leitung einen Pullup bekommt.

    Vermutlich stört auch das zusätzliche Komma:
    I2crbyte , Z , Nack

    Gruß, Michael

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Bei mir funktioniert I2C nur, wenn auch die SCL Leitung einen Pullup bekommt.
    Oh Mann - wie findet man denn sowas heraus?

    In allen mir bekannten Quellen ist immer nur der PullUp für SDA erwähnt...

    Aber das war die Lösung - jetzt bleibt das Programm schon mal nicht mehr in den I2C-Sequenzen hängen, ich sehe saubere Signale auf beiden Leitungen, und kann mich jetzt weiteren Feinheiten wie dem 2. Komma zuwenden

    Besten Dank für den Tipp!

    Daniel

Ähnliche Themen

  1. Adressierung i2c eeprom 24c65
    Von mat-sche im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 15
    Letzter Beitrag: 27.12.2007, 16:23
  2. i2c eeprom 24c65 am atmega betreiben mit bascom
    Von pebisoft im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 33
    Letzter Beitrag: 26.10.2004, 23:34
  3. eeprom 24c65
    Von pebisoft im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 18.10.2004, 21:07

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress