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 Theoretical Idea Problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
[email protected]



Joined: 07 Feb 2012
Posts: 19
Location: pakistan

View user's profile Send private message Send e-mail Yahoo Messenger

I2c Theoretical Idea Problem
PostPosted: Thu Feb 23, 2012 6:05 am     Reply with quote

I'm trying to communicate two pics 18f452 via I2c. I successfully achieve it after a lot of time with hit and trial method even i read about it allot.

Problem is transaction from master to slave & Slave to master Addressing:

In literature I read first byte, you write it as combination of address and least significant bit you which specify, to show your direction from master to slave or slave to master:

May master code is this:
This tell us slave address is 0x60 and adding least significant bit 1 (high) tell us master is writing and slave is reading. Slave address we specify should be 0x60
But with this it is not working.
When I use use slave code which i posted down below in which i specify 0xc0, it works, so it does not fulfill the condition of literature.
Code:

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x60)


Code:

#include <18F452.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3,address=0x60)

void main ()
{

 while(1)
{
 i2c_start();
 i2c_write(0xc0);
 delay_ms(1000);
 i2c_write(0x2);
 output_a(0x2);
 delay_ms(1000);
 i2c_write(0x3);
 output_a(0x3);
 delay_ms(1000);
 i2c_write(0x4);
 output_a(0x4);
 delay_ms(1000);
 i2c_write(0x5);
 output_a(0x5);
 delay_ms(1000);
 i2c_stop();
}
}

Slave:
Code:

#include <18F452.h> //  #include <18F458.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xC0)
 BYTE datar; 
   
 #INT_SSP   
 void ssp_interupt ()   
 {   
    BYTE  state;   

      //printf("*/n");
      state = i2c_isr_state();    //0 - Address match received with R/W bit clear

                                  //1-0x7F - Master has written data; i2c_read() will immediately return the data
 
                                  //0x80 - Address match received with R/W bit set; respond with i2c_write()

                                  //0x81-0xFF - Transmission completed and acknowledged; respond with i2c_write()

      if(state == 0x00)
         {
          datar=i2c_read();
          //printf("Adress match:%x\n",datar);
          output_a(datar);
        }
      else if(state > 0 && state < 0x80)
        {
         datar= i2c_read();
         //printf("Bytes:%x\n",datar);
        //datar=0x00;
        output_a(datar);
        }
      else if(state == 0x80)
        {
         i2c_write(dataw);
          //printf("Data write on Master:%x\n",dataw);
       }
      else if(state > 0x80 && state < 0x100)
        {
        //printf("Data has been acknowledged\n");
       }
   
 }   
   
 void main ()   
 { 
    //port_b_pullups(TRUE); 
    enable_interrupts(GLOBAL);   
    enable_interrupts(INT_SSP);   
   
    while (TRUE) {}   
 }


Rolling Eyes Rolling Eyes Rolling Eyes Exclamation Question Crying or Very sad
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 23, 2012 7:45 am     Reply with quote

just some quick comments.

1) You should think of the least significant bit as how the MASTER deals with 'data'. The Master either reads from or writes to a SLAVE. The MASTER is in control, not the slave.

2) In your master program, while you specify the address of the slave to be 0x60, you don't use the variable 'address' when communicating to the slave. You use....

i2c_start();
i2c_write(0xc0);

And the 0xc0 is the I2C address that you are writing( communicating) to.


you should try....

i2c_write(address); and see what happens...
Ttelmah



Joined: 11 Mar 2010
Posts: 19497

View user's profile Send private message

PostPosted: Thu Feb 23, 2012 10:34 am     Reply with quote

If you look again, his slave is address 0xC0.
However he is specifying an address for the master. _Master devices don't have an address_. This needs to be removed.
I think he is confusing the LSb with the MSb.

Then get rid of the delays. These _will_ cause problems.

Then look again at what happens with state=0x80. This particular state _requires_ you to first read the byte from the I2C register, and then write the data you want to send back. You get here when the address is _received_ for an I2C read by the master. Not reading the byte will mean the bus is not released.

Then there is a problem with the final test. A byte can never be 0x100 (8 bits only). so the test must be:

else if(state > 0x80)

You have already tested for all lower state values...
and, this _must_ write a byte.

If you want to delay, then _stop_, delay, and start again. So:

Code:

#include <18F452.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3)
#define READ_ADDRESS 0x61
#define WRITE_ADDRESS 0x60

void main (void) {
   int8 ctr, dummy;
   while(1) {
       //Write four bytes at 1 second intervals
       for (ctr=2;ctr<5;ctr++) {
          i2c_start();
          i2c_write(WRITE_ADDRESS);
          i2c_write(ctr);
          i2c_stop();
          output_a(ctr);
          delay_ms(1000);
       }
       //Now read four bytes at 1 second intervals - get back ctr*2
       for (ctr=2;ctr<5;ctr++) {
          i2c_start();
          i2c_write(WRITE_ADDRESS);
          i2c_write(ctr); //send ctr to slave
          i2c_write(READ_ADDRESS); //This is an I2C _restart_ used to change
          //bus direction so you can _write_ a register number to retrieve
          //and then read back the contents
          dummy=i2c_read(); //get reply from slave
          i2c_stop();
          output_a(dummy);
          delay_ms(1000);
       }
   }
}

Slave:

#include <18F452.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x60)

BYTE datar;

#INT_SSP   
void ssp_interupt (void) {   
    BYTE  state; 
    static int8 reg_num_sent;
    int8 dummy;
    state = i2c_isr_state();

    if (state == 0x00) {
       //Here _address_ has been received, not data.
       dummy=i2c_read();
       }
    else if(state > 0 && state < 0x80) {
       datar= i2c_read();
       output_a(datar);
       //First data byte received is normally used as the 'register address'
       //to say what you want to read/write back
       if (state==1) reg_num_sent=datar;
    }
    else if(state == 0x80) {
       dummy=i2c_read();
       i2c_write(reg_num_sent*2);
    }
    else if(state > 0x80) {
       i2c_write(reg_num_sent*2);
    }
}   
   
void main (void) {

    enable_interrupts(GLOBAL);   
    enable_interrupts(INT_SSP);   
   
    while (TRUE) {}   



Best Wishes
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 23, 2012 10:44 am     Reply with quote

hmmm.. I thought the 'address' definition meant the default address of the slave he would talk to.
Easy to get confused when you cut your own drivers and think everyone else does what you do...
Ttelmah



Joined: 11 Mar 2010
Posts: 19497

View user's profile Send private message

PostPosted: Thu Feb 23, 2012 3:20 pm     Reply with quote

Yes. Having 'address' at the start of the master code had me confused as well. Then 'twigged' what was going on. As I say confusing the MSb with LSb, so he is trying to use 0x60, and 0xC0 for read/write.... :(
Aargh!.

Best Wishes
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