|
|
View previous topic :: View next topic |
Author |
Message |
corbico
Joined: 23 Jan 2007 Posts: 3
|
Need help with simple I2C communications |
Posted: Mon May 21, 2007 8:19 pm |
|
|
I am attempting to communicate between two processors using i2c, but having a problem. In the following code I simply want to send a byte of data from the master to the slave and back again. The master transmits, the slave reads and displays the data via rs232 but there is no data on the bus back to the master. What am I doing wrong??
Master code:
Code: |
#include <18F8722.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40M, oscillator=10M)
#define SCL1 PIN_C3
#define SDA1 PIN_C4
#use I2C(master, sda=SDA1, scl=SCL1)
int8 cmd, data;
#zero_ram
#include <input.c>
void main(void)
{
printf("\r\nCompiled, %s %s\r\n", __DATE__, __TIME__);
while(true) {
do {
cmd=getc();
cmd=toupper(cmd);
putc(cmd);
} while (cmd!='V');
if(cmd=='V'){
i2c_start();
i2c_write(0x16);
delay_us(5);
data=i2c_read(0);
i2c_stop();
printf("\r\ndata = %X\r\n", data );
}
}
}
|
Slave code:
Code: |
#include <18F8722.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40M, oscillator=10M)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
#use I2C(slave, sda=PIN_C4, scl=PIN_C3, address=0X16, FORCE_HW)
int8 new_byte,data;
#zero_ram
#include <input.c>
#INT_SSP
void isr() {
disable_interrupts(INT_SSP);
disable_interrupts(GLOBAL);
clear_interrupt(INT_SSP);
data = i2c_read();
i2c_write(data);
new_byte =1;
}
void main(void)
{
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(true){
if(new_byte){
printf("\r\ndata = %X\r\n", data );
new_byte=0;
}
}
}
|
Thanks for any help. |
|
|
Fabri
Joined: 22 Aug 2005 Posts: 275
|
|
Posted: Tue May 22, 2007 12:42 am |
|
|
Hi,
You have to introduce an i2c comunication protocoll between master and slave. Take a look to ex_slave.c example just to understand how i2c slave must work.
Regards,
Fabri |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue May 22, 2007 8:24 am |
|
|
You might want to look at how an I2C part communicates. An eeprom (24LC256) comes to mind. Examine how it requires a certain sequence of commands in order transfer data.
First, you need to have the Master tell whatever I2C Slaves, that are attached to the bus, that it wants to 'talk' to somebody. Next, the Master needs to transmit the address of the Slave device it wants to talk to. If the Master will be 'writing' data to the Slave then the eighth bit, in the control word, needs to be a '0'. This will tell the Slave that it needs to accept data from the Master. This data could be an internal address or some other command for the Slave.
If the Master will be 'reading' data from the Slave then the eighth bit, of the control byte, needs to be a '1'. This tells the Slave that it will be transmitting data to the Master.
The eight bit is very important in which direction data will be traveling. You need to make a sequence similar to this:
i2c_start();// gets i2c bus attention
i2c_write(0x16);// address of slave, write mode
i2c_write(data);// write some kind of data to the slave
i2c_start();// restart command sequence
i2c_write(0x17);// address of slave, read mode
data = i2c_read(0);// read data and send a NOACK
i2c_stop();
Your Slave code should be made to accomodate this sort of sequence. Search this forum for examples. A scope is very helpful in seeing what the bus is doing too.
Also, it's not a good idea to be trying to disable interrupts inside of an interrupt routine. In your code you've disabled the global flag and never enable it again.
Clear as mud now?
Ronald
_______________
Never open up a can of worms, unless you're going _fishing. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 22, 2007 1:07 pm |
|
|
Start by programming your Slave PIC with the CCS example code
in Ex_Slave.c. It's in this directory:
c:\Program Files\Picc\Examples
Then use the sample code shown in this post for your Master PIC.
http://www.ccsinfo.com/forum/viewtopic.php?t=28097&start=9
That should work, and it will prove if your hardware is OK (ie., it has
pull-ups on the SDA and SCL lines, and a ground connection between
the two boards).
Don't try to use the 4x PLL oscillator in your initial test program.
Just run it at 10 MHz. Also, use the latest version of the compiler
or use vs. 3.249. |
|
|
corbico
Joined: 23 Jan 2007 Posts: 3
|
Thanks |
Posted: Tue May 22, 2007 7:16 pm |
|
|
Thanks to all for the info. With your help I was able to get the master / slave communications working as well as communicating with a battery pack on the smbus. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|