PDA

View Full Version : I2C Read/Write problems



Dispersion123
- 2nd April 2008, 18:11
Hello all,

I did a search but didn't find anything that quite explains my problem, so here it goes:

I'm attempting to do I2C communications with another (slaved) microcontroller. The other microcontroller is a purchased product so I have little control over the code loaded on it. The device ID (device address?) is $10, I'm attempting to read a 16bit word on the microcontroller that is stored at $22 and $23 on the microcontroller. The microcontroller uses I2C communications at 400Khz, but for some reason my clock is at 122Khz (PIC16f676, 20MHz crystal). I'm not 100% sure I'm using the I2C read command correctly :P. Here is my code thus far:

define OSC 20

'lines to use i2cread
SDA var PORTA.0
SCK var PortA.1
'end lines to use i2cread

'LCDOUT DEFINES
define LCD_DREG PORTC
define LCD_DBIT 0
define LCD_RSREG PORTC
define LCD_RSBIT 4
define LCD_EREG PORTC
DEFINE LCD_EBIT 5 'Register enable bit on portc.5
define lcd_lines 4
'END LCDOUT DEFINES


Scntrl var byte
sadd var byte
Scntrl = $10
sadd = $22
myvar var word
pause 2000
main:
lcdout $fe,1,"Dubugging..."
i2cread PortA.0, PortA.1, Scntrl,sadd,[myvar.lowbyte, myvar.highbyte],fail

'last:
lcdout $fe,$c0,"Success!!!"
lcdout $fe,$94, "myvar = ", #myvar
goto done
fail:
LCDOUT $fe,$c0,"READ FAILED!!!"
done:
end

NOTE: THE LCD Works fine.

skimask
- 2nd April 2008, 18:28
uses I2C communications at 400Khz
Probably not 400Khz all the time, but a maximum of 400Khz...


(PIC16f676, 20MHz crystal).
Look carefully at the datasheet for the 'F676, specifically the RA0, RA1, and section 6 of the datasheet...

JD123
- 2nd April 2008, 18:34
I don't think you can use the myval.Highbyte etc. in the I2C instruction.

From the manual:

"If a word-sized Var is specified, 2 bytes are read and stored into the Var high byte first, followed by the low byte. This order is different than the way variables are normally stored, low byte first."

Looks like you just use the variable (WORD) as is. Pay attention to the loading order.

Dispersion123
- 2nd April 2008, 19:23
I have tried just putting myvar instead of myvar.lowbyte and myvar.highbyte in there. So, I'm guessing I need to turn the comparators off?

ANSEL = %00000000
CMCON = %00000111

???

Any suggestions on how to get the correct device address sent ($10), and read the address $22?

mister_e
- 2nd April 2008, 20:00
You already have a LCD attached to it... why not monitor the HEX value of the WORD variable using HEX4

Not sure if the optional label jump work with I2CREAD and your external device...

JD123
- 2nd April 2008, 21:15
Any suggestions on how to get the correct device address sent ($10), and read the address $22?

If the device address is $10 then doesn't the address have to be left shifted one place?

$10 = %00010000

PBP handles the R/W bit (bit.0), so your sending out address %0001000R (Read or Write bit) and the address "seen" by the receiving device is %00001000

Remember that I2C device addresses are shifted left one place to allow for the read/write bit. You'll never (edit: never say never - there are 10 bit addressing in some devices, though this is not part of the original I2C design data) see an I2C device address over $7F, or %01111111 or DEC127.

So, I think you should be using the DEVICE ADDRESS of $20

mister_e
- 2nd April 2008, 21:32
Doesn't sounds right to me... how about most I2C EEPROM with $A0?

skimask
- 2nd April 2008, 21:32
If the device address is $10 then doesn't the address have to be left shifted one place?
I thought PBP handled that part for you. 'cause with a generic serial eeprom, the address is something like $a0, and that's how you address it...$a0, without the left shift, PBP handles the R/W bit.
But then again, we don't know exactly what kind of secret magic device is being addressed here...

JD123
- 2nd April 2008, 21:45
I thought PBP handled that part for you. 'cause with a generic serial eeprom, the address is something like $a0, and that's how you address it...$a0, without the left shift, PBP handles the R/W bit.
But then again, we don't know exactly what kind of secret magic device is being addressed here...

$A0 is the LOWER 7 bit's of the address, shifted left one place. The DEVICE address being sent out and 'seen' by the reciever is %01010000, or $50. Check the specs of I2C, not just EEPROMS. The device address is specified as a 7 bit address, not 8. But since we are adding the R/W bit to the 8 bit address byte, we have to left shift the DEVICE address one place.

The confusion comes in dealing with 2 different data "specs" or "types" combined into one 8 bit Byte being send. Then suming the two values to "use" one value. That "one" value is not the device address.

You ever do this: (I know I have)
Gang 8 64KBit EEproms and use the device address (bit 4:1) by just rolling the long address over directly into the device address. It won't work. Trust me, just shift the address left once to embed the address into the device address byte.

skimask
- 2nd April 2008, 21:51
The DEVICE address being sent out and 'seen' by the reciever is %01010000, or $50. Check the specs of I2C, not just EEPROMS. The device address is specified as a 7 bit address, not 8. But since we are adding the R/W bit to the 8 bit address byte, we have to left shift the DEVICE address one place........
I guess that's what I'm saying here...is that PBP handles it for us.


The confusion comes in dealing with 2 different data "specs" or "types" combined into one 8 bit Byte being send.
Confusion say...Man who live in glass house...should dress in basement... :D

JD123
- 2nd April 2008, 21:59
Confusion say...Man who live in glass house...should dress in basement... :D

My spell checker wants another quarter and I'm too cheap to give it up! ;)

JD123
- 2nd April 2008, 22:04
I guess that's what I'm saying here...is that PBP handles it for us.

No. it doesn't. PBP handles the R/W bit for us. We still have to give it the correct address, formated to the device address byte. That's why you send %10100000 and the reciever "sees" %01010000 as the device address.

Now, if the receiving device specs say "send $xyz" then they have already formated the address for you. That still doesn't change the fact that the address is the upper 7 bits shifted right one place.

JD123
- 2nd April 2008, 22:11
Doesn't sounds right to me... how about most I2C EEPROM with $A0?


Sorry, I overlooked your post. Are you seeing what I'm saying?

mister_e
- 3rd April 2008, 00:08
Not sure... sure i misunderstand what you said.


addr var word
CTL CON $A0
addr=$F0F0

SendIt:
I2CWRITE PORTD.6, PORTD.7,CTL,addr,[$F1F2]
pause 50
goto sendit

will looks like...
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2461&stc=1&d=1207177612">

But yeah.. on some device, the Address can be mixed with the ControlByte. EEPROMs such as some 24C04, c08 and c16 work like that.
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2462&stc=1&d=1207177999">

They call it page select (sort of)... those Px bits...

NOTE: well it's not a 24lc64screenshot but anyways.

skimask
- 3rd April 2008, 01:20
No. it doesn't. PBP handles the R/W bit for us. We still have to give it the correct address, formated to the device address byte. That's why you send %10100000 and the reciever "sees" %01010000 as the device address.
Ok, I'm smelling what your cooking... I'm pickin' up what you're layin' down...
(what happens if we overclock that same PIC to 50Ghz to get really fast I2C? :D)

Dispersion123
- 3rd April 2008, 06:05
Wow... lots of help... I'm attempting to get the read to work, using $20 for the control byte. I'll see what I can do... eventually I want to be able to read and write registers using the LCD screen as sort of a 'menu' guide, and using my last to ports as button inputs.

EDIT:

Can anyone give me an idea as to why the clock is so far off? The book says 400KHz devices are accessible if the clock is above 8MHz (I'm using 20), but my clock is at 122Khz. The manufacturer of the board said this wasn't a problem so long as the PIC supported 'clock stretching'.

If anyone is interested, what I'm trying to connect to is an 'Open Servo' board.

skimask
- 3rd April 2008, 13:44
Can anyone give me an idea as to why the clock is so far off? The book says 400KHz devices are accessible if the clock is above 8MHz (I'm using 20), but my clock is at 122Khz. The manufacturer of the board said this wasn't a problem so long as the PIC supported 'clock stretching'.
See Post #2...
400Khz is the MAXIMUM for most fast I2C devices. It's not neccessarily the speed that the PIC is communicating to said I2C device. I2CRead/I2CWrite are software, 'bit-banged' commands, not hardware.
If you ran your PIC clock at 40Mhz vs. 20Mhz, the I2C clock may very well jump up to 244Khz.

Acetronics2
- 3rd April 2008, 13:55
See Post #2...
400Khz is the MAXIMUM for most fast I2C devices. It's not neccessarily the speed that the PIC is communicating to said I2C device. I2CRead/I2CWrite are software, 'bit-banged' commands, not hardware.
If you ran your PIC clock at 40Mhz vs. 20Mhz, the I2C clock may very well jump up to 244Khz.


Hi, Ski

You forget the 24 FC series ... @ 1Mhz !!!

Alain

skimask
- 3rd April 2008, 13:57
Hi, Ski
You forget the 24 FC series ... @ 1Mhz !!!
Alain
Don't they call those 'HIGH' speed, a bit like USB? Slow, Fast, High?

JD123
- 3rd April 2008, 16:10
Wow... lots of help... I'm attempting to get the read to work, using $20 for the control byte. I'll see what I can do...

Here's the $24 million dollar question:

Does the documents for the slave IC say send address $10 or does it say that its address is $10.

So far as the clocking speed, there can be pulses that come close to 400k being send out, but that's just for a short period of time. The clocking speed will most likely vary in speed depending on what's being done. BTW, how are you reading the clocking speed? O-scope or frequency counter?

JD123
- 3rd April 2008, 16:27
Mr.E., cute program you got there.

See in the program where you enter "1010000" for the address? That's $50 for the address.

Any who, I think everyone's got the idea, in agreement or not. I just took the O/P literally for the words he used and opened a can of do-do. Sorry.

JD123
- 3rd April 2008, 16:33
Ok, I'm smelling what your cooking... I'm pickin' up what you're layin' down...
(what happens if we overclock that same PIC to 50Ghz to get really fast I2C? :D)

50Ghz? Don't know, but I think you can use the IC as a hot-plate to keep your coffee warm. ;)

mister_e
- 3rd April 2008, 16:48
Mr.E., cute program you got there.

See in the program where you enter "1010000" for the address? That's $50 for the address.

OK :D i see what you mean... $A0 is the ControlByte (Controlword or slave address depending of the document you have on hand... says datasheet) but yeah $50 for the address... this said, i don't remember to have any issue with any datasheet using what they said, whatever how they call it :o maybe why i didn't understood your point ;)

We still don't see the O/P datasheet or part#... weird eh?

JD123
- 5th April 2008, 15:11
Dispersion123, how's it coming, reading the 2 bytes?