View previous topic :: View next topic |
Author |
Message |
bsturm
Joined: 23 Feb 2009 Posts: 29
|
Weird I2C slave issue |
Posted: Fri Mar 06, 2009 4:54 pm |
|
|
I am having a difficult time getting an I2C network working on two 16F886 chips. My master program works well with a slave test program. When I copied the test programs I2C relevant code into my real program, it wouldn't work. I proceeded to comment out everything that was not in the test program until they appeared identical, still not working.
I then noticed the #fuses were different, the test program used HS for the oscillator. The real program used INTRC_IO. I am using the internal oscillator at 8 MHz, there is no external oscillator or crystal. I assume that the PIC must have gotten an oscillator fault and reverted to the internal oscillator. Why does my I2C (mostly) work with this configuration? What is different? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 06, 2009 5:03 pm |
|
|
What are the oscillator frequencies of the Master and Slave PICs in
your original working test setup, and what are they in the current setup ? |
|
![](templates/subSilver/images/spacer.gif) |
bsturm
Joined: 23 Feb 2009 Posts: 29
|
|
Posted: Fri Mar 06, 2009 5:11 pm |
|
|
I was just looking at that. The Master is set at 8 MHz. The Slave test program that worked was at 4 MHz. My slave program (with the issues) was at 8 MHz. I set my Slave program to 4 MHz and it is now working. I thought that I2C is not supposed to be so timing sensitive. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 06, 2009 5:54 pm |
|
|
Normally I would have expected the slave to work better if it's faster,
because it can respond more promptly to the master. |
|
![](templates/subSilver/images/spacer.gif) |
bsturm
Joined: 23 Feb 2009 Posts: 29
|
|
Posted: Fri Mar 06, 2009 6:10 pm |
|
|
Yes, me too. Faster doesn't work at all though. I still get an error every few seconds. There seem to be some timing issues. If I slow down the master, it stops working also. I am going to try to implement the workaround listed in the 16F886 errata. Something seems to be missing in the handshaking, I am guessing. Or maybe a few extra delays here and there? I am worried that this will not be too reliable unless I fix it right. |
|
![](templates/subSilver/images/spacer.gif) |
bsturm
Joined: 23 Feb 2009 Posts: 29
|
|
Posted: Fri Mar 06, 2009 7:49 pm |
|
|
Actually, now it is working best at 8 MHz. I am not sure as to why. So far, it has run 10 minutes with no errors. I plan to let it run for a while with my trap set.
I did change from this:
Code: |
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use i2c(SLAVE, I2C1, address=0xa0) |
To this:
Code: |
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0) |
|
|
![](templates/subSilver/images/spacer.gif) |
bsturm
Joined: 23 Feb 2009 Posts: 29
|
|
Posted: Sun Mar 08, 2009 10:45 am |
|
|
My I2C slave on the 16F886 is working fine now. I also made these changes as suggested on the Microchip forums.
Code: |
#bit SEN = 0x91.0
#bit CKP = 0x14.4 |
I set the SEN bit when the program starts and I set the CKP bit at the end of the ISR.
My master still needs a 100us delay before reading from the slave, like this:
Code: |
i2c_start();
i2c_write(Addr+1); // send i2c address w/ read bit set
delay_us(100); // give time for slave to process
data[0] = i2c_read(ACK); // read data, ACK for next byte
data[1] = i2c_read(NACK); // read data, NACK for last byte
i2c_stop();
|
|
|
![](templates/subSilver/images/spacer.gif) |
bsturm
Joined: 23 Feb 2009 Posts: 29
|
|
Posted: Mon Mar 16, 2009 6:32 pm |
|
|
Yesterday, I made another tweak to get my I2C slave working right. Sometimes I would read five numbers in a loop, each with its own request. Sometimes, the third number would have the wrong data. The numbers on both sides would be fine. This was very baffling, the data was in an array and were all very similar in value. I ended up putting a 1 mS delay after each write/read and it all was fine again. It is maddening how timing sensitive this I2C seems to be. |
|
![](templates/subSilver/images/spacer.gif) |
|