|
|
View previous topic :: View next topic |
Author |
Message |
plainas1234
Joined: 28 Jun 2011 Posts: 3 Location: Anadia
|
PROBLEM I2C PIC-TO-PIC |
Posted: Tue Jun 28, 2011 5:44 pm |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Tue Jun 28, 2011 6:11 pm |
|
|
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
|
|
Posted: Tue Jun 28, 2011 6:30 pm |
|
|
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
|
|
Posted: Wed Jun 29, 2011 4:25 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Jun 29, 2011 5:04 am |
|
|
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: 1348
|
|
Posted: Wed Jun 29, 2011 6:46 am |
|
|
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: 19510
|
|
Posted: Wed Jun 29, 2011 8:09 am |
|
|
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:
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 |
|
|
|
|
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
|