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

Simple r/w with I2C Help!

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



Joined: 22 Oct 2003
Posts: 22

View user's profile Send private message

Simple r/w with I2C Help!
PostPosted: Wed Apr 21, 2004 6:16 am     Reply with quote

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!
PostPosted: Wed Apr 21, 2004 10:49 am     Reply with quote

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

View user's profile Send private message

Ok, but...
PostPosted: Wed Apr 21, 2004 11:36 am     Reply with quote

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
PostPosted: Thu May 06, 2004 6:31 am     Reply with quote

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

View user's profile Send private message

Re: Pic as i2c slave
PostPosted: Thu May 06, 2004 7:46 am     Reply with quote

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







PostPosted: Thu May 06, 2004 9:05 am     Reply with quote

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
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