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 works for breadboard but not on pcb

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







i2c works for breadboard but not on pcb
PostPosted: Wed Feb 17, 2010 2:02 am     Reply with quote

Hi,
I have tested I2C by sending from master to slave on both breadboard and PCB. However, it works only on the breadboard. I tried receiving from slave on the PCB too and it works. Anyone can help? Below is the code I used to send a byte from master to slave and slave will light a LED appropriately.
Also, the master needs to write to the internal register (0x00 in this case), but how do we actually identify the register? Thanks alot for the help.

Master:
Code:

#if defined(__PCH__)
#include <18F2620.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3)


#define SLAVE1_WRT_ADDR   0x12 //LSB=0
#define SLAVE1_READ_ADDR  0x13 //LSB=1

//====================================
void main()
{
int8 cmd = 0x01;

while(1)
  {
         if(cmd == 0x00)
      {
               cmd = 0x01;
          output_high(PIN_B4);
      }   
      else
      {
              cmd = 0x00;
        output_low(PIN_B4);
      }
      delay_ms(1000);
        
      i2c_start();
      i2c_write(SLAVE1_WRT_ADDR);
      i2c_write(0x00);
      i2c_write(cmd);
      i2c_stop();
  }

}


Slave:

Code:

#if defined(__PCH__)
#include <18F2620.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

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

int8 data;
BYTE address, buffer[0x10];


#INT_SSP
void ssp_interupt ()
{
   BYTE 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;
         data = incoming;
      }
      if(state == 2)                     //Second received byte is data
      {
         buffer[address] = incoming;
         //data = incoming;
      }
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
}


//======================================
void main ()
{

   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   //set_tris_c(0x01);
      
   while(1)
   {
      if (data == 0x01)
         output_high(PIN_C5);
      if (data == 0x00)
         output_low(PIN_C5);
   }

}
Ttelmah
Guest







PostPosted: Wed Feb 17, 2010 3:15 am     Reply with quote

In I2C, there are normally really two 'addresses'. The device 'address', and the register 'address'.
The standard packet for a write, is:
START
DEVICE ADDRESS
REGISTER ADDRESS
DATA to the required register....
STOP

Then for read, you use:
START
DEVICE ADDRESS (still the _write_ address)
REGISTER ADDRESS
START (this is called a 'restart')
DEVICE ADDRESS (the read one this time)
DATA from the selected register....
STOP

What is done, is you start just like a write transaction, including _writing_ the required device address, and then issue another start, followed by the command to turn the bus round to read, and the required read(s).

So in your 'master', to read back the byte you have sent:
Code:

      i2c_start();
      i2c_write(SLAVE1_WRT_ADDR);
      i2c_write(0x00); //You have now selected 'address 0' in the slave
      i2c_start(); //Issue the 'restart'
      i2c_write(SLAVE_READ_ADDR); //Say we want to read
      val=i2c_read(); //and get the data
      i2c_stop();


If you modify the slave code, so that all states, 2 and above (up to 7F) put the data into the addressed byte, and then _increment_ the address., and all ones over 80, write the byte, and then increment the address, you can perform multiple writes one after the other, sending several bytes, and do the same when reading, getting several bytes back, after the initial 'setup'.
Ideally add limit checks to 'address', so it can't accidentally go outside the data array beng used.....

Best Wishes
Ttelmah
Guest







PostPosted: Wed Feb 17, 2010 3:58 am     Reply with quote

On the breadboard versus PCB, you just need to start with standard debugging. Really careful inspection for solder whiskers, verify if the processors are working (flash an LED), and at the right rate. Then try just programming each of the lines as an input on one processor, and then setting the other to move it high/low. verify it does go up/down properly, and adjacent lines do not. You almost certainly have:
1) A whisker.
2) A break.
3) A wrong connection.....

Best Wishes
snowbell
Guest







PostPosted: Wed Feb 17, 2010 11:55 pm     Reply with quote

Thanks Ttelmah. I have tried to check all the connections, and they are correct.
The difference I realised between my breadboard and PCB is that I'm using internal oscillator at 8MHz for the breadboard and HS oscillator at 12MHz for the PCB. Indeed, when I tried 8MHz internal osc on the PCB to run I2C, it worked.
Are there any possible reasons for this besides the crystal being spoilt, as I don't have access to an oscilloscope now. Thanks.
Ttelmah
Guest







PostPosted: Thu Feb 18, 2010 3:24 am     Reply with quote

Too much capacitance round the oscillator pins. Typically ground plane too close to the oscillator tracks.
Wrong loading capacitors (typically something between 18, and 27pF would be required for most crystals).
Wrong crystal type (PIC requires a parallel resonant type).
A whisker on one of the oscillator pins.
etc.....

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