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 support@ccsinfo.com

PIC to PIC communication using i2c

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







PIC to PIC communication using i2c
PostPosted: Fri Jul 31, 2009 12:49 am     Reply with quote

Hi.
Using 2 microcontrollers, I want to make a system in which
first PIC gives instructions via i2c interface to the second PIC
and based on the instruction given, the second PIC displays data via LCD.

Thus,

1st PIC ---(1byte(for RS)+1byte(for character or instruction))-->2nd PIC---->LCD display

After getting into more complex coding, I wanted to see if I can send 2 bytes via I2c.

After reading some posts and help file, I tested following code.

First, I tried to see if I could send one byte using following code.

Master:
Code:

#include<16F886.h>
#include<def_16f886.h>
#fuses intrc_io, noprotect
#use delay(clock = 4000000)
#use i2c(master, sda = pin_c4, scl = pin_c3)

void main(void){
   osccon = 0x41;
   while(1){
      delay_ms(1000);
      i2c_start();
      i2c_write(0xa0);
      i2c_write('A');
      i2c_stop();
      }
}


Slave:
Code:

#include<16f886.h>
#include<def_16f886.h>
#use delay(clock = 4000000)
#include<flex_lcd.h>
#fuses intrc_io, noprotect, debug
#use delay(clock = 4000000)
#use i2c(slave, sda = pin_c4, scl = pin_c3, address = 0xa0)

int8 address = 0;
int8 buffer[5] = {0, 0, 0, 0, 0};
int8 incoming = 0;
int8 first_byte = 0;
int8 second_byte = 0;

int8 state = 0;
#int_ssp
void ssp_interupt ()
{
 

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read(0);

   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
   LCD_gotoxy(1,1);
   delay_ms(1);
   lcd_putc(incoming);
}
void main(void){

   enable_interrupts(int_ssp);
   enable_interrupts(global);
   osccon = 0x41;
   lcd_init();
   lcd_send_byte(0,ALL_CLEAR);
   while(1){

   }
}

Turns out, send first byte works well.

Then, I tried to send two bytes (which didn't work).

First byte I want to send is 'A' and the second byte is 'B' for simulation.

Master:
Code:

#include<16F886.h>
#include<def_16f886.h>
#fuses intrc_io, noprotect
#use delay(clock = 4000000)
#use i2c(master, sda = pin_c4, scl = pin_c3)

void main(void){
   osccon = 0x41;
   while(1){
      delay_ms(1000);
      i2c_start();
      i2c_write(0xa0);
      i2c_write('A');
      //i2c_start();          I experimented with this command.
      i2c_write('B');
      i2c_stop();
      }
}


Slave:
Code:

#include<16f886.h>
#include<def_16f886.h>
#use delay(clock = 4000000)
#include<flex_lcd.h>
#fuses intrc_io, noprotect, debug
#use delay(clock = 4000000)
#use i2c(slave, sda = pin_c4, scl = pin_c3, address = 0xa0)

int8 address = 0;
int8 buffer[5] = {0, 0, 0, 0, 0};
int8 incoming = 0;
int8 first_byte = 0;
int8 second_byte = 0;

int8 state = 0;
#int_ssp
void ssp_interupt ()
{
   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read(0);
                //First received byte is address
      if(state==0) first_byte = incoming;
      if(state==1) second_byte = incoming;

   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
   LCD_gotoxy(1,1);
   delay_ms(1);
   lcd_putc(first_byte);
   lcd_putc(second_byte);
}

void main(void){

   enable_interrupts(int_ssp);
   enable_interrupts(global);
   osccon = 0x41;
   lcd_init();
   lcd_send_byte(0,ALL_CLEAR);
   while(1){

   }
}


Frankly, I have no idea what
Code:
state = i2c_isr_state();

statement really means (the help file only specifies that for some range, it means the master said read, or the master said write).

Did I do something wrong? or did I miss anything?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

Re: PIC to PIC communication using i2c
PostPosted: Fri Jul 31, 2009 7:28 am     Reply with quote

jk726 wrote:
Frankly, I have no idea what
Code:
state = i2c_isr_state();

statement really means (the help file only specifies that for some range, it means the master said read, or the master said write).
The manual is not too bad in this respect, but one piece of information is missing: the returned state value is a 'counter'. For every byte received in this message it will count up until it resets when the next message starts.

Code:
      if(state==0) first_byte = incoming;
      if(state==1) second_byte = incoming;
If you look in the example program ex_slave.c you will see the first byte starts at state==1, not at 0.

Note that this implies a maximum message length of 0x7F bytes (excluding the address). I don't know the I2C specifications well enough to say if this limitation comes from the standard or from CCS.
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