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

PIC18F4550 master and DSPIC30F4011 slave i2c problem

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



Joined: 08 Feb 2011
Posts: 14

View user's profile Send private message

PIC18F4550 master and DSPIC30F4011 slave i2c problem
PostPosted: Mon Feb 20, 2012 1:46 am     Reply with quote

hi,
I have a project that requires I2C communication between one master (PIC18F4550) and three slave (two PIC18F4550 and one DSPIC30F4011) but the I2C communication does not work. The SCL pin is always 5V and the SDA pin is always 0V.

I tried to run with just the master and one DSPIC30F4011 but it did not work. I also tried changing the DSPIC slave i2c address to 0x52, 0x42, 0x60, 0x62 and 0x12 but none of them worked.

When I run it with only the PIC18F4550 master and two PIC18F4550 slaves over I2C, data is transmitted and received perfectly.

I have attached my coding.

MASTER

Code:


#include <18F4550.h>
#FUSES HSPLL, NOWDT, NOPROTECT, NOBROWNOUT, STVREN, MCLR ,PLL5,CPUDIV1

#use delay(crystal=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7, bits=8,stream=PORT1)
#use i2c(MASTER,sda=PIN_B0,scl=PIN_B1,force_hw,slow)

unsigned int8 send_usb_data[18],val;

void main()
{
   
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED|T1_DIV_BY_4);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);

   while(1)
   {   
      // Write to the slave 1 board.(PIC18F4550)
      i2c_start();
      i2c_write(0x14);
      i2c_write('A');
      i2c_write('B');
      i2c_write('C');
      i2c_write('D');
      i2c_write('E');
      i2c_write('F');
      i2c_stop();

      // Read from the slave 2 board.

      i2c_start();
      i2c_write(0x15);
      delay_us(10);
      send_usb_data[0] = i2c_read();
      send_usb_data[1] = i2c_read();
      send_usb_data[2] = i2c_read();
      send_usb_data[3] = i2c_read();
      send_usb_data[4] = i2c_read();
      send_usb_data[5] = i2c_read(0);
      i2c_stop();

      // Write to slave 2 board.(PIC18F4550)
      i2c_start();
      i2c_write(0x28);
      i2c_write('G');
      i2c_write('H');
      i2c_write('I');
      i2c_write('J');
      i2c_write('K');
      i2c_write('L');
      i2c_stop();

      // Read from the slave 2 board and display the data.
      i2c_start();
      i2c_write(0x29);
      delay_us(10);
      send_usb_data[6] = i2c_read();
      send_usb_data[7] = i2c_read();
      send_usb_data[8] = i2c_read();
      send_usb_data[9] = i2c_read();
      send_usb_data[10] = i2c_read();
      send_usb_data[11] = i2c_read(0);
      i2c_stop();

      // Write to slave 3 board.(DSPIC30F4011)
      i2c_start();
      i2c_write(0x60);
      i2c_write('m');
      i2c_write('n');
      i2c_write('o');
      i2c_write('p');
      i2c_write('q');
      i2c_write('r');
      i2c_stop();

      // Read from the slave 3 board and display the data.
      i2c_start();
      i2c_write(0x61);
      delay_us(10);
      send_usb_data[12] = i2c_read();
      send_usb_data[13] = i2c_read();
      send_usb_data[14] = i2c_read();
      send_usb_data[15] = i2c_read();
      send_usb_data[16] = i2c_read();
      send_usb_data[17] = i2c_read(0);
      i2c_stop();

      for (val=0;val<18;val++)
      {
             fputc(send_usb_data[val], PORT1);
             send_usb_data[val]=0;
      }

         
   }
}



SLAVE 1 (PIC18F4550)

Code:


#include <18F4550.h>
#FUSES HSPLL, NOWDT, NOPROTECT, NOBROWNOUT, STVREN, MCLR ,PLL5,CPUDIV1
#use delay(crystal=20000000)
#use i2c(SLAVE,sda=PIN_B0,scl=PIN_B1,address=0x14,force_hw)

unsigned int8 send_usb_data[6];

#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) send_usb_data[0] = incoming;
      if(state == 2) send_usb_data[1] = incoming;                       
      if(state == 3) send_usb_data[2] = incoming;                   
      if(state == 4) send_usb_data[3] = incoming;
      if(state == 5) send_usb_data[4] = incoming;                       
      if(state == 6) send_usb_data[5] = incoming;           
   }
   if(state >= 0x80)                     //Master is requesting data
   {
      if(state == 0x80)
      {
         i2c_read();
         i2c_write(send_usb_data[0]);
      }
      if(state == 0x81) i2c_write(send_usb_data[1]);
      if(state == 0x82) i2c_write(send_usb_data[2]);
      if(state == 0x83) i2c_write(send_usb_data[3]);
      if(state == 0x84) i2c_write(send_usb_data[4]);
      if(state == 0x85) i2c_write(send_usb_data[5]);       
   }
}


void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED|T1_DIV_BY_4);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_SSP);      //enable I2C interrupts
   enable_interrupts(GLOBAL);

   while(1)
   {

   }

}




SLAVE 2 (PIC18F4550)

Code:


#include <18F4550.h>
#FUSES HSPLL, NOWDT, NOPROTECT, NOBROWNOUT, STVREN, MCLR ,PLL5,CPUDIV1
#use delay(crystal=20000000)
#use i2c(SLAVE,sda=PIN_B0,scl=PIN_B1,address=0x28,force_hw)

unsigned int8 send_usb_data[6];

#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) send_usb_data[0] = incoming;
      if(state == 2) send_usb_data[1] = incoming;                       
      if(state == 3) send_usb_data[2] = incoming;                   
      if(state == 4) send_usb_data[3] = incoming;
      if(state == 5) send_usb_data[4] = incoming;                       
      if(state == 6) send_usb_data[5] = incoming;           
   }
   if(state >= 0x80)                     //Master is requesting data
   {
      if(state == 0x80)
      {
         i2c_read();
         i2c_write(send_usb_data[0]);
      }
      if(state == 0x81) i2c_write(send_usb_data[1]);
      if(state == 0x82) i2c_write(send_usb_data[2]);
      if(state == 0x83) i2c_write(send_usb_data[3]);
      if(state == 0x84) i2c_write(send_usb_data[4]);
      if(state == 0x85) i2c_write(send_usb_data[5]);       
   }
}


void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED|T1_DIV_BY_4);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_SSP);      //enable I2C interrupts
   enable_interrupts(GLOBAL);

   while(1)
   {

   }

}




SLAVE 3 (DSPIC30F4011)

Code:


#include <30F4011.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES FRC_PLL16                   
#FUSES NOCKSFSM                 
#FUSES WPSB1                 
#FUSES WPSA512                 
#FUSES NOPUT                 
#FUSES NOBROWNOUT             
#FUSES BORRES               
#FUSES LPOL_HIGH         
#FUSES HPOL_HIGH       
#FUSES NOPWMPIN                 
#FUSES MCLR                   
#FUSES NOPROTECT             
#FUSES NOWRT                   
#FUSES NODEBUG                 
//#FUSES ICSP                 

#use delay(clock=120000000)
#use i2c(SLAVE,I2C1,address=0x60,force_hw)

unsigned int8 send_usb_data[6];

#INT_SI2C
void ssp_interupt ()
{
   BYTE incoming, state;

   state = i2c_isr_state();
   
   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1) send_usb_data[0] = incoming;
      if(state == 2) send_usb_data[1] = incoming;                       
      if(state == 3) send_usb_data[2] = incoming;                   
      if(state == 4) send_usb_data[3] = incoming;
      if(state == 5) send_usb_data[4] = incoming;                       
      if(state == 6) send_usb_data[5] = incoming;           
   }

   if(state >= 0x80)                     //Master is requesting data
   {
      if(state == 0x80)
      {
         i2c_read();
         i2c_write(send_usb_data[0]);
      }
      if(state == 0x81) i2c_write(send_usb_data[1]);
      if(state == 0x82) i2c_write(send_usb_data[2]);
      if(state == 0x83) i2c_write(send_usb_data[3]);
      if(state == 0x84) i2c_write(send_usb_data[4]);
      if(state == 0x85) i2c_write(send_usb_data[5]);
   }
}

void main()
{
   setup_spi( FALSE );
   setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
   enable_interrupts(INT_SI2C);
    enable_interrupts(INTR_GLOBAL);

   while(1)
   {
   }
}




I even tried to send and receive just one byte with DSPIC but it did not work. Please help me. Thank you in advance.
mateeb4u@gmail.com



Joined: 07 Feb 2012
Posts: 19
Location: pakistan

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

just try
PostPosted: Mon Feb 20, 2012 7:05 am     Reply with quote

Look in the PIC datasheet, Figure 15-7.
What are the pins used for hardware I2C?
They are not the same pins you have defined.

In a slave you must always use the real I2C hardware. For a master it is advised to use the real hardware but sometimes when this is impossible you can have the CCS compiler generate a software emulation for you.
temtronic



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

View user's profile Send private message

PostPosted: Mon Feb 20, 2012 7:13 am     Reply with quote

and you do have the correct value pullups on the I2L bus lines right ???
neohimura



Joined: 08 Feb 2011
Posts: 14

View user's profile Send private message

Re: just try
PostPosted: Mon Feb 20, 2012 8:13 am     Reply with quote

mateeb4u@gmail.com wrote:
Look in the PIC datasheet, Figure 15-7.
What are the pins used for hardware I2C?
They are not the same pins you have defined.

In a slave you must always use the real I2C hardware. For a master it is advised to use the real hardware but sometimes when this is impossible you can have the CCS compiler generate a software emulation for you.


For PIC18F4550 i used pin number 33 (RB0) for SDA and pin number 34 (RB1) for SCL.
For DSPIC30F4011 i used pin number 26 (RF2) for SDA and pin number 25 (RF3) for SCL.
I checked the datasheet and those are the hardware I2C pins for both PIC.


temtronic wrote:
and you do have the correct value pullups on the I2L bus lines right ???


Yes. I have done pullups on SDA and SCL with 4.7kOhm resistor on each lines. Should I change the resistor value?
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Feb 20, 2012 9:23 am     Reply with quote

Unless this is just for debugging purposes, having a main() exec while loop with no statements in it and then having all the work done in the interrupt handler is ineffective programming. In these scenarios there is no need for an interrupt handler.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Mon Feb 20, 2012 10:19 am     Reply with quote

Seriously, I'd start 'basic'.
Have you verified the 4011, is running, and running at the expected speed?. A simple pin toggle function, and test the output with an LED or scope.

Then most of the latter more complex PICs do need the default stack allocation increased. Normally things like printf, use a lot (which you are not using), but even things like calling an interrupt might give problems, so worth expanding it a bit.

Then progress to the next step, and add a pin toggle function at the start of the I2C interrupt handler. Does this get toggled when you try to talk to the chip?. If not, then probabilities are:
1) An error in the initialisation of the I2C peripheral.
2) An error in the initialisation/handling of the interrupt.
If it does, then I'd be suspicious that possibly I2C_ISR_STATE which normally accesses the MSSP, is not handling the I2C peripheral correctly.

I doubt if many people have played with I2C slave operation on these chips, hence the lack of responses.

On the resistor value, at slow speed, 4.7K, ought to be 'OK', but this does depend on the total capacitance on the lines. The I2C specifications describe how to calculate the max and min values that can be used for a range of speeds capacitances, and voltages. If the slave 4550's, stopped working when the 4011 was attached, then look at this. However if the other chips still work OK, then this is not likely to be the problem.

Best Wishes
neohimura



Joined: 08 Feb 2011
Posts: 14

View user's profile Send private message

PostPosted: Tue Feb 21, 2012 2:46 pm     Reply with quote

asmallri wrote:
Unless this is just for debugging purposes, having a main() exec while loop with no statements in it and then having all the work done in the interrupt handler is ineffective programming. In these scenarios there is no need for an interrupt handler.


It is just for debugging. Smile

Ttelmah wrote:

Seriously, I'd start 'basic'.
Have you verified the 4011, is running, and running at the expected speed?. A simple pin toggle function, and test the output with an LED or scope.

Then most of the latter more complex PICs do need the default stack allocation increased. Normally things like printf, use a lot (which you are not using), but even things like calling an interrupt might give problems, so worth expanding it a bit.

Then progress to the next step, and add a pin toggle function at the start of the I2C interrupt handler. Does this get toggled when you try to talk to the chip?. If not, then probabilities are:
1) An error in the initialisation of the I2C peripheral.
2) An error in the initialisation/handling of the interrupt.
If it does, then I'd be suspicious that possibly I2C_ISR_STATE which normally accesses the MSSP, is not handling the I2C peripheral correctly.

I doubt if many people have played with I2C slave operation on these chips, hence the lack of responses.

On the resistor value, at slow speed, 4.7K, ought to be 'OK', but this does depend on the total capacitance on the lines. The I2C specifications describe how to calculate the max and min values that can be used for a range of speeds capacitances, and voltages. If the slave 4550's, stopped working when the 4011 was attached, then look at this. However if the other chips still work OK, then this is not likely to be the problem.


I tested the 4011 by toggling output with LED. It worked fine.
Ttelmah, can you please explain how I can increase the default stack allocation?
I also tested the interrupt handler with pin toggle function and LED. The LED did not toggle. It remained OFF.
I will calculate the max and min resistor value and test the circuit again.

Thank you very much for all your responses guys Smile
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