|
|
View previous topic :: View next topic |
Author |
Message |
Helyos
Joined: 22 Oct 2003 Posts: 22
|
Simple r/w with I2C Help! |
Posted: Wed Apr 21, 2004 6:16 am |
|
|
Hi, I had this last three days desperate.
I have PCH 3.155 and Iīm working with PIC16F876 4Mhz and I didnīt get (looking for in internet and in this forum and doing thousands of experiments) a code to comunicate 2 pics in I2C. I had tests with the 24LC256 and works fine, and with an I2C LCD too. But when I try comunicate two pics, I canīt.
I put my code here, I donīt know where I have the mistakes.
Thanks
Code: | Master
#include <16F876.h> /* Standard Include for 16F876 Chip */
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
#use delay (clock=4000000) /* Delay for 4 mhz crystal */
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)/* Setup RS232 */
#use I2C(MASTER, sda=PIN_C4, scl=PIN_C3,NOFORCE_SW, SLOW, RESTART_WDT)/* Setup I2C */
#include "lcd4_i2c.c"
#org 0x1F00, 0x1FFF void loader16F876(void) {}
main(){
byte i2c_command;
loader16f876();
lcd_init();
while (true){
delay_ms(1000);
i2c_command = 0xa2;
printf(lcd_putc,"\fOutputting: %x", i2c_command);
delay_ms(1000);
i2c_start(); // Start condition
i2c_write(0xb0); // Device address
i2c_write(i2c_command); // Write Command
i2c_stop(); // Stop condition
}
}
SLAVE
#include <16F876.h> /* Standard Include for 16F876 Chip */
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
#use delay (clock=4000000) /* Delay for 4 mhz crystal */
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)/* Setup RS232 */
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xb0, SLOW, NOFORCE_SW)/* Setup I2C */
#INT_SSP /*I2C Int*/
void ssp_interupt (){
byte incoming;
printf("Ha entrado\n\r");
incoming = 3;
if (i2c_poll()){
printf(" POOL ");
incoming=i2c_read();
printf("Read byte 1: %x\n\r", incoming);
if (incoming == 0xb0){
printf("Incoming = 0xb0 \n\r");
incoming=i2c_read();
printf("Read byte 2: %x\n\r", incoming);
}
}else{
printf(" NO POOL ");
i2c_write(0xa5);
}
}
#org 0x1F00, 0x1FFF void loader16F876(void) {}
main(){
loader16f876();
delay_ms(1000);
printf("Running\n");
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (true){}
} |
I only get in the slave b0 and in the master only get ff.
I want to do a system with 6 slaves and one master (all 16F876) and I would like I can call to one slave, send from the master the operation code, and then do the operation (read this or other value, write this or other value, etc...) and the same in the 6 slaves.
I didnīt find any code that allow me to do this. Could you help me?
Thanks |
|
|
Ttelmah Guest
|
Re: Simple r/w with I2C Help! |
Posted: Wed Apr 21, 2004 10:49 am |
|
|
Helyos wrote: | Hi, I had this last three days desperate.
I have PCH 3.155 and Iīm working with PIC16F876 4Mhz and I didnīt get (looking for in internet and in this forum and doing thousands of experiments) a code to comunicate 2 pics in I2C. I had tests with the 24LC256 and works fine, and with an I2C LCD too. But when I try comunicate two pics, I canīt.
I put my code here, I donīt know where I have the mistakes.
Thanks
Code: | Master
#include <16F876.h> /* Standard Include for 16F876 Chip */
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
#use delay (clock=4000000) /* Delay for 4 mhz crystal */
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)/* Setup RS232 */
#use I2C(MASTER, sda=PIN_C4, scl=PIN_C3,NOFORCE_SW, SLOW, RESTART_WDT)/* Setup I2C */
#include "lcd4_i2c.c"
#org 0x1F00, 0x1FFF void loader16F876(void) {}
main(){
byte i2c_command;
loader16f876();
lcd_init();
while (true){
delay_ms(1000);
i2c_command = 0xa2;
printf(lcd_putc,"\fOutputting: %x", i2c_command);
delay_ms(1000);
i2c_start(); // Start condition
i2c_write(0xb0); // Device address
i2c_write(i2c_command); // Write Command
i2c_stop(); // Stop condition
}
}
SLAVE
#include <16F876.h> /* Standard Include for 16F876 Chip */
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
#use delay (clock=4000000) /* Delay for 4 mhz crystal */
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)/* Setup RS232 */
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xb0, SLOW, NOFORCE_SW)/* Setup I2C */
#INT_SSP /*I2C Int*/
void ssp_interupt (){
byte incoming;
printf("Ha entrado\n\r");
incoming = 3;
if (i2c_poll()){
printf(" POOL ");
incoming=i2c_read();
printf("Read byte 1: %x\n\r", incoming);
if (incoming == 0xb0){
printf("Incoming = 0xb0 \n\r");
incoming=i2c_read();
printf("Read byte 2: %x\n\r", incoming);
}
}else{
printf(" NO POOL ");
i2c_write(0xa5);
}
}
#org 0x1F00, 0x1FFF void loader16F876(void) {}
main(){
loader16f876();
delay_ms(1000);
printf("Running\n");
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (true){}
} |
I only get in the slave b0 and in the master only get ff.
I want to do a system with 6 slaves and one master (all 16F876) and I would like I can call to one slave, send from the master the operation code, and then do the operation (read this or other value, write this or other value, etc...) and the same in the 6 slaves.
I didnīt find any code that allow me to do this. Could you help me?
Thanks |
Your problem, is probably the interrupt latency.
Unfortunately, when an interrupt occurs, there is a delay (the hardware latency), before the handler is called. Then in CCS, the handler saves all the registers that might be in use. Then it tests for which interrupt is enabled, and has triggered. Unfortunately, this means that there are about 30 instruction times between the actual interrupt, and entering the handler!. Unfortunately therefore, when talking to a PIC based slave, there has to be a long delay between sending the first byte, and any further data. If using interrupts for the seperate bytes, there has to be a similar delay between each byte....
Best Wishes |
|
|
Helyos
Joined: 22 Oct 2003 Posts: 22
|
Ok, but... |
Posted: Wed Apr 21, 2004 11:36 am |
|
|
Thanks for your answer but I donīt know how I can solve that.
How can I do to get the communication?
Anybody can put any code that works? I test with ex_slave.c but I didnīt get any results.
Thanks |
|
|
steve Guest
|
Pic as i2c slave |
Posted: Thu May 06, 2004 6:31 am |
|
|
I have used 16f877 in slave mode but it never really worked satisfactorily. I spent a long time working on it and got communications going but in the end I concluded that the implementation by either microchip or ccs leaves a lot to be desired. I imagine 16f876 has similar probs. If at all possible use uart (even software uart). You will save yourself a lot of heartache.
Anybody in this forum ever get an i2c or SPI 2 PIC master/slave implementation working? |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: Pic as i2c slave |
Posted: Thu May 06, 2004 7:46 am |
|
|
steve wrote: | I have used 16f877 in slave mode but it never really worked satisfactorily. I spent a long time working on it and got communications going but in the end I concluded that the implementation by either microchip or ccs leaves a lot to be desired. I imagine 16f876 has similar probs. If at all possible use uart (even software uart). You will save yourself a lot of heartache.
Anybody in this forum ever get an i2c or SPI 2 PIC master/slave implementation working? |
I have had very good results using SPI between two PIC's. The key is to perform transfers in packets as fast as posiable. The master turning on and off the chip select wil keep everything in sync. I perform a CRC on the packets to insure the data is valid and simply drop packets with bad CRC. Droped packets are uncommon and usually related to external noise. This is much faster than using a serial port. The packet size in both directions is the same size but some bytes may be unused. You could even have the master turn on the CS and wait for the slave to jump into an interupt routine and then perform the transfer. That way your slave device can be free running and still stop to respond to it's master. For me I have a transfer every few mS with enough time between packets to allow the slave time to aquire new data.
http://www.ccsinfo.com/forum/viewtopic.php?t=17723&highlight=spi |
|
|
Hans Guest
|
|
Posted: Thu May 06, 2004 9:05 am |
|
|
I am using I2C communication between an 8051 (the master) and an 16F877 (the slave).
The main problem with this is that the 16F877 does "clock stretching" which means the MSSP hardware holds SCL low until an interrupt is generated and serviced (on each byte) after the MSSP had an adress match.
So your master must wait until SCL is "free" by setting SCL high and wait until it is high. I could only get this working with a software I2C on the master side (which i had to do anyway since my 89C51RD2 has no I2C hardware).
I am not using CCS but Hi-Tech but hope this helps anyway.
Hans |
|
|
|
|
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
|