Shop OBEX P1 Docs P2 Docs Learn Events
Help reading/writing EEPROM — Parallax Forums

Help reading/writing EEPROM

ArchiverArchiver Posts: 46,084
edited 2003-02-24 10:37 in General Discussion
I need some help reading from and writing to the 24LC256. I've been
able to write to it (i think) using this program:

'

'I/O pins
'

sda CON 8
scl CON 9

'

'I2C Definitions
'


i2c_read CON 1
i2c_write CON 0
i2c_out VAR Byte
i2c_in VAR Byte
i2c_ack VAR Bit

'

'EEPROM
'


device CON %1010000
EEdata VAR Byte
EEaddress VAR word

'

'General Variables
'


x var byte
degC var byte
degF var byte
counter VAR Byte
'

'MAIN PROGRAM
'

loop:
freqout 0,20,3800
high 13
shiftout 15,14,lsbfirst,[noparse][[/noparse]238]
low 13
high 13
shiftout 15,14,lsbfirst,[noparse][[/noparse]170]
shiftin 15,14,lsbpre,[noparse][[/noparse]x]
low 13
degC=x/2
degF= degC * 9 / 5 + 32
pause 1000

FOR eeAddress = 0 TO 10
EEdata = degF
gosub ByteWrite
Debug "Wrote ", dec EEdata, " to memory location ", dec EEaddress,
cr, cr
pause 1000
debug "next", cr, cr
next
Debug "Finshed!!"
END
'

'subroutines
'


ByteWrite:
gosub I2C_START
for counter = 0 to 2
lookup counter, [noparse][[/noparse] (device<<1 | i2c_write), EEaddress.highbyte,
EEaddress.lowbyte], i2c_out
gosub I2C_TX
next
i2c_out = EEdata
gosub I2C_TX
gosub I2C_STOP
return


CurrentRead:
gosub I2C_START
i2c_out = device << 1 | i2c_read
gosub I2C_TX
gosub I2C_RX_NO_ACK
return


'

'sub-subroutines
'


I2C_TX:
shiftout sda, scl, 1, [noparse][[/noparse]i2c_out]
shiftin sda, scl, 0, [noparse][[/noparse]i2c_ack\1]
if i2c_ack = 0 then I2C_RETURN
return


I2C_RX:
shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
shiftout sda, scl, 1, [noparse][[/noparse]%0\1]
return

I2C_RX_NO_ACK:
shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
gosub I2C_STOP

I2C_RETURN:
return

I2C_START
high sda
high scl
low sda
low scl
return

I2C_STOP
low sda
high scl
high sda
pause 1
return

I think that it writes, as I have a debug statment reading back what
was just written, and it reads correctly.

the thing I need help most with is reading. I have no clue whatsoever
as to how to read this EEPROM. So any help you can give me for
reading EEPROM would be greatly appreciated.

I know from reading the list posts that everyone on this list is very
helpful to begining "stampers" like myself.

thanks in advance,
BGrobotics

Comments

  • ArchiverArchiver Posts: 46,084
    edited 2003-02-24 01:06
    I need some help reading from and writing to the 24LC256. I've been
    able to write to it (i think) using this program:

    '

    'I/O pins
    '

    sda CON 8
    scl CON 9

    '

    'I2C Definitions
    '


    i2c_read CON 1
    i2c_write CON 0
    i2c_out VAR Byte
    i2c_in VAR Byte
    i2c_ack VAR Bit

    '

    'EEPROM
    '


    device CON %1010000
    EEdata VAR Byte
    EEaddress VAR word

    '

    'General Variables
    '


    x var byte
    degC var byte
    degF var byte
    counter VAR Byte
    '

    'MAIN PROGRAM
    '

    loop:
    freqout 0,20,3800
    high 13
    shiftout 15,14,lsbfirst,[noparse][[/noparse]238]
    low 13
    high 13
    shiftout 15,14,lsbfirst,[noparse][[/noparse]170]
    shiftin 15,14,lsbpre,[noparse][[/noparse]x]
    low 13
    degC=x/2
    degF= degC * 9 / 5 + 32
    pause 1000

    FOR eeAddress = 0 TO 10
    EEdata = degF
    gosub ByteWrite
    Debug "Wrote ", dec EEdata, " to memory location ", dec EEaddress,
    cr, cr
    pause 1000
    debug "next", cr, cr
    next
    Debug "Finshed!!"
    END
    '

    'subroutines
    '


    ByteWrite:
    gosub I2C_START
    for counter = 0 to 2
    lookup counter, [noparse][[/noparse] (device<<1 | i2c_write), EEaddress.highbyte,
    EEaddress.lowbyte], i2c_out
    gosub I2C_TX
    next
    i2c_out = EEdata
    gosub I2C_TX
    gosub I2C_STOP
    return


    CurrentRead:
    gosub I2C_START
    i2c_out = device << 1 | i2c_read
    gosub I2C_TX
    gosub I2C_RX_NO_ACK
    return


    '

    'sub-subroutines
    '


    I2C_TX:
    shiftout sda, scl, 1, [noparse][[/noparse]i2c_out]
    shiftin sda, scl, 0, [noparse][[/noparse]i2c_ack\1]
    if i2c_ack = 0 then I2C_RETURN
    return


    I2C_RX:
    shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
    shiftout sda, scl, 1, [noparse][[/noparse]%0\1]
    return

    I2C_RX_NO_ACK:
    shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
    gosub I2C_STOP

    I2C_RETURN:
    return

    I2C_START
    high sda
    high scl
    low sda
    low scl
    return

    I2C_STOP
    low sda
    high scl
    high sda
    pause 1
    return

    I think that it writes, as I have a debug statment reading back what
    was just written, and it reads correctly.

    the thing I need help most with is reading. I have no clue whatsoever
    as to how to read this EEPROM. So any help you can give me for
    reading EEPROM would be greatly appreciated.

    I know from reading the list posts that everyone on this list is very
    helpful to begining "stampers" like myself.

    thanks in advance,
    BGrobotics
  • ArchiverArchiver Posts: 46,084
    edited 2003-02-24 01:10
    Are you doing a "dummy write" first when reading?
    These notes relate to the 24C02, but should be similar:
    http://www.lennard.net.nz/electronics/i2c.html#eepromexample


    > From: "bgrobotics <Air_force@w...>" <Air_force@w...>
    > Reply-To: basicstamps@yahoogroups.com
    > Date: Mon, 24 Feb 2003 01:06:21 -0000
    > To: basicstamps@yahoogroups.com
    > Subject: [noparse][[/noparse]basicstamps] Help reading/writing EEPROM
    >
    > I need some help reading from and writing to the 24LC256. I've been
    > able to write to it (i think) using this program:
    >
    > '
    >
    > 'I/O pins
    > '
    >
    > sda CON 8
    > scl CON 9
    >
    > '
    >
    > 'I2C Definitions
    > '
    >
    >
    > i2c_read CON 1
    > i2c_write CON 0
    > i2c_out VAR Byte
    > i2c_in VAR Byte
    > i2c_ack VAR Bit
    >
    > '
    >
    > 'EEPROM
    > '
    >
    >
    > device CON %1010000
    > EEdata VAR Byte
    > EEaddress VAR word
    >
    > '
    >
    > 'General Variables
    > '
    >
    >
    > x var byte
    > degC var byte
    > degF var byte
    > counter VAR Byte
    > '
    >
    > 'MAIN PROGRAM
    > '
    >
    > loop:
    > freqout 0,20,3800
    > high 13
    > shiftout 15,14,lsbfirst,[noparse][[/noparse]238]
    > low 13
    > high 13
    > shiftout 15,14,lsbfirst,[noparse][[/noparse]170]
    > shiftin 15,14,lsbpre,[noparse][[/noparse]x]
    > low 13
    > degC=x/2
    > degF= degC * 9 / 5 + 32
    > pause 1000
    >
    > FOR eeAddress = 0 TO 10
    > EEdata = degF
    > gosub ByteWrite
    > Debug "Wrote ", dec EEdata, " to memory location ", dec EEaddress,
    > cr, cr
    > pause 1000
    > debug "next", cr, cr
    > next
    > Debug "Finshed!!"
    > END
    > '
    >
    > 'subroutines
    > '
    >
    >
    > ByteWrite:
    > gosub I2C_START
    > for counter = 0 to 2
    > lookup counter, [noparse][[/noparse] (device<<1 | i2c_write), EEaddress.highbyte,
    > EEaddress.lowbyte], i2c_out
    > gosub I2C_TX
    > next
    > i2c_out = EEdata
    > gosub I2C_TX
    > gosub I2C_STOP
    > return
    >
    >
    > CurrentRead:
    > gosub I2C_START
    > i2c_out = device << 1 | i2c_read
    > gosub I2C_TX
    > gosub I2C_RX_NO_ACK
    > return
    >
    >
    > '
    >
    > 'sub-subroutines
    > '
    >
    >
    > I2C_TX:
    > shiftout sda, scl, 1, [noparse][[/noparse]i2c_out]
    > shiftin sda, scl, 0, [noparse][[/noparse]i2c_ack\1]
    > if i2c_ack = 0 then I2C_RETURN
    > return
    >
    >
    > I2C_RX:
    > shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
    > shiftout sda, scl, 1, [noparse][[/noparse]%0\1]
    > return
    >
    > I2C_RX_NO_ACK:
    > shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
    > gosub I2C_STOP
    >
    > I2C_RETURN:
    > return
    >
    > I2C_START
    > high sda
    > high scl
    > low sda
    > low scl
    > return
    >
    > I2C_STOP
    > low sda
    > high scl
    > high sda
    > pause 1
    > return
    >
    > I think that it writes, as I have a debug statment reading back what
    > was just written, and it reads correctly.
    >
    > the thing I need help most with is reading. I have no clue whatsoever
    > as to how to read this EEPROM. So any help you can give me for
    > reading EEPROM would be greatly appreciated.
    >
    > I know from reading the list posts that everyone on this list is very
    > helpful to begining "stampers" like myself.
    >
    > thanks in advance,
    > BGrobotics
    >
    >
    >
    > To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    > from the same email address that you subscribed. Text in the Subject and Body
    > of the message will be ignored.
    >
    >
    > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
    >
    >
    >
  • ArchiverArchiver Posts: 46,084
    edited 2003-02-24 10:37
    It took me a little while to figure out reads in I2C as well. Here's a
    pseudocode write and read (for easy reading)

    writes:
    starti2c
    write devicewriteaddress
    write memoryaddress
    write firstvalue
    write secondvalue
    write thirdvalue
    stopi2c

    reads:
    starti2c
    write devicewriteaddress (10100000)
    write memoryaddress
    starti2c <- Second start command, NO stop.
    write devicereadaddress (10100001)
    read firstvalue
    read secondvalue
    read thirdvalue
    stopi2c

    I2C device addresses are not just the address, their also the command to
    tell it you want to read or write. The LSB is the read (0) or write (1)
    command and the other 7 bits are the device address. The four highest bits
    are the device's base address. For the 24LC256 the base address is 1010. The
    next three bits are A2, A1 and A0, then you tack on a zero or 1 for write or
    read.

    A0, A1 and A2 set the 2nd, 3rd, and fourth LSBs of the address like this:

    1 0 1 0 A2 A1 A0 R/W

    So if you left all three grounded the write address would be

    10100000

    If you pulled A1 high, write would be
    10100100

    and read would be

    10100101

    To do a read you first have to do a write, send the eeprom memory address
    you want to read, issue another start conversation command, send the read
    command, then finally read from the eeprom.

    You'll notice there are two starts without a stop in the read routine. The
    second start is required to sort of reset the chip so it'll listen to the
    new read address. Do NOT issue a stopi2c before the second start this point.
    Once you send a stop, you give up control of the I2C bus and another I2C
    device could take control between the two commands. Obviously not a danger
    if its just the stamp and eeprom but its the standard way to talk I2C.


    Different I2C devices have different base addresses. For the DS1307 real
    time clock its D (1101) so its write address is 11010000 and read would be
    11010001.

    Hope that helps.



    My 'lectronic Newb site http://members.shaw.ca/pmeloy/
    Original Message
    From: <Air_force@w...>
    To: <basicstamps@yahoogroups.com>
    Sent: Sunday, February 23, 2003 5:06 PM
    Subject: [noparse][[/noparse]basicstamps] Help reading/writing EEPROM


    > I need some help reading from and writing to the 24LC256. I've been
    > able to write to it (i think) using this program:
    >
    > '
    >
    > 'I/O pins
    > '
    >
    > sda CON 8
    > scl CON 9
    >
    > '
    >
    > 'I2C Definitions
    > '
    >
    >
    > i2c_read CON 1
    > i2c_write CON 0
    > i2c_out VAR Byte
    > i2c_in VAR Byte
    > i2c_ack VAR Bit
    >
    > '
    >
    > 'EEPROM
    > '
    >
    >
    > device CON %1010000
    > EEdata VAR Byte
    > EEaddress VAR word
    >
    > '
    >
    > 'General Variables
    > '
    >
    >
    > x var byte
    > degC var byte
    > degF var byte
    > counter VAR Byte
    > '
    >
    > 'MAIN PROGRAM
    > '
    >
    > loop:
    > freqout 0,20,3800
    > high 13
    > shiftout 15,14,lsbfirst,[noparse][[/noparse]238]
    > low 13
    > high 13
    > shiftout 15,14,lsbfirst,[noparse][[/noparse]170]
    > shiftin 15,14,lsbpre,[noparse][[/noparse]x]
    > low 13
    > degC=x/2
    > degF= degC * 9 / 5 + 32
    > pause 1000
    >
    > FOR eeAddress = 0 TO 10
    > EEdata = degF
    > gosub ByteWrite
    > Debug "Wrote ", dec EEdata, " to memory location ", dec EEaddress,
    > cr, cr
    > pause 1000
    > debug "next", cr, cr
    > next
    > Debug "Finshed!!"
    > END
    > '
    >
    > 'subroutines
    > '
    >
    >
    > ByteWrite:
    > gosub I2C_START
    > for counter = 0 to 2
    > lookup counter, [noparse][[/noparse] (device<<1 | i2c_write), EEaddress.highbyte,
    > EEaddress.lowbyte], i2c_out
    > gosub I2C_TX
    > next
    > i2c_out = EEdata
    > gosub I2C_TX
    > gosub I2C_STOP
    > return
    >
    >
    > CurrentRead:
    > gosub I2C_START
    > i2c_out = device << 1 | i2c_read
    > gosub I2C_TX
    > gosub I2C_RX_NO_ACK
    > return
    >
    >
    > '
    >
    > 'sub-subroutines
    > '
    >
    >
    > I2C_TX:
    > shiftout sda, scl, 1, [noparse][[/noparse]i2c_out]
    > shiftin sda, scl, 0, [noparse][[/noparse]i2c_ack\1]
    > if i2c_ack = 0 then I2C_RETURN
    > return
    >
    >
    > I2C_RX:
    > shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
    > shiftout sda, scl, 1, [noparse][[/noparse]%0\1]
    > return
    >
    > I2C_RX_NO_ACK:
    > shiftin sda, scl, 0, [noparse][[/noparse]i2c_in]
    > gosub I2C_STOP
    >
    > I2C_RETURN:
    > return
    >
    > I2C_START
    > high sda
    > high scl
    > low sda
    > low scl
    > return
    >
    > I2C_STOP
    > low sda
    > high scl
    > high sda
    > pause 1
    > return
    >
    > I think that it writes, as I have a debug statment reading back what
    > was just written, and it reads correctly.
    >
    > the thing I need help most with is reading. I have no clue whatsoever
    > as to how to read this EEPROM. So any help you can give me for
    > reading EEPROM would be greatly appreciated.
    >
    > I know from reading the list posts that everyone on this list is very
    > helpful to begining "stampers" like myself.
    >
    > thanks in advance,
    > BGrobotics
    >
    >
    >
    > To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    > from the same email address that you subscribed. Text in the Subject and
    Body of the message will be ignored.
    >
    >
    > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
    >
    >
Sign In or Register to comment.