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

PROBLEM I2C PIC-TO-PIC

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



Joined: 28 Jun 2011
Posts: 3
Location: Anadia

View user's profile Send private message

PROBLEM I2C PIC-TO-PIC
PostPosted: Tue Jun 28, 2011 5:44 pm     Reply with quote

Staff needed help, I put two pic's to communicate via I2C, and used examples that are on the forum, but what follows is that the pic slave only responds at a time and do not understand why I think the pic is stopped, someone I could help!?!?
Obrigrado the attention


code master:
Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
   
#define SLAVE1_WRT_ADDR   0x12
#define SLAVE1_READ_ADDR  0x13

//====================================
void main()
{
int8 data;

//int teste=50;

while(true)
  {
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   data = i2c_read();
   i2c_stop();
 
   printf("Read %u \n\r",data);

   delay_ms(1000);
  }

}

code slave:
Code:

#include <16F877.h>
#device adc=8
#fuses NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP 
#use delay(clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

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();
   printf("\n\rV");
  }

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

//======================================
void main ()
{
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
adc_result = read_adc();
printf("\n\r VALOR ADC -> %u",adc_result);
   
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
   
while(true)
  {

   adc_result = read_adc();
   printf("\n\r VALOR ADC -> %u",adc_result);
   delay_ms(50);
  }

}
temtronic



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

View user's profile Send private message

PostPosted: Tue Jun 28, 2011 6:11 pm     Reply with quote

quick comment ..
Anytime you use serial I/O....you should(must) add the 'errors' option to the
use rs232(.........) function.

This allows the PIC program to recover from some hardware errors.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 28, 2011 6:30 pm     Reply with quote

Quote:
while(true)
{
i2c_start();
i2c_write(SLAVE1_READ_ADDR);
data = i2c_read();
i2c_stop();

One reason I can see immediately is that when you edited the code from
some other post, you left out the 0 parameter from the i2c_read() function.

It should be:
Code:
data = i2c_read(0);


There might be other problems. I didn't look any further.
plainas1234



Joined: 28 Jun 2011
Posts: 3
Location: Anadia

View user's profile Send private message

PostPosted: Wed Jun 29, 2011 4:25 am     Reply with quote

Staff already made your changes and does not work the same, ie the pic master communicates once with the slave and the second time going to communicate the slave pic is already stopped. I simulate the program in proteus.
temtronic



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

View user's profile Send private message

PostPosted: Wed Jun 29, 2011 5:04 am     Reply with quote

Get rid of Proteus !!

The simulator is FULL of bugs, errors and 'quirks'. It does NOT emulate the real world correctly.

Buy real chips, program them and see what happens.

Don't waste anymore time on Proteus!!
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Wed Jun 29, 2011 6:46 am     Reply with quote

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


Can sometimes cause problems. When you issue a read from the master to the slave, you send the address byte plus the read bit set. That value still needs to be read by the slave before they write back.

Also, I don't remember which version it is now, but one of the 4.xxx compiler versions fixed a bug where i2c_read() would hang up in certain weird situations (I know this because I was the one that reported that issue to them and they fixed it), so if it still locks up, consider trying to just read from the I2C Rx buffer directly (along with clearing/setting the appropriate flags).
Ttelmah



Joined: 11 Mar 2010
Posts: 19329

View user's profile Send private message

PostPosted: Wed Jun 29, 2011 8:09 am     Reply with quote

Get rid of the printf in the interrupt handler....

Problems with this:
1) _SLOW_. Takes over 3mSec. Code needs to be out of the ISR ready for the next byte in _uSec_. This part doesn't apply at present, because you don't write to the slave.
2) Blocks interrupts in the main. This is a potential 'killer'. Interrupts will be disabled in the printf function in the _main_ code, because you have print's, in both the ISR and main. So for about 19mSec, interrupts will be turned off in the slave. This _will_ stop it handling I2C data correctly.

Then change your test in the ISR:
Code:

   if(state < 0x80)

to '<='.

This _must_ include the 0x80 state.

The key is that on the 0x80 state, a byte has been _received_ from the master (the command byte), which has to be read _before_ you load the output register. On all the higher states (0x81 etc.), you can just write the byte, but on 0x80, you must read the data first. This is Jeremiah's point about reading the address byte

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