PDA

View Full Version : Hardware I2C



Kamikaze47
- 11th March 2008, 17:11
I need to interface a PIC18F4550 to a 24FC512 EEPROM chip which uses an I2C.

The 18F4550 has hardware based I2C capability, but reading through that section of the data sheet has got me fairly confused.

Does anyone have any advice on using the hardware based I2C capabilities?

skimask
- 11th March 2008, 17:15
I need to interface a PIC18F4550 to a 24FC512 EEPROM chip which uses an I2C.
The 18F4550 has hardware based I2C capability, but reading through that section of the data sheet has got me fairly confused.
Does anyone have any advice on using the hardware based I2C capabilities?

I2C is a bit of a pain in hardware. http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf
explains the inner working of I2C relatively easily.
Why hardware I2C vs. PBP's I2C handling?

Kamikaze47
- 11th March 2008, 17:18
This is for the same project that I was having difficulties with my interrupts interrupting SEROUT commands. I assume the I2CREAD and I2CWRITE would have the same problems when interrupted?

skimask
- 11th March 2008, 17:23
This is for the same project that I was having difficulties with my interrupts interrupting SEROUT commands. I assume the I2CREAD and I2CWRITE would have the same problems when interrupted?

I2CRead/I2CWrite can be as fast as the PIC and/or device can make use of them...
Same thing with SerIn/SerOut...if the PIC is set up to run fast and the device can run just as fast, they don't take up much time.
The I2C commands won't get interrupted by ON INTERRUPT but they would get interrupted by DT's fast interrupts.
I would think you could easily go into the I2C macro's and add a couple of lines to turn the interrupts on and off before and after the I2C command (or do it manually each time an I2C command is executed).

Forget that other link. I think this one is better:
http://www.i2c-bus.org/I2C-Primer.520.0.html

Kamikaze47
- 11th March 2008, 17:31
I am using ASM interrupts, as some of them are time critical. I also would prefer not to turn off the interrupts during I2C usage, as I don't want to miss any interrupt events.

I just found this on MicroChip's site. It looks helpful: http://ww1.microchip.com/downloads/en/AppNotes/00989A.pdf

skimask
- 11th March 2008, 17:40
I am using ASM interrupts, as some of them are time critical. I also would prefer not to turn off the interrupts during I2C usage, as I don't want to miss any interrupt events.

I just found this on MicroChip's site. It looks helpful: http://ww1.microchip.com/downloads/en/AppNotes/00989A.pdf

Looks helpful, but I'd suggest reading that other site on I2C and learn a bit about what has to happen behind the scenes for an I2C transaction to be successful.
I2C isn't like serial. You can't really just 'plug a byte' and assume the receiver got it (well, you can for a few things). There's a few steps involved (start, control, address, data, stop/ack/nak, etc). Some under PIC control, some under user control.

How time critical are those 'time critical' interrupts?
Keep in mind that I2C is a lot faster than 9600 baud serial...

Kamikaze47
- 11th March 2008, 18:00
Thanks skimask, i'll give it a read.

I guess when I think about it, they aren't extremely time critical. My main worry was about missing interrupt events. But I guess as long as the interrupt does trigger - say a millisecond late, that shouldn't impact the performance.

skimask
- 11th March 2008, 18:04
I guess when I think about it, they aren't extremely time critical.
It happens...more often than not.
You hear 'I need sub-nanosecond accuracy to time my slot cars!'...come on...do you really?


My main worry was about missing interrupt events. But I guess as long as the interrupt does trigger - say a millisecond late, that shouldn't impact the performance.
Well if I knew what the trigger and the items involved were, I might have a better idea laying in the back of my head on how to compensate...

Kamikaze47
- 11th March 2008, 18:10
Ok, i've got 3 interrupts at the moment.

- USB interrupt that just does a USBSERVICE to keep the USB alive - i'm not sure how often this triggers - i heard somewhere that it was every few milliseconds, but that could be wrong.

- INT0 interrupt hooked to the clock line of a PS2 keyboard (High-Low transition means theres a new bit to capture) - don't want to miss any of these bits.

- TMR0 interrupt that triggers every 6mS to scan a grid of buttons.

skimask
- 11th March 2008, 18:19
- USB interrupt that just does a USBSERVICE
That's a bit of a tough one. I've heard anywhere from 10ms all the way up to 250ms (I don't believe that one for a second, or 4 service interrupts :) )


- INT0 interrupt hooked to the clock line of a PS2 keyboard
Only takes a split uSec to handle this one, if all you do is read and store, then return.


- TMR0 interrupt that triggers every 6mS to scan a grid of buttons.
Could probably extend this out a bit, or maybe put the work off to a 2nd PIC talking serial to the 1st PIC.

This almost sounds like a game controller, like for a flight sim...

Also, as you read the I2C doc's, keep in mind that the PIC controls everything about the I2C when in master mode. The device being talked to only does something after the PIC makes it do it. Therefore, if the PIC starts something, and then has to wait for a bit to continue doing something, the device will just sit there and happily hang out and wait for it.

Kamikaze47
- 11th March 2008, 18:26
Interesting. So the PIC implementation of I2C may be useful. I'll have to try it.

Unfortunately, i've only just ordered the EEPROM chip today, so I have to wait for it to arrive to try it out :(

The reason the timer interrupt is 6mS is because it takes 2 of these interrupts to read 1 row of the matrix, and there are 6 rows, so it takes 72mS to read the entire matrix.

Darrel Taylor
- 11th March 2008, 20:06
I2C is Synchronous in nature. So things only happen when the clock is toggled.
If the I2C routines get interrupted, it won't matter, because the clock won't toggle either.

SERIN/OUT requires certain timing between the bits, and fails when interrupted because that timing changes.
I2C won't care.
<br>

Kamikaze47
- 12th March 2008, 04:47
Oh cool. Good to hear.

Thanks DT and skimask for ur help.

Kamikaze47
- 12th March 2008, 15:26
My PBP manual says:

"The timing of the I2C instructions is set so that standard speed devices
(100kHz) will be accessible at clock speeds up to 8MHz. Fast mode
devices (400kHz) may be used up to 20MHz. If it is desired to access a
standard speed device at above 8MHz, the following DEFINE should be
added to the program: DEFINE I2C_SLOW 1"

My 48Mhz OSC is obviously not "up to 20Mhz".
Do you think it still run at 400kHz by default with a 48Mhz OSC?

skimask
- 12th March 2008, 15:35
Do you think it still run at 400kHz by default with a 48Mhz OSC?
If they don't, set I2C_SLOW and see what happens.
I don't have access to the macro's here with me, but checking the I2C macros might show whether or not the timing is compensated for with the various oscillator DEFINE's.

Kamikaze47
- 12th March 2008, 15:47
I cant make much sense of the macros, but i'll just see what happens.

Still waiting for the EEPROM chip to be delivered, but figured I can make a start on my code anyway.

skimask
- 12th March 2008, 15:59
Still waiting for the EEPROM chip to be delivered, but figured I can make a start on my code anyway.

I know I've been able to get a regular ol' 24LC256 working without a problem at 40Mhz.

Before you start writing code (and failing! :) ), be sure to do a search here for the '512 types. There's a couple of small issues that seem to trip people up a lot.

Kamikaze47
- 12th March 2008, 17:39
I've been reading the posts about it, and getting a pretty good idea of where to look if it doesn't work first time. I've written a test program just to write 32 bytes to the EEPROM and then read it back and check against the original data. Now just gotta wait for the chip to arrive.

One thing I did notice is that people are saying you have to wait 10mS between writing and reading. Does this also apply to just reading? i.e. If I read 32 bytes with [STR string\32] and then do the same thing again to read the next 32 bytes, will I have to wait 10mS between? I'm sure this info must be in the data sheet, but i looked thru the data but couldnt work it out.

skimask
- 12th March 2008, 18:07
One thing I did notice is that people are saying you have to wait 10mS between writing and reading. Does this also apply to just reading? i.e. If I read 32 bytes with [STR string\32] and then do the same thing again to read the next 32 bytes, will I have to wait 10mS between? I'm sure this info must be in the data sheet, but i looked thru the data but couldnt work it out.

Only applies to the write. If you're using PBP 2.50a, also use the DEFINE that shuts off interrupts during writes.
Use 10mS as a starting point for the 'after write' delay and make sure it all works fine.
Then start backing off your delay until it fails, then bump it up a notch. You could get really picky and use pauseus for the delay.
But I'd say poll the eeprom's busy bit itself for maximum performance.
As far as multiple byte writes, depends on the eeprom. If the eeprom's page size is 32 bytes, then you write 32 bytes, wait 10mS, write 32, wait 10mS...etc...

Kamikaze47
- 12th March 2008, 19:16
I'm glad that this only applies to writes, because in this particular application the PIC wont need to write to the EEPROM at all. I will fill it with data 1st, and the PIC will only need to read the data, not write it. So looks like I dont have to worry about timing. I'll just read the data whenever I need it.

Darrel Taylor
- 12th March 2008, 20:29
If you're using PBP 2.50a, also use the DEFINE that shuts off interrupts during writes.
That only works with Writes to Internal EEPROM.
Has no effect on I2CWRITE.

skimask
- 13th March 2008, 13:24
That only works with Writes to Internal EEPROM.
Has no effect on I2CWRITE.

'der....
I knew that....