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 with 3 pic

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



Joined: 21 Apr 2010
Posts: 6
Location: earth, solar system

View user's profile Send private message

i2c with 3 pic
PostPosted: Wed Apr 21, 2010 9:04 am     Reply with quote

Hi,
I did a circuit with 3 pic (master is a 18F2550, one slave is a 18F2680 and another slave is a 18F2550), and I want to connect them using i2c

I don't know why but slaves don't answer to master request

If I modify the master to communicate with just one slave, it answers as expected.

I saw something similar here, but I don't know how to export the solution to my programs


programs are very simple; master send 2 bytes to each slave, 1st slave return the sum of these bytes plus 1, and 2nd slave return the sum of these bytes minus 1

here are my codes:

master.c
Code:
#include <18F2680.h>
#fuses NOMCLR,INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOWRT,NOWRTD,PUT,STVREN,NODEBUG,NOWRTB
#use delay(clock=16000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(fast, Master, sda=PIN_C4, scl=PIN_C3)

int data_in1 = 0;
int data_in2 = 0;

int data_out1 = 0;
int data_out2 = 16;

void main()
{
    setup_oscillator(OSC_16MHZ);
    SETUP_ADC(ADC_OFF);
    SETUP_ADC_PORTS(NO_ANALOGS);

    delay_ms(10);

    while(TRUE)
    {
        delay_ms(100);
        printf("\r\n-");
       
        i2c_start ();
        i2c_write (0x30);
        i2c_write (data_out1);
        i2c_write (data_out2);
        i2c_stop();
       
        i2c_start ();
        i2c_write (0x31);
        data_in1=i2c_read(0);
        i2c_stop ();
       
        delay_ms(1);
       
        i2c_start ();
        i2c_write (0x40);
        i2c_write (data_out1);
        i2c_write (data_out2);
        i2c_stop();
       
        i2c_start ();
        i2c_write (0x41);
        data_in2=i2c_read(0);
        i2c_stop ();
       
        printf("to 0x30:0x%X,0x%X - from 0x31: 0x%X,0x%X", data_out1, data_out2, data_in1, data_in2);
       
        ++data_out1;
        ++data_out2;
    }
}


slave1.c
Code:

#include <18F2550.h>
#fuses NOMCLR,INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOWRT,NOWRTD,PUT,STVREN,NODEBUG,NOWRTB
#use delay(clock=16000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(fast, Slave, SDA=PIN_b0, SCL=PIN_b1, address=0x30)

int data=0;
int i2c_state;


#INT_SSP
void ssp_interupt ()
{
    i2c_state = i2c_isr_state();
    if(i2c_state < 0x80)
    {
        if(i2c_state == 0)
            i2c_read();

        if(i2c_state == 1)
            data = i2c_read();
           
        if(i2c_state == 2)
            data += i2c_read();
    }
    else
    //if(i2c_state >= 0x80)
    {
        data++;
        if(i2c_state == 0x80)
        {
            i2c_write(data);
        }
       
    }
}

void main()
{
    setup_oscillator(OSC_16MHZ);
    setup_adc(ADC_OFF);
    setup_adc_ports(NO_ANALOGS);
   
    enable_interrupts(INT_SSP);
    enable_interrupts(GLOBAL);
   
   
    delay_ms(10);
   
    while(TRUE)
    {
    }
}


slave2.c
Code:

#include <18F2550.h>
#fuses NOMCLR,INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOWRT,NOWRTD,PUT,STVREN,NODEBUG,NOWRTB
#use delay(clock=16000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(fast, Slave, SDA=PIN_b0, SCL=PIN_b1, address=0x40)

int data=0;
int i2c_state;


#INT_SSP
void ssp_interupt ()
{
    i2c_state = i2c_isr_state();
    if(i2c_state < 0x80)
    {
        if(i2c_state == 0)
            i2c_read();

        if(i2c_state == 1)
            data = i2c_read();
           
        if(i2c_state == 2)
            data += i2c_read();
    }
    else
    //if(i2c_state >= 0x80)
    {
        data--;
        if(i2c_state == 0x80)
        {
            i2c_write(data);
        }
       
    }
}

void main()
{
    setup_oscillator(OSC_16MHZ);
    setup_adc(ADC_OFF);
    setup_adc_ports(NO_ANALOGS);
   
    enable_interrupts(INT_SSP);
    enable_interrupts(GLOBAL);
   
   
    delay_ms(10);
   
    while(TRUE)
    {
    }
}



Last edited by 01011 on Wed Apr 21, 2010 2:36 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 21, 2010 11:27 am     Reply with quote

Quote:
// talk with first slave
i2c_start ();
i2c_start ();

You are doing two 'starts' at the beginning of each sequence. That's not
part of the i2c protocol. There is only supposed to be one 'start'.


Quote:
if(i2c_state < 0x80)
{
if(i2c_state == 0)
i2c_read(0);

if(i2c_state == 1)
data = i2c_read(0);

if(i2c_state == 2)
data += i2c_read(0);

Here you are giving the i2c_read() function a parameter of 0, while inside
the #int_ssp interrupt routine. CCS never does this in any example.
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed Apr 21, 2010 11:36 am     Reply with quote

Quote:
data += i2c_read(0);

As PCM programmer has pointed out, you don't need to have the '0' parameter in this i2c_read() command. The place a '0' does belong is in the Master routine. You place the '0' in the i2c_read command so that the master can tell the slave that the master is finished reading data from the slave.

I might suggest you place a slave in your circuit, one at a time, and make sure you can talk to each of them, separately. Then, try adding both slaves to the circuit. Also, make sure your master is not sending commands too fast. Each slave needs a certain amount of time to respond to each command, fetch whatever data you're requesting and then send it back out to the bus for the master to receive.

Ronald
01011



Joined: 21 Apr 2010
Posts: 6
Location: earth, solar system

View user's profile Send private message

PostPosted: Wed Apr 21, 2010 2:46 pm     Reply with quote

Sorry for these 2 mistakes, I was trying some codes and I posted the wrong programs.

I've edited my 1st post to correct these mistakes (I use fast i2c, in slave I use i2c_read(), and there is no double start condition).

But my circuit still not work.

When I modify the main loop of master.c as below:
Code:
while(TRUE)
    {
        delay_ms(100);
        printf("\r\n-");
       
        i2c_start ();
        i2c_write (0x30);
        i2c_write (data_out1);
        i2c_write (data_out2);
        i2c_stop();
       
        i2c_start ();
        i2c_write (0x31);
        data_in1=i2c_read(0);
        i2c_stop ();
       
        delay_ms(1);
       
        printf("to 0x30:0x%X,0x%X - from 0x31: 0x%X,0x%X", data_out1, data_out2, data_in1, data_in2);
       
        ++data_out1;
        ++data_out2;
    }

the program work correctly, (i.e. when communicating with just one slave, there is no problem).

But when my master try to communicate with 2 slave, that is what happens:

- 1st time it writes/reads in/from 0x30/0x31, I notice no problem.
- Then, when it tries for the first time to write/read in/from 0x40/0x41, slave interrupts don't happen.
- After that, neither 0x30/0x31 nor 0x40/0x41 answer to any request.


why?
01011



Joined: 21 Apr 2010
Posts: 6
Location: earth, solar system

View user's profile Send private message

PostPosted: Mon Apr 26, 2010 5:13 am     Reply with quote

hi,

no one has an idea? Crying or Very sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 26, 2010 12:23 pm     Reply with quote

Your test programs are too complicated. You're using i2c FAST mode,
which may not work with a slave. You need to simplify it and strip it
down.

Try the test program shown in this post. Create a 2nd slave. Put it at
address 0x14. See if you can make it work:
http://www.ccsinfo.com/forum/viewtopic.php?t=39242&start=6

Note how, farther along in that thread, he was able to use that code
and make a multi-slave i2c system that worked. It's a 2-page thread.
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