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

I2C master - slave communication

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



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

I2C master - slave communication
PostPosted: Sun Jul 04, 2010 1:07 pm     Reply with quote

Hi all!

I'm trying to communicating between two PIC's with I2C protocol and I'm having troubles...

Circuit is simple as it is could be. Two PIC16F886 each have LCD connected on portB, SCL and SDA are connected together and 4k7 pullup resistors are on them. This is it. Hardware is actually put together on protoboard.

Code for slave is taken out from EX code and modified a little. Everything stops at master i2c_stop() command at the end of code. If I disconnect slave then master go over that point. I was looking what happens with oscilloscope and SDA line stays low at that point of program.

Here is code
MASTER:
Code:
#include <16F886.h>

#FUSES NOWDT,INTRC_IO,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO                 
#FUSES NOFCMEN,NOLVP,NODEBUG,NOWRT,BORV40   

#use delay(clock=8000000)
#define I2C_SCL   PIN_C3
#define I2C_SDA   PIN_C4
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors)

#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)

#include "flex_lcd.c"

void setup()
{

   setup_adc_ports(NO_ANALOGS|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(false);
   setup_oscillator(OSC_8MHZ);

   lcd_init();
}


void main()
{
int8 data,t;

   setup();
 
   lcd_putc("Start...  \n");
   
   while (1)
   {
     delay_ms(500);
   
   i2c_start();
   i2c_write(0xA0);
   i2c_write(0x00);
   i2c_write('A');
   i2c_stop();
   
   delay_ms(1);   
   
   i2c_start();
   i2c_write(0xA0);
   i2c_write(0x00);   
   i2c_start();   
   i2c_write(0xA1);   
   data=i2c_read();   
   i2c_stop(); //<--- IT STOPS HERE!!!

   printf(lcd_putc," Read: %u \n",data);
   }
   
}


SLAVE:
Code:
#include <16F886.h>

#FUSES NOWDT,INTRC_IO,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO                 
#FUSES NOFCMEN,NOLVP,NODEBUG,NOWRT,BORV40                 

#use delay(clock=8000000)
#use i2c(Slave,Slow,sda=PIN_C4,scl=PIN_C3,force_hw,address=0xA0)

#include "flex_lcd.c"

byte address, buffer[0x10];
BYTE incoming, state, ping;

#int_SSP
void  SSP_isr(void)
{
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]);
      ping=1;
   }
}



void setup()
{
   setup_adc_ports(NO_ANALOGS|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(INT_SSP);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_8MHZ);

   lcd_init();
   
   ping=0;
}


void main()
{
   int t;
   
   setup();
   
   Printf(lcd_putc,"Ready ...\n");
   
   while(1)
   {
      if (ping==1)
      {
         lcd_putc('.');
         ping=0;
      }
   }
}


Please can somebody give me a fresh perspective, I'm stuck in a loop Rolling Eyes thank's!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 04, 2010 1:26 pm     Reply with quote

Quote:

i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_start();
i2c_write(0xA1);
data=i2c_read();
i2c_stop(); //<--- IT STOPS HERE!!!

You have to do a NACK on the last read. This is in the i2c spec.
Do this by giving the i2c_read() function a 0x00 parameter.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Sun Jul 04, 2010 1:39 pm     Reply with quote

I bow to the master!
Thank you ... as I said I was caught in a loop.

Do you have a good title to read about I2C spec?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 04, 2010 1:51 pm     Reply with quote

Here's the i2c spec.
http://www.nxp.com/acrobat_download2/literature/9398/39340011.pdf
The part about the Master doing a NACK on the last byte to be read
is in the last paragraph on page 10.

I just noticed that Philips came up with a more easy-to-read version
of the i2c spec:
http://www.nxp.com/documents/user_manual/UM10204.pdf
In that one, the NACK is explained in item #5 on page 10.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Sun Jul 04, 2010 4:22 pm     Reply with quote

Thank you for that and rapid response! Cool
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