Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

I2CRead/I2CWrite problems

Status
Not open for further replies.

AIW128ProGuy

New Member
Hello,
I am trying to simply write data to an EEPROM and read it back, however I am having problems with that simple task. My microcontroller is the PIC 12F629 and the EEPROM is the 24AA00. I am using PicBasic Pro Compiler v2.43. My code is below:


Include "modedefs.bas"
W0 con 8
B0 var byte

I2CWRITE 0,1,$A0,0,[W0]
pause 10

I2CREAD 0,1,$A1,0,[B0]
If (B0 = 8) Then
High 5
Else
High 4
Endif
End


The problem is that no matter what I try, I2CREAD only returns a value of zero. The Data Pin is pin 0 and the Clock pin is pin 1. The control byte is '1010xxx0' for write and '1010xxx1' for read. I know that data is being sent because I took a multimeter to it and the voltage is definately changing on both the lines. Also, I included a label during the troubleshooting that would jump if no acknowledgement bit was sent...but it didn't jump. Thus leading me to believe that the EEPROM is getting the data and acknowledging it...but still returning all zeros. If you can help me out, I must have just messed up the syntax or something. Thanks.

** Chris **
 
I had a similar problem. To read you have to first write.

Write (sequence)

Start command:
slave adress + W bit:
Command address:
data(one or more):
stop command:

Write (sequence)

Start:
slave adress + W bit:
Command address:
Stop command

Start command:
slave address+ R bit
(read data from EEPROM one or more bytes)
Stop command:

The command address counter increments everytime a write of read is done. So to read you first set the address you want to read from, then go read it. Kinda confusing at first, but make sense later. hope this helps you out
 
Hey thanks for the help, but when I use the PicBasic Compiler it automatically takes care of the write before the read. But just to make sure I tried to use the I2CWrite command before the I2CRead like this:


B0 var byte

I2CWrite 0,1,$A0,0
pause 10
I2CRead 0,1,$A1,0,[B0]
If (B0 = 0) Then
High 5
Else
High 4
Endif


So I tried doing the write first and sending no data like you suggested. However, this did not work. I believe this is because when I compile the file using PicBasic, the compiler automatically sets the write before the read just as you have said. But the problem is that even when I type the I2CRead command exactly as it says in the manual, then compile it, it still only returns all zeros as the data. I am basically typing exactly what is in their sample file so I do not understand what is going wrong. If you have any ideas/suggestions please let me know.

** Chris **
 
Currently, my EEPROM (8-pin 24AA00) has:

+5V To Vcc
4.7k Pull Up resistors connected to Data and Clock pins
Gnd on everything else

My PIC (8-pin 12F629) has:

+5V to Vss
Gnd to Vdd
10k resistor connected to /MCLR
Data and clock running to the EEPROM
The other three pins run to a buffer then to an LED


My pull up resistors are just connected to +5V power and then to the data and clock inputs. Thanks for your help!
 
Well, I have tried every combination with and without the resistors (pull-ups on data and clock lines and the inline resistor on /MCLR). But it does not seem to matter if I have the pull-ups or not. Or even the resistor on /MCLR for that matter. If they are there or not, I still read only zeros from my EEPROM. I did not have time to run down to the lab and use their scope, so I just used my digital multimeter to see if I was getting a reading out of the data or clock pins and I can not tell. I think it is just so fast that I could not pick it up anyway. I do not know how familiar you are with PicBasic code, but I used their sample program for I2C interface. The code is supposed to write to the EEPROM (data values equal to the data address). Then, read back that same data and put it out on an asyncronous serial pin. But their program has the same problem. It returns only zeros. I think that maybe I am not using the I2CRead function properly. Here is what I am doing:

Syntax:
I2CRead DataPin, ClockPin, ControlCode, DataAddress, Data

My Code:
B0 var byte 'This defines B0 as a one byte variable
I2CRead 0,1,$A0,0,[B0] 'This sets DataPin to 0
' ClockPin to 1
' ControlCode to $A0
' DataAddress to 0
' Data read should go into B0 variable

It is this last part that is confusing. The data from the EEPROM should be read into the variable B0. Now I should be able to manipulate B0 or compare B0 to something. But B0 is always zero. Either the data being read back is zero and that is being put in B0, or the data being read back is not actually being stored in B0 and B0 is just remaining empty. If you know the syntax, please let me know.

Also I decided to try reading and writing from the internal EEPROM just to see if I could get that to work. I used the following code:

W0 con 4
B0 var byte

Write 1, [W0] 'Writes to address 1 the value of W0, which is 4
pause 10
Read 1, [B0] 'Reads the value at address 1 into the variable B0
If B0 = 4 then
High 5 'Turns on the correct LED
else
High 4 'Turns on the wrong LED
endif

THIS WORKED PERFECTLY!! It wrote a 4 to the internal EEPROM then read that value back into the variable B0. I checked that B0 was 4 and then turned on the correct LED. This process should be the same for an external EEPROM using the I2C interface. That is the problem I am having. Thanks for all your help, let me know what you think.

** Chris **
 
P.S.

I tried a two byte address. It did not do anything different. I even tried it with out the address entry (since it is optional), but still returned all zeros. Just incase it helps to know, I am using a 24AA00 EEPROM instead of an LC version. I don't think this makes any difference, but by now I just don't know what is going on anymore. Thanks for your help.

** Chris **
 
Same Problem

I am having the exact same problem.
The LCD is only displaying zeros.
Here is my code. It is very similar to yours.


define CHAR_PACING 1000


receive var byte
addr var word
cont con %10100000

startup:
pause 1000
clear
high GPIO.2 'initialize LCD
pause 100
low GPIO.2
serout GPIO.2, 2, [17] 'turn backlight on

addr = 0
i2cwrite GPIO.0,GPIO.1,cont,addr,[12]
pause 10

addr = 0
i2cread GPIO.0,GPIO.1,cont,addr,[receive]
pause 10
serout GPIO.2, 2, [#receive]
pause 10

end
 
Answer

I Spent 6 hours trying to figure out the problem.
you have to turn off the comparator.

DEfine OSC 4
define CHAR_PACING 1000

CMCON0 = 7
ANSEL = %00000000
TRISIO = %00000000
DPIN var GPIO.0
CPIN var GPIO.1
addr var word
in var byte
cont con %10100000
cont2 con %10100001

startup:
pause 1000
clear
high GPIO.2 'initialize LCD
pause 100
serout GPIO.2, 2, [17] 'turn backlight on

addr = 0

i2cwrite DPIN,CPIN,$A0,addr,[12]
pause 10



addr = 0

i2cread DPIN,CPIN,$A0,addr,[in]
pause 10
serout GPIO.2, 2, [#in]
pause 10



end
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top