24C512 eeprom unable to read/wite on I2C bus

Max
2010-10-16
2013-05-30
  • Max

    Max - 2010-10-16

    I want to write and read on 24C512 but I have write problem.

    I use this part of code is correct  ?

    ;Defines (Constants)
    #define EEPROM_WR 0xA0                 
    #define EEPROM_RD 0xA1
    #define I2C_MODE Master
    #define I2C_DATA PORTA.3
    #define I2C_CLOCK PORTA.2

    Sub rand_write
    I2CStart
    I2CSend EEPROM_WR
    I2CSend ee_addr_lasthigh
    I2CSend ee_addr_lastlow
    I2CStart
    I2CSend ee_dati
    I2CStop
    End Sub

    Sub rand_read
    I2CStart
    I2CSend EEPROM_WR
    I2CSend ee_addr_inihigh
    I2CSend ee_addr_inilow
    I2CStart
    I2CSend EEPROM_RD
    I2CReceive ee_dati
    End Sub

    Best regard Massimo

     
  • kent_twt4

    kent_twt4 - 2010-10-18

    To my way of thinking, delete the 2nd unnecessary I2CStart in the send routine.

    For the receive routine:  May need a I2CStop after 1st sending of eeprom  address(s) and before the next I2CStart.  At least that's the way I did it  Also need to resend the eeprom address(s) again after 2nd I2CStart and before sending the eeprom read command.  And last, missing I2CStop command at the end.  Using the code tags in the message box really helps for future inquiries.

    Look up the eeprom routines in the contributor's section here for the work flow.  Looks like I may have some extra pin manipulation going on, but that was almost four years ago :=).

     
  • Max

    Max - 2010-10-19

    I have resolved problem modifing the library I2C.h
    from
    Sub I2CReceive (Out I2CByte, In I2CGetAck = TRUE)
    to
    Sub I2CReceive (Out I2CByte, In I2CGetAck = FALSE)

    because last byte read must get  NACK an not ACK
    Now my SUB for WRITING or READING single byte at time work fine


    #define EEPROM_WR 0xA0                 
    #define EEPROM_RD 0xA1
    #define I2C_MODE Master
    #define I2C_DATA PORTA.3
    #define I2C_CLOCK PORTA.2

    Dim ee_addr_ini As word alias ee_addr_inihigh , ee_addr_inilow
    Dim ee_addr_last As word alias ee_addr_lasthigh , ee_addr_lastlow
    Dim ee_dati As byte

    Sub rand_write
    I2CStart
    I2CSend EEPROM_WR
    I2CSend ee_addr_lasthigh
    I2CSend ee_addr_lastlow
    I2CStart
    I2CSend ee_dati
    I2CStop
    End Sub

    Sub rand_read
    I2CStart
    I2CSend EEPROM_WR
    I2CSend ee_addr_inihigh
    I2CSend ee_addr_inilow
    I2CStart
    I2CSend EEPROM_RD
    I2CReceive ee_dati
            I2Cstop
    End Sub


    NOTE 0xA0 or 0xA1 is for pin A0 A1 A2 of 24C512 to ground  (addr 0)

     
  • Hugh Considine

    Hugh Considine - 2010-10-19

    There isn't a need to edit the library to change whether a NACK or ACK is needed. If a subroutine parameter has = and a value, that's called the default value. If you don't give GCBASIC a value to put in, it will use the default value. For example, this line:

    I2CReceive ee_dati

    does not give a value for I2CGetAck, so GCBASIC will use whatever the default value is. However, if you write this:

    I2CReceive ee_dati, FALSE

    then GCBASIC will see that you have given it a value to use for I2CGetAck, and will set it to FALSE (ie, there is a value given, so GCBASIC will ignore the default value and use whatever you give it.)

    I haven't done any experimentation with I2C EEPROM chips, so can't really offer much specific advice. However, from experience with other I2C devices, it is quite common to get a NACK rather than an ACK for the last byte. Also, I think Kent is right about the extra start condition in the write subroutine - the datasheet for the AT24C512 doesn't show a start condition in the middle of the write.

     
  • Hugh Considine

    Hugh Considine - 2010-10-19

    Sorry, my bad - looks like there isn't actually an easy way to change I2CGetAck in GCGB. Might have to rethink that.

    In the mean time, I think you should be able to trick GCGB by changing "ee_dati" to "ee_dati, FALSE" in the receive icon. When that is converted to GCBASIC code, it should come out correctly (as "I2CReceive ee_dati, FALSE", rather than "I2CReceive ee_dati".)

     
  • Nobody/Anonymous

    1) w_cholmondeley thank for your advice to use" I2CReceive ee_dati, FALSE" instead to modify the library.
    2) for the second I2Cstart in the middle of sub rand_write maybe  I made a mistake with cut/past .
    As sone as possible i will apply the changes and check the routines again .
    Best regard

     

Log in to post a comment.