# I2C sometimes works PIC18F

Status
Not open for further replies.

#### Synaps3

##### Member level 1
I am using a PIC18F to communicate over I2C to the RDA5820 FM chip. I have a suspicion the problem has nothing to do with the RDA however, because I've tried other chips in place and experienced the same problems. About 50% of the time the PIC will halt (just stops executing as if i2c disconnected), and the rest of the time the communication works fine. This is the first time I'm programming a I2C device, so I may be overlooking something. I have pullups on both pins (the datasheet for the RDA says that it has internal pullups) and when I leave out the external, nothing seems to change. I'm using a 100khz clock and the datasheet specifies 0 to 400khz. I'm doing all this on a breadboard with long wires. Could that be effecting it?

#### Aussie Susan

Which PIC18F? Does it have a watchdog?
When it works, does it keep working or only for a short time?
Can you show us your code as there might be something there?
Are you running under a debugger? What compiler and programmer?
(As you can see, I've had to guess a lot because you have not really told us much.)
Susan

#### Synaps3

##### Member level 1
I found out that the MikroC I2C library has a bug that they are working on that causes the PIC to stop executing when it has a communication error. HOWEVER, this is not the source of the problem; it's just an additional problem. The device should not have communication problems half of the time.

I don't know if it would continue working as my code is not long enough to test that. I'm using PIC18F26K22 with MikroC, no debugger (do have proteus though).

Here is my code:

Code:
  ANSELC = 0;
ANSELB = 0;
TRISB.F6 = 1;  //set port b bit 6 to input
TRISB.F7 = 1;  //set port b bit 7 to input
TRISC.F7 = 1;  //set port c bit 7 to input

TRISC.F3 = 0;  //i2c ports to output
TRISC.F4 = 0;

I2C1_Init(100000);
Delay_ms(125);

//reset
iic_wr(2, 0xc282);
//enable
iic_wr(2, 0xc281);
iic_wr(5, 0x8c84);
//60.0-115.0Mhz
iic_wr(0x53, 650);
iic_wr(0x54, 1150);

//transmit
iic_wr(0x40, 1);
iic_wr(0x3, 0x525c); // 97.9

I2C write code:

Code:
void iic_wr(unsigned char addr, unsigned int dat)
{
I2C1_Start();
I2C1_Wr(0x22);
Delay_ms(1);

I2C1_Wr(dat>>8);
I2C1_Wr((unsigned char)dat);
I2C1_Stop();
Delay_ms(125);
}

#### Aussie Susan

If you don't have a debugger, I suppose that you don't have a scope either! IT would have been very useful to see the signals and to make sure that they were well formed etc..
I'm sure that is not all of your code!
What oscillator source are you using? What frequency is the oscillator?
If you don't have a debugger, how do you know that the device is 'halt'ing? Also, do you really "halt" or do you mean a tight loop or what?
I assume that you have all of the bypass capacitors in place, that the \MCLR\ pin is held high (or disabled in the config settings). Is the programmer still connected when you try to run the code?
I assume that you have the "MODE" pin on the RDA5820 held low?
On that, have you tried using the SPI interface instead? It can be simpler (no ACK etc in the command signals) and is also a bit easier to drive from your software. If you can show that the SPI interface works then it would help to narrow down the problems.

#### Synaps3

##### Member level 1
If you don't have a debugger, I suppose that you don't have a scope either! IT would have been very useful to see the signals and to make sure that they were well formed etc..

I do. I just don't have access to it right now. I'll take a look at it as soon as I can.

I'm sure that is not all of your code!

That's correct, but it is all of the i2c code. It is also the first code that is executed (nothing before it). All the other code has to do with 2x16 LCD communication.

What oscillator source are you using? What frequency is the oscillator?

The oscillator crystal is 32.768khz. Is it ok to use an i2c bus frequency greater than this speed (I'm using 100khz)?

If you don't have a debugger, how do you know that the device is 'halt'ing? Also, do you really "halt" or do you mean a tight loop or what?

Well, all I know is that after the code I posted there is a line that outputs text to my LCD and whenever the RDA is not initialized, the text is not displayed. There are no loops or anything fancy for it to get caught in (in the internal mikroC libraries there may be).

I assume that you have all of the bypass capacitors in place, that the \MCLR\ pin is held high (or disabled in the config settings). Is the programmer still connected when you try to run the code?

I have a bypass capacitor on the RDA, but none on the PIC. Not 100% sure about the MCLR - I'll check that. The programmer is still connected. I'm using the pickit3 and I'm using it as the power source as well.
(I know this might mean I have a debugger, but I use mikroC so I can't use it with that.)

I assume that you have the "MODE" pin on the RDA5820 held low?

Thanks for the help. I can see you looked deep.

I'm sure it is. One reason is because I've tested other chips in place of the RDA that only have i2c communication and they have the same problem. The RDA I'm using is actually mounted on a module from china. The module does not contain any components other than the RDA and the 32khz crystal. It is used just to make experimentation on the breadboard easier. The problem is this MODE pin is not exposed to the module. I asked the chinese though, and they said that it is set for i2c by default (so that sounds like the MODE pin must be low), but I can't verify because it's not exposed and the pin is far too small to probe directly on the RDA.

On that, have you tried using the SPI interface instead? It can be simpler (no ACK etc in the command signals) and is also a bit easier to drive from your software. If you can show that the SPI interface works then it would help to narrow down the problems.

No, I haven't and I don't think it would be possible to put the MODE pin high because of above.

#### Aussie Susan

The oscillator crystal is 32.768khz. Is it ok to use an i2c bus frequency greater than this speed (I'm using 100khz)?
(It is statements such as this that are the reason I ask to see all of the code, including the configuration settings.)
The I2C baud rate generator (as described in Section 15.7 of the PIC18F26K22 data sheet) cannot run faster that Fosc/4 (and there is also the division by (SSPxADD+1) in there as well). Therefore to achieve 100kHz you must be getting Fosc to be at least 400kHz.
Looking at the various oscillator configurations possible with that processor, based on a 32.768kHz crystal and at best a 4x PLL, I can't see how you can generate the necessary Fosc. You certainly CAN generate that using the HFINTOSC or MFINTOSC clock sources.
Therefore I suspect that either your SCK frequency is way off what you think it is or you are not setting up the oscillator using the crystal you say you are.
The PIC must have the bypass capacitors (as must any such IC). Depending on how good your power supply is, even if there is plenty of current available, the switching transients caused by a MCU at high speed (although I accept that it sounds like your is running very slowly) can cause all sorts of 'strange' behaviours.
I really don't know the MikroC compiler (I've only ever used the free C18 and more recently the XC8 compilers from Microchip with the PicKit3 programmer/debugger) but I'm surprised that you say you cannot use mikroC to debug your code - looking at Chapter 3 of a mikroC User Guide I found on the Internet, Chapter 3 is all about how to debug through the mikroC IDE. As I say, I really have no experience in this area.
Susan

#### Synaps3

##### Member level 1
(It is statements such as this that are the reason I ask to see all of the code, including the configuration settings.)

MikroC doesn't do this in code. You go through the menus to configure this. I've posted a screenshot.

The I2C baud rate generator (as described in Section 15.7 of the PIC18F26K22 data sheet) cannot run faster that Fosc/4 (and there is also the division by (SSPxADD+1) in there as well). Therefore to achieve 100kHz you must be getting Fosc to be at least 400kHz.

My PIC chip is using a 4mhz crystal. It is the RDA that is using 32.768khz. Is it still a problem to use 100khz i2c?

The PIC must have the bypass capacitors (as must any such IC). Depending on how good your power supply is, even if there is plenty of current available, the switching transients caused by a MCU at high speed (although I accept that it sounds like your is running very slowly) can cause all sorts of 'strange' behaviours.

I'll add that and test it.

I'm surprised that you say you cannot use mikroC to debug your code - looking at Chapter 3 of a mikroC User Guide I found on the Internet, Chapter 3 is all about how to debug through the mikroC IDE. As I say, I really have no experience in this area.

It's not an in-circuit debugger. I thought that's what you meant. You have to purchase their programmer (not pickit3) if you want to debug using their software as far as I know.

#### Synaps3

##### Member level 1
Do both clocks have to be faster than the i2c clock? If the PIC chip is 4mhz and the RDA is 32khz, can I still use 100khz i2c?

I've discovered something that is leading me to think the problem is in the hardware/wiring/breadboard. I found if I turn the power on and off quickly (no more than 1 second), the i2c always works the second time. If I wait any time longer than that, it almost never works. This makes me think capacitance in the board maybe???

#### Synaps3

##### Member level 1
OK, I'm pretty sure the problem was SSPCON. I'm done for today (solder joint keeps breaking off the chip). I'll test to see if that fixed it tomorrow.

#### Synaps3

##### Member level 1
It was SSPCON. It still fails about every 10 times though, and I suspect it's the RF getting into the i2c line because when I lowered output power to lowest value (-30dBm), it seems to work every time.

Here is the SSPCON I used:
Code:
  SSPCON1.F5 = 1;       // Synchronous Serial Port Enable(I2C)
SSPCON1.F3 = 1,SSPCON1.F2 = 0,SSPCON1.F1 = 0,SSPCON1.F0 = 0; //I2C in master mode

What's the best way to reduce EMI in the i2c lines?

Last edited:

#### Aussie Susan

I'm sorry but I don't understand what you mean by "it was SSPCON". (For a start, there are 3 SSPxCONy registers where x refers to which of the MSSP peripherals you are using and y is form 1 to 3 depending on which register you are referring to. I assume this is some sort of non-standards register and bit renaming that MikroC use that differs from the data sheet!)
Are you saying that the EMI is altering the "SSPCON" register in some way? If so then I think you will have other registers begin altered as well and therefore a very serious problem (not to mention very high EMI fields).
Or are you saying that EMI on the SCK and SDA lines was high enough to mean the voltage transitions were leading to incorrect detection of a transition (from '0' to '1' or '1' to '0')? If so then it si NOT a register prob elm but an EMI problem.
As you are assign about EMI shielding, the answer is to use some form of shielded cables.
HOWEVER, that also probably means that you have significant other physical design issues such as cables that are too long, intermodulation between the SCK snd SDA lines and so on. You have not mentioned anything about the physical layout so it is hard to tell.
In most radio designs, the RF section is physical shielded from the rest of the circuit in some way, either by having the antenna (or other radiating element) external to the device or having a grounded metal barrier with a small hole for the signal lines to pass through.
Susan

#### Synaps3

##### Member level 1
I'm sorry but I don't understand what you mean by "it was SSPCON". (For a start, there are 3 SSPxCONy registers where x refers to which of the MSSP peripherals you are using and y is form 1 to 3 depending on which register you are referring to. I assume this is some sort of non-standards register and bit renaming that MikroC use that differs from the data sheet!)

It is SSPCON 1 and the F1, F2, F3... are bits 1, 2, 3, etc.

Or are you saying that EMI on the SCK and SDA lines was high enough to mean the voltage transitions were leading to incorrect detection of a transition (from '0' to '1' or '1' to '0')? If so then it si NOT a register prob elm but an EMI problem.

This is what I'm saying. It is an EMI problem; it is no longer an SSPCON problem.

As you are assign about EMI shielding, the answer is to use some form of shielded cables.
HOWEVER, that also probably means that you have significant other physical design issues such as cables that are too long, intermodulation between the SCK snd SDA lines and so on. You have not mentioned anything about the physical layout so it is hard to tell.

Right now the circuit is on a breadboard and the SCK and SDA lines are aprox 14cm long. When I design a PCB, they will only be a few cm long, so I think this may help fix the problem. I seem to have fixed the problem by adding two 100ohm resistors in series on the SCK and SDA lines. I think in addition to shorter wires that should be enough.

I know this is beginning to get a bit off topic, but would adding vias right along the lines on the final PCB improve even more or is it not really worth it? As far as I know there is no way to make a shielded trace on a PCB other than vias or a metal wall, right?

#### Aussie Susan

Depending on the RF frequency relative to the SCL/SDA frequencies you could try bypass capacitors on the lines.
However I think the best way is to keep the radiating element as far away from the rest of the circuit as possible.
I'm not entirely sure why placing resistors in the line would help as they are frequency independent impedances - other than to reduce the overall signal size in which case the EMI must have been very high to effectively swamp the I2C signals which would also have been reduced.
Susan

Status
Not open for further replies.