View previous topic :: View next topic |
Author |
Message |
ElectricalNoob
Joined: 17 May 2007 Posts: 15
|
I2C Question - What am I doing wrong? |
Posted: Thu Jun 14, 2007 9:39 am |
|
|
I'm trying to setup I2C communication between two PIC16F877As. I have two 20Mhz external clocks one for each of the two pics which I connected to the OSC1/CLKI pin on each of the pics. I connected two 4.7k resisters to a 5V supply and to the RC3 and RC4 pins on one of the pics. Then I connected the RC3 of one pic to the RC3 of the other and the RC4 pins of one of the pics to the RC4 of the other. I connected the master pic to a max232 chip and I tested the rs232 communication. rs232 worked fine. Everything is connected to the same 5V regulator and the same ground. I believe everything is connected properly. Do I have to do something special with the clocks?
In my next step I programmed the slave pic with the Slave.c code. Then for the master pic I used PCM Programmers code which I modified slightly. Changed clock from 4Mhz to 20Mhz. Made 877.h to 877A.h. Also used default fuses. I will list the master and slave code below. After programming I applied power to the circuit and looked at hyperterminal. In hyperterminal I got "read" to display.
What am I doing wrong?
MASTER CODE:
Code: |
#include <16F877A.H>
//#fuses XT, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
//====================================
void main()
{
int8 data;
// Write the letter 'B' to the slave board.
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_write('B');
i2c_stop();
// Read from the slave board and display the data.
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_start();
i2c_write(0xA1);
data = i2c_read(0);
i2c_stop();
printf("read %c \n\r", data);
while(1);
}
|
SLAVE CODE:
Code: |
#include <16F877A.h>
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, 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 ()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (TRUE) {}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 14, 2007 10:46 am |
|
|
Quote: | Also used default fuses |
Post the #fuses statements for both programs.
Also post your compiler version. |
|
|
ElectricalNoob
Joined: 17 May 2007 Posts: 15
|
|
Posted: Thu Jun 14, 2007 12:23 pm |
|
|
Compiler version is 4.016
The configuration I'm using is
Oscillator - RC
Watchdog timer - off
Power up timer - on
brown out detect - on
low voltage program - disabled
flash program write - write protection off
data ee read protect - off
code protect - off |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 14, 2007 12:45 pm |
|
|
Quote: |
I have two 20Mhz external clocks one for each of the two pics
which I connected to the OSC1/CLKI pin on each of the pics.
Oscillator - RC
Watchdog timer - off
Power up timer - on
brown out detect - on
low voltage program - disabled
flash program write - write protection off
data ee read protect - off
code protect - off
|
Read this section in the 16F877A data sheet:
Quote: | 14.2 Oscillator Configurations |
Find out the correct oscillator fuse setting to use for your configuration.
Look in the list of available fuse settings at the start of the 16F877A.H
file. Then pick the correct setting. (for both your PIC programs) |
|
|
ElectricalNoob
Joined: 17 May 2007 Posts: 15
|
|
Posted: Thu Jun 14, 2007 9:44 pm |
|
|
I've looked into configuration bits before, but when I used the fuses you used, it would not work. According to the datasheet 20Mhz external is HS. However I tried changing my configuration bits to use HS and again I had the same problem. It would display read, and nothing else after. I've always been puzzled by the fact that with RC it would work, even though I was using an external ocillator. So I never really thought much of it before. It is only with this I2C code that I have trouble with. It's really frustrating. However as I was writing this email I did try another thing.
I modified the fuse in your master code and the slave code to be:
#fuses HS,NOWDT,NOPROTECT
After doing this it worked. Thanks again for the suggestion. I don't know why, but I keep having trouble with the little things. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 14, 2007 10:16 pm |
|
|
You should add NOLVP to that. |
|
|
ElectricalNoob
Joined: 17 May 2007 Posts: 15
|
|
Posted: Thu Jun 14, 2007 11:14 pm |
|
|
Thanks PCM programmer |
|
|
|