PDA

View Full Version : Problems with driving external EEPROM M24256



Kristjan
- 31st January 2008, 01:11
Hi!

I'm using PIC18F2320 to drive EEPROM M24256. Here is the code to write variable to the address 1.

'--------------------------------
DEFINE OSC 4
Include "modedefs.bas"

CVRCON = 0 ' No reference
CMCON = 7 ' No comparator
TRISA = %00000000 ' Set PORTA pins into output
TRISB = %00000000 ' Set PORTB pins into output
TRISC = %00000000 ' Set PORTC pins into output

addr var word ' Address of EEPROM
val var byte ' Value of writable variable
val2 var byte ' Value of readable variable
DPIN var PORTC.4 ' Serial Data pin
CPIN var PORTC.5 ' Clock pin
cont var byte ' Control

Pause 1

val = 14 ' Starting value
val2 = 5 ' Starting value
addr = 1 ' Address

loop:

cont = %10100000 'Control is set to write

I2Cwrite DPIN, CPIN, cont, addr, [val] 'Writes value to EEPROM address 1
Pauseus 30

cont = %10100001 'Control is set to read

I2Cread DPIN, CPIN, cont, addr, [val2] ' Read EEPROM Contents
serout PORTC.6, N9600, [val2] ' Value to serial port

Goto loop ' Forever

The problem is that readed value "val2" is always zero. I think that, there is no writing into memory done. The "Control" format is based on datasheet of M24256. For reading I need to invert the first bit. In schematic all connections should be ok, as I've checked it many times. The clock and data pins aren't pulled up through resistors as PIC output isn't with open-collector. Could anybody tell, what I'm missing in code to write some variable into memory?

Jerson
- 31st January 2008, 01:15
I think you need to split the address in the I2c command as low and high byte for this to work.

JF

Kristjan
- 31st January 2008, 01:43
Tnx. for fast reply, Jerson! Were you were meaning to send lower and higher address byte separately to EEPROM for reading and writing?

Example:

I2Cwrite DPIN, CPIN, cont, addr.Byte0, [val] 'Writes value to EEPROM address 1
I2Cwrite DPIN, CPIN, cont, addr.Byte1, [val] 'Writes value to EEPROM address 1

In EEPROM datasheet it is described, that the address should be sent in two parts and then data byte. In PICBasic PRO Compiler book it is also written, that address is sent in bytes or words. It is determined by the size of the variable, that is used.

Jerson
- 31st January 2008, 03:35
This is what I use to address a 24C512 device



I2Cwrite SDA, SCL, $A0, Address.HighByte, Address.LowByte, _
[Date[0],Date[1],Date[2],Time[0],Time[1],Time[2],Key]


Hope this is what you're looking for

JF

mbruno
- 31st January 2008, 08:07
I had the same problem with the 24aa eeprom , I had to check the data sheet to find out what the address var should be either byte or word and the make sure the data line and the clock line have pull up resistors,

Good Luck
Mike
P.S. just checked the data sheet quickly and I think the address value should be byte and WC line should be held low during write or the ACK will not be sent..

Kristjan
- 31st January 2008, 11:02
This address splitting seems logical and I tried it, but unfortunately it didn't change the result. Anyways it remains in my code.

Also I was adding to data line pull up resistor as it was said in datasheet. Now the "val2" value is 16.

In datasheet it is said, that each data byte in the memory has a 16-bit address. The Most Significant Byte should be send first and then Least significant. As I understand the address must be word type variable.
I was checking the routing of reading process. This sequence is a bit different than in writing process.

Read sequence:
Start => Control => Address.HighByte => Address.HighByte => Start => Control => Data Out

Here the Control byte and Start condition has to be send twice. In writing it is without second Start and Control. I don't know how the I2C protocol is set. Perhaps for reading it should be also done something different.

Jerson
- 31st January 2008, 11:51
Hi!

I'm using PIC18F2320 to drive EEPROM M24256. Here is the code to write variable to the address 1.



'--------------------------------
DEFINE OSC 4
Include "modedefs.bas"

CVRCON = 0 ' No reference
CMCON = 7 ' No comparator
TRISA = %00000000 ' Set PORTA pins into output
TRISB = %00000000 ' Set PORTB pins into output
TRISC = %00000000 ' Set PORTC pins into output

addr var word ' Address of EEPROM
val var byte ' Value of writable variable
val2 var byte ' Value of readable variable
DPIN var PORTC.4 ' Serial Data pin
CPIN var PORTC.5 ' Clock pin
cont var byte ' Control

Pause 1

val = 14 ' Starting value
val2 = 5 ' Starting value
addr = 1 ' Address

loop:

cont = %10100000 'Control is set to write
You do not need to do this

I2Cwrite DPIN, CPIN, $A0, addr.highbyte,addr.lowbyte, [val] 'Writes value to EEPROM address 1
Pauseus 30

cont = %10100001 'Control is set to read
You do not need to do this

I2Cread DPIN, CPIN, $A0, addr.highbyte, addr.lowbyte, [val2] ' Read EEPROM Contents
serout PORTC.6, N9600, [val2] ' Value to serial port

Goto loop ' Forever




This should take care of your problem. You can try using your cont variable, butyou dont need to change the bit state for read / write. PBP takes care of that

JF

Kristjan
- 31st January 2008, 12:01
Just made the changes in code, as you said Jerson. Still no changes. I'll get today 24LC16B EEPROM. Perhaps this will start to work.

mbruno
- 31st January 2008, 12:26
I spent some time reading the data sheet and the addressvar is word, have you tried to use a for next loop
for address = 1 to 5
ic2write statment
next address
this seems to work for me to write and read memory locations on the 24aa65 chip, and i did not have to split the address into upper and lower bytes.

Hum, I will think on it some more to day, if I can find my program I will upload the code I used..I know it is some where on the computer ??

Mike

Jerson
- 31st January 2008, 14:07
Krisjan

I think you need to check the condition of the pins 1,2,3 and 7 of your eeprom. The pins 1,2 and 3 decide the bits in the control word(beware of this) allowing you to address multiple devices depending on the capacity of each device. Pin 7 has to be low for a write to occur. There seems to be no other explanation to this issue

JF

mbruno
- 1st February 2008, 07:52
Mr. Jerson is very right on , make sure that the address pins are ground and in fact I have all pins at ground execpt for the data and clock lines, exception is if there is more than one memory chip connected,
read section 5.34 and 5.35 in the PicBasic pro compiler book it has a very good discription of how these commands work... also read the data sheet. try to use an error rutine at the end of the i2c statment, it will let you know if the write or read is successfull..
good luck

Mike

example of some code

addres var word
w var byte
cont con %10100000

for addres = 1 to 255
i2cwrite portb.var,portb,var,cont,addres,[w], error
pause 150
next addres

for reading just put in the 12cwread for the write statment

error:
lcdout $fe,1, "error no ack received"
end

Kristjan
- 1st February 2008, 11:46
Hi Mike and Jerson!

Good news. It started to work finally :)
Not going straight into point, I must mention, that my EEPROM is M24256W. Address PINs are in EEPROM - M24256B! So there is kind of big difference, which doesn't seem so important at first place.
To conclude some things in my experiment (perhaps it would be helpful for somebody, who deals with same problem):
Check pin connections! (This time all connections were right)
Data pin must be pulled-up! (If you are using open collector, then also clock pin)
Pause after writing has to be at least 10ms. (Not 30us as I had it in my code ;) )

By the way. Everything else what was mentioned under this topic was right. This address splitting to higher and lower byte is working and also it is not necessary to set Control byte separately for reading and writing. Anyways, as it came out now, it is also working without splitting and you can set also Control byte separately for reading and writing. It works!

And now the main point. I went through again PIC Basic handbook, after hours of experimenting with different cases and connections. I even changed ports for data and clock in my PIC. So in this book, there are descriptions about defines for I2C. So, when I added DEFINE I2C_SCLOUT 1, everything started to work. This define makes the I2C clock line bipolar. I don't know why it is necessary in my case, but it makes everything to work :)

So here is the final code, which works with this PIC and EEPROM:

-------------------------------------------------------------

DEFINE OSC 4
define I2C_SCLOUT 1 ' Makes I2C clock line bipolar

Include "modedefs.bas"

CVRCON = 0 ' No reference
CMCON = 7 ' No comparator
TRISA = %00000000 ' Set PORTA pins into output
TRISB = %00000000 ' Set PORTB pins into output
TRISC = %00000000 ' Set PORTC pins into output

addr var word ' Address of EEPROM
val var byte ' Value of writable variable
val2 var byte ' Value of readable variable
D var PORTC.2 ' Serial Data pin
C var PORTC.3 ' Clock pin
cont var byte ' Control

Pause 1000 ' Pause 1 sec.

val2 = 5 ' Starting value

loop: ' Loop forever

' OK to use cont = %10100000 'Control is set to write
val = 0
for addr = 1 to 10
val = val + 1
I2Cwrite D, C, $A0, addr, [val] 'Write to EEPROM

' OK I2Cwrite D, C, $A0, addr.highbyte, addr.Lowbyte, [val] 'Writes value to EEPROM address 1
' OK I2Cwrite D, C, cont, addr.highbyte, addr.Lowbyte, [val] 'Writes value to EEPROM address 1
' OK I2Cwrite D, C, cont, addr, [val]
Pause 10 ' Pause for 10ms. Needed for writing!
next addr

' OK to use cont = %10100001 'Control is set to read

for addr = 1 to 10
I2Cread D, C, $A0, addr, [val2] 'Read from EEPROM

' OK I2Cread D, C, $A0, addr.highbyte, addr.Lowbyte, [val2] ' Dump EEPROM Contents
' OK I2Cread D, C, cont, addr.highbyte, addr.Lowbyte, [val2] ' Dump EEPROM Contents
' OK I2Cread D, C, cont, addr, [val2]
serout PORTC.6, N9600, [val2] 'Value to serial port
next addr
Pause 200

Goto loop ' Forever

-----------------------------------------------------------------

Soon I'll got also EEPROM 24LC16B in my hand, which I want to drive with this PIC. I hope it will not cause anymore problems.

Thank you for your support Mike and Jerson!

Kristjan

mbruno
- 1st February 2008, 12:15
Hey ! glad to see that every thing worked out for you,, I was sorta worried my taking a different approch than Mr. Jerson would cause some confusion, but I see things worked out in the end..

good Luck

Mike

kindred22
- 4th February 2008, 15:12
how to read and write data on the internal eeprom of 16f877a?
is there a need of interrupt disable?

because when i program a reading data it will out only on the lcd a 0 using the command READ passing through a variable, and on to the lcd..

on the writing data will cause an infinite loop...

thank you...advance

skimask
- 4th February 2008, 15:13
how to read and write data on the internal eeprom of 16f877a?
is there a need of interrupt disable?
because when i program a reading data it will out only on the lcd a 0 using the command READ passing through a variable, and on to the lcd..
on the writing data will cause an infinite loop...
thank you...advance

And yet again...where's the code?

Archangel
- 4th February 2008, 20:52
And yet again...where's the code?

Silly, it's still in the phillipines!

skimask
- 5th February 2008, 13:59
Silly, it's still in the phillipines!

OF COURSE! What was I thinking! :D That's where it's been all along...

And I would've gotten away with it too if it hadn't been for you meddling kids... :D

kindred22
- 10th February 2008, 11:33
sorry i didn't put out the code...

-------

portb=0
trisb=0

aa var byte
bb var byte

eeprom 2,[0]
aa=4
write 2,aa
read 2,bb

if bb=4 then
portb.0=1
endif

end

----------------------------------

that is my code!!!
using 16f877a did not light portb.0
using 16f84a light...
is there any prob with my code?

tnx...

skimask
- 10th February 2008, 11:34
sorry i didn't put out the code...
-------
portb=0
trisb=0
aa var byte
bb var byte
eeprom 2,[0]
aa=4
write 2,aa
read 2,bb
if bb=4 then
portb.0=1
endif
end
----------------------------------
that is my code!!!
using 16f877a did not light portb.0
using 16f84a light...
is there any prob with my code?
tnx...

How many times are you going to double post?
Once is more than enough from the multiple personalities.