PDA

View Full Version : External EEPROM Not getting data (24LC515)



Tom Gonser
- 20th March 2005, 15:01
Hi folks:
I need some help getting an EEPROM to respond and hold data..

I have a test program that ONLY tries to write 100 then read values to an external 24LC515 EEPROM part. I have scoured the boards and the MCP docs, but have been unable to get this simple little program to work. The example programs use var byte, and this chip needs var word, so that has been made. Here is the program - any ideas why it spits out '0' for all the stored values instead of a count from 1-100 ???


' I2CREAD and I2WRITE Commands - Two 24LC515 chips
'
' Write to the first 100 locations of an external serial EEPROM - 24LC515
' Read first 100 locations back and send to serial out repeatedly
' Note: using WORD as variable

' EEPROM PIN EEPROM PIN NAME PIC PIN MISC
' EEPROM.1 A0 Gnd/VCC depending on chip
' EEPROM.2 A1 Gnd/VCC depending on chip
' EEPROM.3 A2 Vcc
' EEPROM.4 Vss Gnd
' EEPROM.5 SDA SDA 1K resistor RA0 DPIN - data
' EEPROM.6 SCL SCL RA1 CPIN - clock
' EEPROM.7 WP Gnd
' EEPROM.8 Vcc Vcc

' Chip1 = AO is low, A1 is low
' Chip2 = AO is high, A1 is low
' 24LC515 address is '1010'
' address '1010', '0', chip select bits, read/write bits

Include "modedefs.bas" ' Include serial modes

SO var PortB.4 ' out to GPS
BD con 16572 ' 4800b driven inverted none (eliminate need for max232)

' **************************EEPROM ****************************************
DPIN var PortA.0 ' I2C data
CPIN var PortA.1 ' I2C clock
address var word
value var word
Chip1 con %10100000 ' address of chip1
Chip2 con %10100100 ' address of chip2
B0 var word
B1 var byte
B2 var byte


' write stuff into memory

For Address = 0 To 100
I2CWRITE DPIN,CPIN,Chip1,Address,[Address] ' Write each location's address to itself
Pause 10 ' Delay 10ms after each write
Next Address

For Address = 100 To 0 step -1
I2CWRITE DPIN,CPIN,Chip2,Address,[Address] ' Write each location's address to itself
Pause 10 ' Delay 10ms after each write
Next Address

loop:
' Chip 1 output
Serout2 SO,BD,["Chip 1",10,13] ' Name
For Address = 0 To 100 step 2
I2CREAD DPIN,CPIN,chip1,Address,[B1,B2] ' Read 2 locations in a row
Serout2 SO,BD,["Address: ", #address," B1: ", #B1," B2: ",#B2,10,13] ' Print 2 locations
Next Address
Serout2 SO,BD,[10,13,10,13,10,13] ' Spaces
' Chip 2 output
Serout2 SO,BD,["Chip 2",10,13] ' Name
For Address = 0 To 100 step 2
I2CREAD DPIN,CPIN,chip1,Address,[B1,B2] ' Read 2 locations in a row
Serout2 SO,BD,["Address: ", #address," B1: ", #B1," B2: ",#B2,10,13] ' Print 2 locations
Next Address
Serout2 SO,BD,[10,13,10,13,10,13] ' Spaces

Goto loop

Tom Gonser
- 21st March 2005, 00:09
I've tried everything to get it to work with the little program posted here, and have not been able to.

Based on the threads, I *think* I've got the connections and settings right, but it is not working. Then it occurred to me that PBP might not support it yet (?)

Things that are still a mystery are:

1. %10100000 is the device address, but is it required to set the last bit for read or write, or does the I2CREAD/WRITE commands handle that? IE, do I need to define two constants:

Chip1_w con %10100001 ' address of chip1 for writing
Chip1_R con %10100000 ' address of chip1 for reading

2. Do I ALWAYS have to write 64 bytes at a time?

3. What if I only want to store 1 byte value, am I storing 1 byte and 63 empty ones? Seems like a waste of space.

4. If I have to store 64 at a time, do I need to increment a storage address by 64 each time?

5. I note all the example files use the address as var byte. With large memory like this this has to be a 'word', right?

6. I've seen LOTS of defines, etc. If running a standard 16F876/A, using a 4 mhz EX crystal, is there some special sauce that is needed?

7. The chips say they are 400kb - is there some setting for the clock on the 16F876/A that must be set ?

8. I have 4.7K resistors on SDA and SCL to +5 - I hear that is needed all the time(?) or is it a recommendation

9. Is it required with PBP to ALWAYS have RA1 - > SCL, and RA0 - > SDA ? Or can you use other pins also?

Thanks! I hope the answer is out there!
Tom

Dave
- 21st March 2005, 16:58
Tom, I am curently using this part in a project I have designed and it works great. One thing to remember though read the data sheet section on addressing as I had a problem similar to yours and it turned out to be the way they do block switching. Normally this would be done with the external address lines but this part is so big they broke it into 2 blocks. Also make sure all external address lines are tied to +5 or ground. These are the routines I wrote to use this part. I always store by page so as to avoid the accumulated write time associated with this part.

HTH
Dave Purola,
N8NTA

CNTRL_BYTE CON $A2 'CONTROL BYTE FOR I2C EEPROM MEMORY (A0 USED FOR CHIP SELECT)
'************************************************* ********************
RW_EEPROM: 'READ FROM or WRITE TO SERIAL EEPROM
'************************************************* ********************
IF BLOCK < 1023 THEN
IF READ_WRITE = 1 THEN 'WRITE 64 BYTE BLOCK TO EEPROM
IF BLOCK <> 0 THEN 'IF STARTING NEW PASS DON'T READ OLD LOCATION
READ_WRITE = 0 'SET FOR BLOCK READ
GOSUB READ_WRITE_BLK 'READ FROM SERIAL EEPROM NEXT AVAILABLE STORAGE BLOCK
READ_WRITE = 1 'SET FOR BLOCK WRITE
ENDIF
ADDRESS = BLOCK << 6 'CALCULATE 12C ADDRESS TO STORE DATA TO
CNTROL_BYTE = CNTRL_BYTE 'COPY CONTROL BYTE
CNTROL_BYTE.3 = ADDRESS.15 'SET 32K BLOCK BIT
I2CWRITE SDA,SCL,CNTROL_BYTE,ADDRESS,[STR STOR_DATA\64] 'SAVE DATA TO 12C
PAUSE 6 'ALLOW TIME FOR I2C WRITE ~5Ms.
BLOCK = BLOCK + 1 'INCREMENT FOR NEXT AVAILABLE BLOCK TO WRITE
BLOCK = BLOCK MIN 1023 'LIMIT TO 1K BLOCKS OF 64 BYTES
GOSUB READ_WRITE_BLK 'WRITE TO or READ FROM SERIAL EEPROM LAST STORAGE BLOCK
ELSE
ADDRESS = BLOCK << 6 'CALCULATE 12C ADDRESS TO STORE DATA TO
CNTROL_BYTE = CNTRL_BYTE 'COPY CONTROL BYTE
CNTROL_BYTE.3 = ADDRESS.15 'SET 32K BLOCK BIT
I2CREAD SDA,SCL,CNTROL_BYTE,ADDRESS,[STR STOR_DATA\64] 'LOAD IN ENTIRE BLOCK
ENDIF
ENDIF
RETURN

'************************************************* ********************
READ_WRITE_BLK: 'WRITE TO or READ FROM SERIAL EEPROM NEXT AVAILABLE STORAGE BLOCK
'************************************************* ********************
ADDRESS = 65534 'POINT TO LAST STORED DATA(WORD) ADDRESS
CNTROL_BYTE = CNTRL_BYTE 'COPY CONTROL BYTE
CNTROL_BYTE.3 = ADDRESS.15 'SET 32K BLOCK BIT
IF READ_WRITE = 1 THEN
I2CWRITE SDA,SCL,CNTROL_BYTE,ADDRESS,[BLOCK.LOWBYTE,BLOCK.HIGHBYTE] 'WRITE DATA POINTER TO 12C
PAUSE 6 'ALLOW TIME FOR I2C WRITE ~5Ms.
ELSE
I2CREAD SDA,SCL,CNTROL_BYTE,ADDRESS,[BLOCK.LOWBYTE,BLOCK.HIGHBYTE] 'READ DATA POINTER FROM 12C
ENDIF
RETURN

Tom Gonser
- 22nd March 2005, 13:16
Thanks for the info. Yes, I was getting messed up with the 'block select' bit - did not realize the 515 was actually 2 x 256, and you have to change this bit to address the rest of the memory.

Question: My data payload is only 36bytes. I have a page size of 64bytes.. How can I both use the [string] to write pages, and not waste space? Or is it possible?

Since my payload is 36bytes, if I write a byte at a time, that will take .36 seconds, which is too long. If I write the page, it is what 5ms?

Thanks,
TG