External EEPROM can't read/write


Closed Thread
Results 1 to 17 of 17
  1. #1
    Join Date
    Oct 2005
    Location
    Las Vegas, Nevada, USA
    Posts
    27

    Default External EEPROM can't read/write

    I am using a 16F877 with a 24LC256 in an effort to display a logo on a graphic LCD. The following code should write the logo to the 24LC256 and read 10 of the written addresses from the 24LC256. However, the read retrieves FFH for each address.

    The 24LC256 has pins 1, 2, 3, 4, and 7 at gnd. Pin 8 is 5V. Pin 5 to PORTC.4 with a 4.7k pull-up to 5V. Pin 6 to PORTC.3 with a 4.7k pull-up to 5V. I've tried multiple 24LC256's and other resistor values to no avail.

    Any suggestions? Thank you.

    Code:
    @ DEVICE HS_OSC, WDT_OFF, LVP_OFF, BOD_OFF, PWRT_ON, PROTECT_OFF
    
    DEFINE	LOADER_USED	1
    DEFINE    OSC 20
    
    ADCON1 = 7
    
    sda   var   PORTC.4     'I2C SDA for ext eeprom
    scl    var   PORTC.3     'I2C SCL  for ext eeprom 
    ctl    con  160	     'EEPROM control code	
    addr  var  WORD         'eeprom word address
    i       var   byte           'Index counter
    
    edata     var    BYTE        'Data byte to be written and read
    out_pin	var    PORTC.6   'TX pin of 16F877
    ser_baud  con  32            '19200
    
    addr   = 0
    edata  = 0
    pause 100
    serout2 out_pin,ser_baud,["Writing to EEPROM . . .",10,13]
    for i = 0 to 249	  
    lookup i,[_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$3F,$C0,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$0F,$FA,$60,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$7C,$04,$38,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$D2,$60,$C8,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$01,$D0,$22,$1C,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$03,$A2,$80,$0C,$00,$00,$00],edata
    I2CWRITE sda,scl,ctl,addr.highbyte,addr.lowbyte,[edata]
    pause 10
    addr = addr + 1
    next
    
    . . .
    
    for i = 0 to 249	  
    lookup i,[_
    $00,$00,$00,$01,$FE,$1F,$9F,$E0,$7C,$07,_
    $FE,$3C,$1F,$03,$80,$3F,$C0,$3C,$E0,$00,_
    $7F,$DF,$FC,$14,$97,$1D,$FD,$77,$00,$1C,_
    $00,$00,$00,$03,$0F,$03,$E1,$F0,$FC,$0E,_
    $1E,$38,$0E,$03,$80,$61,$E0,$FD,$E0,$00,_
    $77,$CD,$FC,$80,$95,$8D,$EF,$7B,$80,$1C,_
    $00,$00,$00,$00,$07,$01,$C0,$F0,$1C,$1C,_
    $04,$38,$0E,$03,$80,$00,$E0,$1E,$00,$00,_
    $7F,$DF,$6E,$2E,$BC,$CE,$FF,$BE,$80,$1C,_
    $00,$00,$00,$00,$07,$01,$C0,$70,$1C,$18,_
    $00,$38,$0E,$03,$80,$00,$E0,$1C,$00,$00,_
    $7D,$4F,$FF,$81,$37,$3B,$FB,$F8,$80,$1C,_
    $00,$00,$00,$00,$07,$01,$C0,$70,$1C,$38,_
    $00,$38,$0E,$03,$80,$00,$E0,$1C,$00,$00,_
    $5F,$E5,$BB,$CA,$2F,$FE,$FF,$F4,$80,$1E,_
    $00,$00,$00,$00,$3F,$01,$C0,$70,$1C,$38,_
    $00,$38,$0E,$03,$80,$07,$E0,$1C,$00,$00,_
    $6F,$AF,$FF,$C1,$7E,$FE,$BF,$C7,$00,$0E,_
    $00,$00,$00,$01,$E7,$01,$C0,$70,$1C,$38,_
    $00,$38,$0E,$03,$80,$3C,$E0,$1C,$00,$00,_
    $3D,$E3,$F7,$E0,$6B,$57,$F7,$C3,$00,$0F,_
    $00,$00,$00,$43,$07,$01,$C0,$70,$1C,$38,_
    $00,$38,$0E,$03,$80,$60,$E0,$1C,$00,$00,_
    $2F,$EA,$DD,$FE,$D9,$BF,$BD,$F3,$00,$07,_       '1231 to 1240
    $80,$00,$01,$CE,$07,$01,$C0,$70,$1C,$3C],edata
    I2CWRITE sda,scl,ctl,addr.highbyte,addr.lowbyte,[edata]
    pause 10
    addr = addr + 1
    if addr > 1230 and addr < 1241 then
         serout2 out_pin,ser_baud,[dec addr,44,32,hex2 edata,72,10,13]
    endif
    next
    
    . . .
    
    for i = 0 to 169	  
    lookup i,[_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$03,$C0,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
    $00,$00,$00,$00,$00,$00,$00,$00,$00,$00],edata
    I2CWRITE sda,scl,ctl,addr.highbyte,addr.lowbyte,[edata]
    pause 10
    addr = addr + 1
    next
    serout2 out_pin,ser_baud,["Reading EEPROM . . .",10,13]
    for addr = 1231 to 1240
         i2cread sda,scl,ctl,addr.highbyte,addr.lowbyte,[edata]
         serout2 out_pin,ser_baud,[dec addr,44,32,hex2 edata,72,10,13]
    next
    serout2 out_pin,ser_baud,["Finished",10,13]
    end

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    First thoughts... Get rid of the fat...
    Break it down...Make it as simple as possible.
    Read and write a single value to a single location, then build your way up to the final result.
    Then try this:
    Code:
    eepromaddress var word
    eepromdata var byte
    i2cd var portc.0
    i2cc var portc.1
    eepromctrl var byte
    eepromctrl = $a0
    i2cread i2cd , i2cc , eepromctrl , eepromaddress , [ eepromdata ]
    i2cwrite i2cd , i2cc , $a0 , eepromaddress , [ eepromdata ]
    Notice anything different?


    (besides the fact that there isn't a single colon up there )
    (I could've done this
    Code:
    a var word:d var byte:c var portc.0:k var portc.1:n var byte:n=160:i2cread c,k,n,a,[d]:i2cwrite c,k,n,a,[d]
    Last edited by skimask; - 8th May 2008 at 05:53.

  3. #3
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by coyotegd View Post
    I am using a 16F877 with a 24LC256 in an effort to display a logo on a graphic LCD. The following code should write the logo to the 24LC256 and read 10 of the written addresses from the 24LC256. However, the read retrieves FFH for each address.
    addr = 0
    write 0+(0..249)
    write 249+(0..249)
    write 498+(0..169)

    read 1231 ????

    You seem to write somewhere and read elsewhere. No wonder it reads FF

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Jerson View Post
    You seem to write somewhere and read elsewhere. No wonder it reads FF
    Which is why I said to 'break it down'.
    You know why it doesn't work, I know why it doesn't work...
    Hopefully, now the O/P knows why it doesn't work...

  5. #5
    Join Date
    Oct 2005
    Location
    Las Vegas, Nevada, USA
    Posts
    27


    Did you find this post helpful? Yes | No

    Default Huh, you don't know what ". . ." means?

    I don't mean to be rude but the ". . ." means that I omitted code from the post or did you want three pages of the same thing over and over?

    I also have no idea what colons have to do with anything.
    Last edited by coyotegd; - 8th May 2008 at 08:19.

  6. #6
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by coyotegd View Post
    I don't mean to be rude but the ". . ." means that I omitted code from the post or did you want three pages of the same thing over and over?
    But have you tried the above suggestions at all?

    I also have no idea what colons have to do with anything.
    That's sort of a semi-inside-joke. Don't worry about it. (I have a tendency to write code with a load of colons in it to make more of it fit on each screen)

  7. #7
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Instead of using addr.highbyte,addr.lowbyte in your I2CREAD / I2CWRITE lines, try using
    just addr. PBP already knows addr is a word and will handle both high & low bytes of the
    address for you.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  8. #8
    Join Date
    Oct 2005
    Location
    Las Vegas, Nevada, USA
    Posts
    27


    Did you find this post helpful? Yes | No

    Default Simple example; still doesn't work

    I wrote a very simple program but with the same output result:

    5, 57
    5, 255

    Code:
    DEFINE	LOADER_USED	1
    DEFINE    OSC 20
    
    edata     var	  BYTE
    
    pause 100
    i2cwrite portc.4,portc.3,160,5,[57]
    pause 10
    serout2 portc.6,32,[dec 5,44,32,dec 57,10,13]
    i2cread portc.4,portc.3,160,5,[edata]
    serout2 portc.6,32,[dec 5,44,32,dec edata,10,13]
    end
    I tried using portc.0 as SDA and portc.1 at SCL with the same result. I used a different 16F877. It just doesn't make any sense to me anymore. I've checked the datasheets and my circuit many, many times.
    Last edited by coyotegd; - 8th May 2008 at 17:56.

  9. #9
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Have you tried scoping the SCL and SDA lines to see if it is really communicating? I2C is a no-brainer - if you get it working the first time.

    The address should be declared in a WORD sized variable for the 24LC256. You then use this variable to hold the addresses for access.

    Code:
    Address  var  Word             ' this will hold the 16 bit word address
    EData     var  Byte             '  Eprom data byte for read/write
    
    Address = 5                      ' address to access
    Edata    = $55                   ' data to write
    I2Cwrite SCL,SDA,$A0, Address, [EData]   ' write it
    Edata = 0               ' destroy the value before read
    I2Cread SCL,SDA,$A0, Address , [EData]   ' read it back
    if Edata = $55 then Success                   ' if it compares, You Succeeded

  10. #10
    Join Date
    Oct 2005
    Location
    Las Vegas, Nevada, USA
    Posts
    27


    Did you find this post helpful? Yes | No

    Default Exactly, a no brainer

    It's the fact that this should be a "no brainer" that is so baffling. I've breadboarded much more complicated circuits, yet this simple EEPROM circuit won't work. I thought perhaps someone else had encountered this type of problem before and knew of a solution or could identify a source for troubleshooting.

    A digital probe pulses away on both SCL and SDA during read/write ops.

    BTW, I scoped portc.4 and c.3 outputs and SDA and SCL appear to be working. See Scope.jpg with data on top and clock on bottom. Both high prior to write/read operation and data high, clock low after write/read op. However, after a couple minutes, the clock goes high. I have no idea why.

    The write-data signal doesn't change thoughout the write process and it's the same for the read-data signal, but the read signal is not the same as the write signal. See Scope2.jpg.
    Attached Images Attached Images   
    Last edited by coyotegd; - 11th May 2008 at 21:50.

  11. #11
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Those waveforms look pretty bad.

    For sure you need a lower pull-up resistance. 2KΩ is recommended for 400khz operation.
    <br>
    DT

  12. #12
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Must have something to do with the multiplexed peripherals on RC3/4. I couldn't identify what could be the cause, but you could try to load the TRISC register yourself and define I2C_INTERNAL in case you want to use the internal I2C engine. There is something about the SSPSTAT reg too. Maybe you should look at those. I cannot comment since I havent used the 877 yet.

  13. #13
    Join Date
    Oct 2005
    Location
    Las Vegas, Nevada, USA
    Posts
    27


    Did you find this post helpful? Yes | No

    Default I'll try setting the registers

    Darrel, I've tried 1k, 2k, 4.7k and 10k. I get a more well-defined square-wave with a 1 or 2k, but I still have the same result. I don't think the 24LC256 is being written to or read.

    Jerson, I've looked at the 16F877 datasheet and found the first six bits of the SSPCON register and the first seven bits of the SSPCON2 register. Also, the requirement to set C.3 and C.4 as inputs with TRISC.

    A lot of pages of the datasheet are devoted to I2C. Although PIC Basic Pro makes I2C a "no brainer", the data sheet suggests using assembler isn't so easy. I only have a small amount of assembler experience with an 8051.

    I'll try configuring registers with PBP, but once I use the I2CWRITE and READ commands, won't PBP do it's own configuration, changing prior configurations?

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Question

    Don't bother playing with the SSP registers.
    PBP's I2C commands are "bit-banged", and they do not use the Hardware I2C (SSP module).

    I2C_INTERNAL is only for a small group of Very OLD pic's that have Internal I2C memory. It doesn't apply to PBP's I2CWRITE/READ commands.

    coyotegd,

    You still haven't responded to the previous suggestions regarding the Word sized Address.
    Can't go any further without that result.
    <br>
    DT

  15. #15
    Join Date
    Oct 2005
    Location
    Las Vegas, Nevada, USA
    Posts
    27


    Did you find this post helpful? Yes | No

    Default Word Size Address

    Darrel, I started this mess with a word sized address without highbyte, lowbyte. I found in another thread that the high-low byte addressing worked for someone, and when it didn't work for me, I made my first post in this tread with my code at the time.

    However, I changed the 16F877 a third time and it's working! Is it possible that some PICs just don't work with I2C? Prior to finding a working 16F877, I tried two other 16F877's and a 16F876A. All failed to work properly.

    Is it possible I had the circuit wrong? I can't go back and try a PIC that failed because they are all in their respective parts' bins with others of the same type. The most complicated part of my circuit is the MAX233, and it worked properly the first time. The 24LC256 is simple: Pins 1 to 4, and 7 to gnd, pin 8 to 5V, pin 5 pulled-up and to c.4, and pin 6 pulled-up and to c.3.

    Anyway, thank you all. You kept me motivated to keep trying. All I can say to anyone reading this tread with a similar problem is just keep trying different components, and periodically, start your breadboarding all over again. As stated above I tried four different PICs, and I re-wired my circuit at least four times. This is the code that works:

    Code:
    @ DEVICE HS_OSC, WDT_OFF, LVP_OFF, BOD_OFF, PWRT_OFF, PROTECT_OFF
    
    DEFINE	LOADER_USED	1
    DEFINE    OSC 20
    addr      var       word
    edata     var       BYTE
    addr = 0
    edata = 50
    pause 100
    for addr = 5 to 10
         I2CWRITE portc.4,portc.3,$A0,addr,[edata],Nowriteack
         pause 10
         serout2 portc.6,32,[dec addr,44,32,dec edata,10,13]
         edata = edata + 10
    next
    for addr = 5 to 10
         i2cread portc.4,portc.3,$A0,addr,[edata],NoREADAck
         serout2 portc.6,32,[dec addr,44,32,dec edata,10,13]
    next
    end
    NoWriteAck:
    serout2 portc.6,32,["No Write Acknowledgement",10,13]
    return
    NoReadAck:
    serout2 portc.6,32,["No Read Acknowledgement",10,13]
    return
    I've attached a picture, which was the objective of this exercise. It's rough, but at least I can move on to improvements and new challenges.
    Attached Images Attached Images  
    Last edited by coyotegd; - 13th May 2008 at 05:10. Reason: Add picture

  16. #16
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by coyotegd View Post
    ... I tried two other 16F877's and a 16F876A. All failed to work properly. ...
    I can't go back and try a PIC that failed because they are all in their respective parts' bins with others of the same type.
    Is it possible that some PICs just don't work with I2C?
    I doubt that very strongly.

    But, I would imagine that putting parts that have had problems back in the bin with the new chips, would enhance the probability considerably.

    Anyhow, glad it's working.

    Cheers,

    Added: Woohoo! Nice picture.
    Last edited by Darrel Taylor; - 13th May 2008 at 05:20. Reason: WooHoo.
    DT

  17. #17


    Did you find this post helpful? Yes | No

    Default

    In the past I've had a lot of sporadic problems with i2c and breadboards as well...I suspect your problem was solved somehow when rewiring the breadboard... My problems always went away when soldering my prototypes... Hope this helps...

Similar Threads

  1. Can't read sequential addresses in external EEPROM
    By tjkelly in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 18th February 2010, 14:46
  2. Replies: 1
    Last Post: - 28th January 2010, 22:15
  3. How to write/read strings EEPROM/LCD
    By g-hoot in forum mel PIC BASIC Pro
    Replies: 22
    Last Post: - 11th February 2007, 06:26
  4. Internal EEPROM Read/write Addressing Errors with 18F PIC's
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 18
    Last Post: - 12th July 2005, 19:42
  5. word variable to 25lc640
    By TONIGALEA in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 6th July 2004, 19:59

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts