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

PIC16F18346 to PIC16F18346 I2C Communication
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 06, 2021 7:02 am     Reply with quote

Regarding the R/W bit, you're not doing it correctly. Look at the
sample code in the link below. Look at the section where it reads
from the slave board. See how it does it:
http://www.ccsinfo.com/forum/viewtopic.php?t=32368&start=3
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Tue Jul 06, 2021 7:33 am     Reply with quote

Slave addresses are required to be even. Cannot be odd.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Tue Jul 06, 2021 11:14 pm     Reply with quote

Ttelmah wrote:
Slave addresses are required to be even. Cannot be odd.


Hi Ttelmah,

What did you mean? I dont understand.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Tue Jul 06, 2021 11:40 pm     Reply with quote

You said
Quote:

But if I change it to 0x13(00010011)


Slave addresses can _only_ be even numbers. They cannot be odd numbers.
A slave set with an address of 0x12, responds to address bytes of both 0x12,
and 0x13. The actual 'slave address', is the upper 7 bits of the byte sent.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Wed Jul 07, 2021 12:18 am     Reply with quote

Ttelmah wrote:
You said
Quote:

But if I change it to 0x13(00010011)


Slave addresses can _only_ be even numbers. They cannot be odd numbers.
A slave set with an address of 0x12, responds to address bytes of both 0x12,
and 0x13. The actual 'slave address;, is the upper 7 bits of the byte sent.


Hii Ttelmah,
I didnt want to say to change the slave address as 0x13. When the slave address is 0x12 and I want to send data from the master and send 0x12 as address+r/w from the master, I can send data from the master and read from the slave. 0x12 is 00010010. When I send 0x12 from the master, isn't it the slave address information from the 7th bit to the 1st bit (0001001), and the r/w bit if the 0th bit (0) is? Isn't it necessary to give a write command (1) before sending data from the master? When I send 0x13 as address+r/w from the master, the write command must be given, the last bit is 1. Why can I send data at 0x12 and not 0x13?
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Wed Jul 07, 2021 2:00 am     Reply with quote

PCM programmer wrote:
Regarding the R/W bit, you're not doing it correctly. Look at the
sample code in the link below. Look at the section where it reads
from the slave board. See how it does it:
http://www.ccsinfo.com/forum/viewtopic.php?t=32368&start=3


Hi PCM programmer,

I did some changes in my code as the link you sent. I can send data from master and slave read correctly. But when master sent to slave request data order, master didnt read correctly. Slave sent 4, master read 0x26. Why?

When I debugged in the slave code, I've seen it never go inside if(state==0x80).

Code:

#include <16F18346.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT

#define Slave_Read   0x12
#define Slave_Write   0x13

/* Delay for 4 mhz crystal */
#use delay(clock = 24MHz)

/* Setup I2C */
#pin_select SCL1OUT = PIN_C3
#pin_select SCL1IN  = PIN_C3

#pin_select SDA1OUT = PIN_C6
#pin_select SDA1IN  = PIN_C6

#use I2C(MASTER, I2C1, SLOW)

main()
{
   int8 OKU;
   setup_oscillator(OSC_HFINTRC_24MHZ,OSC_CLK_DIV_BY_16);
   set_analog_pins();
   int8 i2c_command = 66;
   
   while (true)
   {
      OKU=0;
      
        i2c_start();      // Start condition
        i2c_write(0x12);   // Device address
      i2c_write(0x00);
        i2c_write(4);   // Write Command
        i2c_stop();      // Stop condition
        delay_ms(100);
      
      output_toggle(pin_C0);

        i2c_start();
      i2c_write(0x12);   // Device address
      i2c_write(0x00);
      i2c_start();
        i2c_write(0x13);
        OKU=i2c_read(0);
        i2c_stop();
        delay_ms(100);

        if(OKU==4)
        {
            output_toggle(pin_A2);
        }

   }
}


Code:
#include <16F18346.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT


/* Setup I2C */
#pin_select SCL1OUT = PIN_C3
#pin_select SCL1IN  = PIN_C3

#pin_select SDA1OUT = PIN_C6
#pin_select SDA1IN  = PIN_C6

#use i2c(SLAVE, I2C1, address=0x12, FORCE_HW)

BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt ()
{
   int8 incoming, state;
   
   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(buffer[address] == 4)
         {
            output_toggle(pin_A2);
         }
         
      }
    }
   if(state == 0x80)  //Master is requesting data
   {
       i2c_write(buffer[address]);
   }
}


main()
{
      set_analog_pins();
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_SSP);
      while (true)
   {

   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jul 07, 2021 2:18 am     Reply with quote

OK. The problem was you referred to a slave address of 13, and this can't happen. The R/W bit is not actually part of the 'address'...

Anyway, going on to your code. The problem is how address==80 is
handled. I again refer you to the example. The point is that when you
do the read on address 0x80, you must do I2c_read(2), not the standard
read. If you do the standard read, it releases the bus, and then the slave
does not have time to load the reply.....
So:
Code:

#INT_SSP
void ssp_interupt ()
{
   int8 incoming, state;
   
   state = i2c_isr_state();
   
   if (state <= 0x80)   //Master is sending data
   {
      if (state==0x80)
         incoming = i2c_read(2); //critical - reads without releasing clock
      else
         incoming = i2c_read();
      if(state == 1)                    //First received byte is byte address
      {
         address = incoming;
      }
      if(state >= 2 && state!=0x80)    //Second received byte is data
      {
         buffer[address] = incoming;
         if(buffer[address] == 4)
         {
            output_toggle(pin_A2);
         }     
      }
    }
    if(state >= 0x80)  //Master is requesting data
    {
       i2c_write(buffer[address]);
    }
}

I've also changed it so it can handle more than one byte sent or
received. You were only handling state 2, not 3, 4, 5 etc..
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Wed Jul 07, 2021 2:49 am     Reply with quote

Ttelmah wrote:
OK. The problem was you referred to a slave address of 13, and this can't happen. The R/W bit is not actually part of the 'address'...

Anyway, going on to your code. The problem is how address==80 is
handled. I again refer you to the example. The point is that when you
do the read on address 0x80, you must do I2c_read(2), not the standard
read. If you do the standard read, it releases the bus, and then the slave
does not have time to load the reply.....

I've also changed it so it can handle more than one byte sent or
received. You were only handling state 2, not 3, 4, 5 etc..


Thanks a lot Ttelmah! It works.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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