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

speed of i2c data transfer

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







speed of i2c data transfer
PostPosted: Wed Feb 03, 2010 1:08 am     Reply with quote

Hi, may I know how fast is the data transfer from Master to Slave in I2C? In the code below, I tried to send 0x00 or 0x01 from slave to master and master will light an LED if it receives 0x01, and not light the LED if it receives 0x00. I tested the code and it works, but there is always a delay of about 10s from the time I input a high/low to pin_C0 at the slave to the time the LED is lit/unlit. May I know is I2C supposed to take such a long time? Or am I doing something wrong? Thanks.

Master:
Code:

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

#elif defined(__PCH__)
#include <18F4620.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000, internal)
#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 data;

while(1)
  {
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   data = i2c_read(0);
   i2c_stop();

   //printf("read %X \n\r", data);
   if (data == 0x01)
      output_high(PIN_C0);
   if (data == 0x00)
      output_low(PIN_C0);


   //delay_ms(1000);
  }

}


Slave:

Code:

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

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

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

int8 adc_result;


#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;

state = i2c_isr_state();
   
if(state < 0x80)     // Master is sending data
  {
   incoming = i2c_read();
  }

if(state >= 0x80)   // Master is requesting data from slave
  {
   i2c_write(adc_result);
  }

}


//======================================
void main ()
{
//setup_adc_ports(AN0);
//setup_adc(ADC_CLOCK_DIV_8);
//set_adc_channel(0);
//delay_us(20);
//adc_result = read_adc();

enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
//set_tris_c(0x01);
   
while(1)
  {
   //adc_result = read_adc();
   if(input(PIN_C0))
      adc_result = 0x01;
    else
      adc_result = 0x00;
   delay_ms(500);
  }

}
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Feb 03, 2010 3:08 am     Reply with quote

I would expect up to .5 second delay with your code due to this line:-
delay_ms(500);

If you press the button just after the code has done the check, your code will wait at least .5 second before it tests the button again and updates the value.

I also see you have a delay_ms(1000) which is now commented out.
Comment out the delay_ms(500); and see what happens.

i2c has 2 speeds ratings standard upto 100k and fast upto 400k but as it is clocked it may vary and I don't know how fast your pic will clock it.
Ttelmah
Guest







PostPosted: Wed Feb 03, 2010 4:44 am     Reply with quote

First, 20% of the code you post, is 'wasted space'.
You have taken an example, designed to work with two chips, one a PIC16, and one a PIC18, and left in place the handling for the compiler switch, but made it not work. The PCM compiler _cannot handle_ the PIC18F4620, so get rid of this code. It is just making your work bulkier , without gaining anything....

There main problem with your oscillator fuses. You have 'HS' selected (which says use an external oscillator), and a delay statement saying use 20MHz, and an internal oscillator. 20MHz, is _not_ available from the internal oscillator, so the settings are 'invalid'. I'd suspect the chip is actually clocking at perhaps the 500KHz rate, making your '500mSec' delay in the slave, actually take 40* as long....

Best Wishes
snowbell
Guest







PostPosted: Fri Feb 05, 2010 9:24 am     Reply with quote

Thanks for all the help. It is really the oscillator problem which I did not even realise I defined them wrongly. Thanks once again.
snowbell
Guest







PostPosted: Fri Feb 05, 2010 10:54 am     Reply with quote

I got another problem now. The initial code example I used was the master receiving data from the slave. Now I tried to edit the previous code to have the master send data to the slave instead. But the code doesn't work anymore. Any help would be gladly appreciated. Thanks.

Master:
Code:

#if defined(__PCH__)
#include <18F4620.h>
#fuses INTRC,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000, internal)
#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;

while(1)
  {
   if(input(PIN_C0))
      cmd = 0x01;
    else
      cmd = 0x00;
   
   i2c_start();
   i2c_write(SLAVE1_WRT_ADDR);
   i2c_write(cmd);
   i2c_stop();

   //printf("read %X \n\r", data);

  }

}


Slave:
Code:

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

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

int8 data;


#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;
   
   state = i2c_isr_state();
      
   if(state < 0x80)     // Master is sending data
   {
      incoming = i2c_read();
      data = incoming;
   }
   
   if(state >= 0x80)   // Master is requesting data from slave
   {
      i2c_write(data);
   }

}


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

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

}
snowbell
Guest







PostPosted: Sat Feb 06, 2010 12:28 pm     Reply with quote

Hi, I've tried to debug my code but it still doesn't work. Anyone knows the reason why? Thanks.
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