PDA

View Full Version : I2C Read and Write



DerekMacom
- 11th April 2008, 13:08
Hi I was wondering if anyone could give me a clue as to what's going wrong here, it's driving me nuts? Signals look ok as far as I can see, 4k7 pull ups fitted on both lines

I've got a P18f252 interfaceing with a 24LC84 eeprom, it's in HS PLL mode, the eeprom is the only device on the bus...

Any help would be appreciated.

My code is sitting in a loop with the following code...

'defines
'DEFINE OSC 40 ' Operating frequency
'DEFINE I2C_SLOW 1
'I2C_CON CON %10100000 ' Memory I2c control byte
'i2c_sda var PORTA.0 ' I2C serial data line
'i2c_scl var PORTA.1 ' I2C serial clock line

mem_off = 0;
MyWordWr = MyWordWr+1
i2cwrite i2c_sda, i2c_scl, I2C_CON, mem_off, [MyWordWr]
i2cRead i2c_sda, i2c_scl, I2C_CON, mem_off, [MyWordRd]

ram[F05_HI] = MyWordRd/256 'This register can be read over modbus
ram[F05_LO] = MyWordRd

ram[F10_HI] = MyWordWr/256 'This register can be read over modbus
ram[F10_LO] = MyWordWr

JD123
- 11th April 2008, 16:01
'I2C_CON CON %10100000 ' Memory I2c control byte

change this to a var, not con

from the pbp manual:

" Constants should not be used for the address as the size can vary dependent on the size of the constant. "

DerekMacom
- 14th April 2008, 09:39
Hi thanks for replying... though the 'I2C_CON CON %10100000 ' is my control byte, not the address which is 'mem_off' and declared as a word.

I'll give it a shot though.

Thanks again.

Derek

DerekMacom
- 14th April 2008, 09:54
Defining the control byte as a var didn't help... so I need to keep looking :o(

Also I've noticed that if I put a 10ms Pause between my write and read my serial coms stops responding, does the PAUSE command disable the interupts or something?

mister_e
- 14th April 2008, 10:31
Make sure you have disabled all multiplexed Analog modules on the pin you're using. (ADCs and/or comparators)

http://www.picbasic.co.uk/forum/showthread.php?t=561

Could be interesting to see your config fuses setting... and the whole code.

falingtrea
- 14th April 2008, 21:21
Well, I did a search for a 24LC84 and could not find a data sheet anywhere. What size is this part? If it is bigger than 32 kbits, then it probably needs a word size value for mem_off. For your ram_lo data I think you should mask off the upper byte by and'ing MyWordWrite and MyWordRead with 0xFF. Or use the .lowbyte and .highbyte modifiers. In fact, I don't see size definitions for any of your variables. Is mem_off a byte or word variable? Is ram a byte or word array? What are F05 and F10 defined as?

DerekMacom
- 15th April 2008, 12:56
First of all sorry it was a typo.... it trying to talk to a 24LC64.

I am switching the ADC off with ADCON1 = $07, been caught with this one before. Though in this project I'm reading one of the ADC channels, so this might be worth a look.

Fuse setting's are all default apart from HS PLL enabled.

JD123
- 15th April 2008, 16:22
Is the "mem_off" variable word size? The 24C64 uses a word sized address. Your variable "mem_off" is being sent as the address. Also, just asking, but you do have the A0:A2 pins on the IC grounded for the device address "1010000", right?

Your lines:


ram[F05_HI] = MyWordRd/256 'This register can be read over modbus
ram[F05_LO] = MyWordRd

are a bit odd and are going to run up a lot of code space. I'd use:


ram[F05_HI] = MyWordRd.Highbyte
ram[F05_LO] = MyWordRd.Lowbyte

falingtrea
- 15th April 2008, 16:22
Alright let's try some simple things. Are the A0, A1,and A2 pins are tied to ground or VCC? These address pins also need to be correctly selected in the control byte. For the control byte you are using they should be all grounded. Is the WP pin floating or connected to gnd?

You definately need some way of waiting 10 msec between writing and reading or you will get a NACK from the part and no read data. Also, if you want to use interrupts to manage the serial port, you will probably have to write your own serial port interrupt routine. The PB code is not really interrupt driven itself. From the PBP manual:

"Since PBP statements are not re-entrant (PBP must finish the statement that is being executed before it can begin a new one) there could be considerable delay (latency) before the interrupt is handled."

edit: Like minds, eh JD?? :)

JD123
- 15th April 2008, 17:08
Seems so, Tim. I didn't notice the lack of a 10ms pause though. Good catch.

falingtrea
- 15th April 2008, 22:36
Also I've noticed that if I put a 10ms Pause between my write and read my serial coms stops responding, does the PAUSE command disable the interupts or something?

Serial rate of 9600 baud is about 1 msec per character so a 10 msec pause could definately cause problems. The manual says this about HSERIN:

"As the hardware serial port only has a 2 byte input buffer, it can easily overflow if characters are not read from it often enough."

You might have to break up the pause into chunks and do a serial read in between. Maybe do 3-4 HSERIN or SERIN calls with a 2-3 msec timeout.

JD123
- 15th April 2008, 23:11
Tim, it doesn't look like he's using the HSERIN. Ports RA.0 and RA.1 aren't the serial ports on this PIC.

DerekMacom
- 16th April 2008, 14:28
Hi there....

I have a project I've 'adopted' that I've been asked to add a feature to. I'm soon going to be starting again from scratch as there are many things about the code in it's current form that aren't good. Mostly that there is way too much stuff going on in the interrupts. I was hoping to add this feature quickly but looks like this is going to be another thing to add to my 'reason's to start from fresh' list. I'm useing the internal eeprom for the time being to buy me some time until I get a chance to start fresh.

Thank you to you all for trying to help.
Derek

falingtrea
- 16th April 2008, 16:02
Tim, it doesn't look like he's using the HSERIN. Ports RA.0 and RA.1 aren't the serial ports on this PIC.

Yeah, but Derek mentioned at one point that when he put in a PAUSE he had problems with his serial comm. I figured he must have more code than the snippet he has posted. :)

falingtrea
- 21st April 2008, 16:44
Heh! Saw this thread reference in another I2C thread. Looks like it might apply here to.

http://www.picbasic.co.uk/forum/showthread.php?t=587