View previous topic :: View next topic |
Author |
Message |
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
16F886 I2C |
Posted: Mon Aug 06, 2007 10:46 pm |
|
|
Hi All,
I am migrating a program from a 16F876 to a 16F886.
The device is configured as an I2C slave.
I am using an 18F4620 as the Master
I can load the original program into the 876 and it will run the ex_slave program beautifully however it will not run on the 886.
As soon as I connect the 886 to the I2C bus both devices stop running.
I have checked the C3 and C4 pins on the 886 while it is running and they are held low which I am sure is part of the problem. From the data sheet I can see nothing else that would cause this problem.
Your thoughts as always would be appreciated.
Cheers
Mark _________________ Life is too short to avoid asking questions |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Aug 06, 2007 10:47 pm |
|
|
Post your compiler version. |
|
|
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
|
Posted: Mon Aug 06, 2007 10:51 pm |
|
|
My Apologies, I should know better
Version 4.047
Cheers
Mark _________________ Life is too short to avoid asking questions |
|
|
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
Slave Code |
Posted: Mon Aug 06, 2007 10:56 pm |
|
|
Here is my version of the Slave code
Code: |
#include <16F886.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16)
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWRT //Program memory not write protected
#FUSES BORV40 //Brownout reset at 4.0V
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Slave,Slow,sda=PIN_C4,scl=PIN_C3,force_hw,address=0xA0)
BYTE address, buffer[0x10];
#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;
state = i2c_isr_state();
if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;
}
if(state == 0x80) //Master is requesting data
{
i2c_write(buffer[address]);
}
}
void main ()
{
setup_adc_ports(sAN0|VSS_VDD);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (1) {
output_toggle(Pin_B2);
delay_mS(100);
}
} |
Cheers
Mark _________________ Life is too short to avoid asking questions |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 07, 2007 1:14 pm |
|
|
1. Can you make the 16F886 work at all ? Can you make it blink an LED ?
2. Did you do both tests (for 16F876 and 16F886) with the same compiler
version (4.047) ?
3. For the test with the 16F886, did you use the same board as for the
16F876 ? Or is it a new board ? Ideally, you would have just one
board and pull the 16F876 out of a socket, and drop in the 16F886
in its place.
4. What's the Vdd voltage used with each PIC ? |
|
|
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
Results |
Posted: Tue Aug 07, 2007 1:49 pm |
|
|
Hi PCM,
If I run the 886 by itself it will blink it's LED quite happily.
Both tests were completed with 4.047
both PICs are supplied from the same 5 volt supply
The problem comes when , after programming, I plug the pcb carrying the slave into the bus. The bus just carries +5,Gnd SCL and SDA.
There is nothing else connected to the bus as I am only experimenting with this code before integrating in a bigger project.
I have received a notification to download 4.049, should I do so?
Cheers
Mark _________________ Life is too short to avoid asking questions |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 07, 2007 2:25 pm |
|
|
Right, but is the 16F886 mounted on a new, untested slave board ?
Or has the slave board been tested already with the 16F876 ? |
|
|
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
|
Posted: Tue Aug 07, 2007 2:29 pm |
|
|
I have three pcbs, One has an 876 onboard and two have 886's.
This is a very common board in our fleet and well tested. I get the same results with both 886 boards. _________________ Life is too short to avoid asking questions |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 07, 2007 2:52 pm |
|
|
Does the slave board have the pull-ups on it ? Or are they mounted
on the master board ?
If you take a slave board that has no PIC on it, and plug it into the bus,
are the SDA and SCL lines still held low ?
If you take the slave board with a 16F886 on it, and program the PIC
with the code shown below, are the SDA and SCL lines still held low ?
Code: |
#include <16F886.h>
#fuses HS,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=20000000)
//=======================
void main ()
{
while (1);
} |
In other words, I want to establish beyond a shadow of a doubt, that
the reason the SDA and SCL lines are being held low is caused by the
slave code, and not for any other reason. |
|
|
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
Tests |
Posted: Tue Aug 07, 2007 3:06 pm |
|
|
The pullups are only on the master pcb, 4k7. I did try fitting extra ones on the slave pcb but as it did not change things I removed them again.
With no PIC all lines stay high
Witha PIC programmed with your sample code all lines stay high so I guess we have eliminated the hardware.
I have also tried version 4.049, the outcome was the same, still pulls lines low
Cheers
Mark _________________ Life is too short to avoid asking questions |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 07, 2007 3:19 pm |
|
|
I have already looked at the errata sheet for the 16F886 and didn't see
anything. The only difference in the SSP module is a Slave address
mask register, but the data sheet says it's in a benign state upon
power-up. (This should be checked. It may not be the case).
The next thing to do is:
1. Compare the data sheets between the 16F876 and the 16F886 and
look for any differences in the SSP module, regarding i2c. I think they
are supposed to be compatible (other than the mask register).
2. Then compile your code for both the 16F886 and the 16F876 and print
out the .LST files and compare them line-by-line, looking for any
differences. |
|
|
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
Differences |
Posted: Tue Aug 07, 2007 6:20 pm |
|
|
I have checked out the two list files and printed the program memory files as symbols. The files seem the same so far. In particular the SSPBUF on the 876 = 0x36 and the SSPCON on the 886 = 0x36.
This sets up I2c Slave mode, 7bit address.
Out of curiosity I programmed an 18F252 with the same slave code using another address. I now have the 876 and the 252 on the buss talking to the Master.
I will keep at it.
Cheers
Mark _________________ Life is too short to avoid asking questions |
|
|
Mark Weir
Joined: 11 Sep 2003 Posts: 51 Location: New Zealand
|
#use I2C |
Posted: Tue Aug 07, 2007 9:07 pm |
|
|
If I remove the word " slave " from the #use I2c function the bus is allowed to go high and if i use " master " the bus still tries to work but I guess it competes with the real master so locks things up.
How do we get to see what the word " slave " is actually doing?
Cheers
Mark _________________ Life is too short to avoid asking questions |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 07, 2007 11:20 pm |
|
|
Here's something to try.
The PICs in this series 16F685/687/689/690 have an errata on the
SSP module. It might affect other PICs. It might affect the operation
of the Slave mode.
http://ww1.microchip.com/downloads/en/devicedoc/80243D.pdf
The errata describes a fix, which I've implemented in the routine below.
The compiler puts in start-up code at the beginning of main() that
enables Slave mode by writing to the SSPCON register. The bug fix
assumes that the SSPCON is in the reset state (cleared), so the first
thing I do is to put it back in that state. Then I do the bug fix.
Try it. It might work.
Code: |
void SSP_bugfix(void)
{
#byte SSPCON = 0x14 // Address for 16F887
SSPCON = 0x00; // Put SSPCON in power-on-reset state
delay_cycles(10);
SSPCON = 0x39; // Enable SSP in SSPMSK mode
SSPCON = 0x36; // Enable SSP in i2c Slave mode
}
//==============================
void main ()
{
setup_adc_ports(sAN0|VSS_VDD);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
SSP_bugfix(); // *** ADD THIS LINE
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
|
|
|
|
|