Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

I2C read operation failing?

Status
Not open for further replies.

shreyas.p

Newbie level 3
Joined
Oct 18, 2010
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,350
Hello

I have written a simple code to read the data present on PCF8574 pins and display it on port 2.

In my project, I have 8 switches connected to PCF8574. And I want to read the status of switches and display it on Port 2.

The following code is working perfectly for WRITE operation. When I write the data 01010101 to PCF8574, it is working (see attached image). To test the read operation, I connected the pins of PCF8574 to vcc and ground to generate a pattern (01010101). But it is not being read.

Here is the code i'm using:

;--------------------------------------
; CODE
; (address pins of PCF8574 are connected to ground)
;--------------------------------------

var1 equ r2
temp equ r4
delay equ r1


sda EQU P1.0
scl EQU P1.1


ORG 0000H
AJMP MAIN


MAIN:
setb sda
setb scl

jnb sda $
setb scl $

mov sp,#50H

acall start
mov a,#40h ; device address of PCF8574 (write operation LSB = 0)
acall send_byte
acall acknowledge

acall start
mov a,#41H ; read operation (LSB=1)
acall send_byte
acall acknowledge

acall read_byte
mov P2,A
acall stop

ret


;---------------------------------------
;SUBROUTINES:
;---------------------------------------

send_byte: mov R0,#08h ; setup count
next_bit:
acall wait_halfbit
rlc A ; rotate next bit into carry
mov SDA,C ; set IIC data to carry value
setb SCL ; set IIC clock
acall wait_halfbit ; wait
clr SCL ; drop clock. signals receiver to sample data
djnz R0,next_bit ; do next bit
setb SDA ; idle the data line
ret


read_byte: mov r0,#08H
mov a,#00h
next:
acall wait_halfbit
mov C,sda
setb scl
acall wait_halfbit
clr scl
rrc A
djnz r0, next
setb sda
acall acknowledge
ret


start:
acall wait_halfbit
clr SDA
clr SCL
ret

stop:
clr SDA
clr SDA ; stop bit

setb SCL
acall wait_halfbit
setb SDA
clr SCL
ret


acknowledge:
setb SCL
acall wait_halfbit
clr SCL
RET

wait_halfbit:
nop
nop
nop
nop
ret



delayms: ; delay of 10ms (however i hven't used it in this code)
mov var1,#230
d:
nop
nop
djnz var1,d
djnz 10,delayms
ret

end
;---------------------------------------

Also I'm getting a message saying
"Simulation is not running in real time due to excessive CPU load"

What does this mean?
I haven't executed this code on breadboard. I'm just testing it on Proteus.
 

Attachments

  • ckt.JPG
    ckt.JPG
    184.8 KB · Views: 55
  • ckt2.JPG
    ckt2.JPG
    193.3 KB · Views: 53
Last edited:

The sequence
Code:
acall acknowledge
acall start

is generating the bus sequence
clr SCL
...
clr SDA
clr SCL
which will never cause a restart. There may be other errors, too.
 

This is a 'C' coding for Read Byte [Using I2C protocol]..

unsigned char ReadByte (bit ack)
{
unsigned char lop, dta;
SCL = 0;
for(lop=0; lop<8; lop++)
{
dta <<= 1;
SCL = 1;
Delay(10);
if(SDA) dta++;
SCL = 0;
}
SDA = ack;
SCL = 1;
Delay(5);
SCL =0;
SDA = 1;
return dta;
}
 

can you post the rest of the code ..?
It might be helpful for me.

thx
 

This is a 'C' coding for Write Byte [Using I2C protocol]

bit WriteByte (unsigned int dta)
{
unsigned char lop;
bit err;
SCL = 0;
for(lop=0; lop<8; lop++)
{
if(dta & 0x80) SDA = 1;
else SDA = 0;
SCL = 1;
Delay(10);
SCL = 0;
dta <<= 1;
}
SDA = 1;
SCL = 1;
if(SDA) err = 1;
else err = 0;
Delay(10);
SCL = 0;
return err;
}

These two things [WriteByte and ReadByte] are enough to write data to registers or read data from registers...
 

I cannot tell for sure but it appears that you are driving the data line high during the read - you need to change the data direction bit during the read so the slave device can pull the the data low when it needs to. In fact you should set the data bit low and then toggle the data direction bit for both reads and writes.
 

it appears that you are driving the data line high during the read
I don't think so. The code seems to be dedicated to 8051 standard IO. It has open drain ports with weak pullup, without any data direction register. There's no risk of driving SDA high with these interfaces.
 

FVM is correct... The code which i have put meant for 8051... In 8051 there is no data direction register [Not like AVR]...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top