CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Need help with simple I2C communications

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
corbico



Joined: 23 Jan 2007
Posts: 3

View user's profile Send private message

Need help with simple I2C communications
PostPosted: Mon May 21, 2007 8:19 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 22, 2007 12:42 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 22, 2007 8:24 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 22, 2007 1:07 pm     Reply with quote

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

View user's profile Send private message

Thanks
PostPosted: Tue May 22, 2007 7:16 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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