Libstock
It is currently 23 Nov 2014 16:48

All times are UTC + 1 hour




Post new topic Reply to topic  [ 36 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: 06 Dec 2006 05:04 
Offline

Joined: 28 Aug 2006 23:27
Posts: 6
Hi all, here is some simple code for Master/Slave I2C projects. I can't take all of the credit for writing this. I used mB and mP code/methods that I found on the forum and translated it into this. Feel free to comment, but I might not be quick to respond because I only get on here about 1-2 times a week.

Here's the Master code

/*
 * Project name:
     Master
 * Description:
     Master control for PIC 2 PIC I2C Communication
 * Configuration:
     MCU:             PIC16F876A
     SW:              mikroC v6.0
 * NOTES:
*/

//------------------------------------------------------------------------------
const Slave_Addy = 0x69;

void send(unsigned short send_data){
  I2C_Init(100000);
  I2C_Start();
  I2C_Wr(Slave_Addy);
  I2C_Wr(send_data);
  I2C_Stop();
}

unsigned short read(){
  unsigned short read_data;
  I2C_Init(100000);
  I2C_Start();
  I2C_Wr(Slave_Addy + 1);
  read_data = I2C_Rd(0);
  delay_ms(100);
  I2C_Stop();
  return read_data;
}

void main(){
 // Main program code place here. 
 // Use sub-routine "send" to send data to slave.
 // Use "read" to read data from slave.
}


Here's the Slave code

/*
 * Project name:
     Slave
 * Description:
     Slave code for PIC 2 PIC I2C Communication
     Write data from Master to PORTB
     Send PORTC data to Master
 * Configuration:
     MCU:             PIC16F876A
     SW:              mikroC v6.0
 * NOTES:
*/

//------------------------------------------------------------------------------
const Addy = 0x69;                    // set I2C device address
const Delay_Time = 250;               // port check delay
//------------------------------------------------------------------------------
//                      Global Processing Variables
//------------------------------------------------------------------------------
unsigned short j;                      // just dummy for buffer read
unsigned short rxbuffer;               //
unsigned short tx_data;                //
//------------------------------------------------------------------------------
void Init(){
  ADCON1 = 0;                          // All ports set to digital
  TRISA = 0;                           // Set PORTA as output
  TRISB = 0;                           // Set PORTB as output
  TRISC = 0xFF;                        // Set PORTC as input
  SSPADD =  Addy;                      // Get address (7bit). Lsb is read/write flag
  SSPCON = 0x36;                       // Set to I2C slave with 7-bit address
  PIE1.SSPIF = 1;                      // enable SSP interrupts
  INTCON = 0xC0;                       // enable INTCON.GIE
}
//------------------------------------------------------------------------------
void interrupt(){                      // I2C slave interrupt handler
  if (PIR1.SSPIF == 1){                // I2C Interrupt
    PIR1.SSPIF = 0;                    // reset SSP interrupt flag

    //transmit data to master
    if (SSPSTAT.R_W == 1){             // Read request from master
      SSPBUF = tx_data;                // Get data to send
      SSPCON.CKP = 1;                  // Release SCL line
      j = SSPBUF;                      // That's it
      return;
    }
    if (SSPSTAT.BF == 0){              // all done,
      j = SSPBUF;                      // Nothing in buffer so exit
      return;
    }

    //recieve data from master
    if (SSPSTAT.D_A == 1){             // Data [not address]
      rxbuffer = SSPBUF;               // get data
      j = SSPBUF;                      // read buffer to clear flag [address]
      return;
    }
  }
  j = SSPBUF;                              // read buffer to clear flag [address]
}
//------------------------------------------------------------------------------
void main(){
  Init();
  while(1){
    PORTB   = rxbuffer;
    tx_data = PORTC;
    Delay_ms(Delay_Time);
  }
}


Enjoy,
Tom


Top
 Profile  
 
PostPosted: 06 Dec 2006 09:04 
Offline
mikroElektronika team
User avatar

Joined: 03 Aug 2004 12:59
Posts: 6608
Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: 07 Dec 2006 13:48 
Offline

Joined: 02 Aug 2006 16:42
Posts: 32
thanx. but i send data from master do not read on slave portB.
master PortC.F3 to Slave PortC.F4 & M PortC.F4 To S PortC.F3 is right shematic.


Top
 Profile  
 
 Post subject:
PostPosted: 08 Dec 2006 01:08 
Offline

Joined: 28 Aug 2006 23:27
Posts: 6
gedo wrote:
thanx. but i send data from master do not read on slave portB.
master PortC.F3 to Slave PortC.F4 & M PortC.F4 To S PortC.F3 is right shematic.


I'm not sure if you are asking a question here or trying to state something but I'll try to explain a little bit more.

You send serial data from the Master to the Slave using these two lines.
PORTC.F3 is the SCL line
PORTC.F4 is the SDA line


The pin mapping (schematic) should be:
Master PORTC.F3 -> Slave PORTC.F3
Master PORTC.F4 -> Slave PORTC.F4

Those are the I2C lines on the 16F876A.

The slave program takes the serial data from the master, 8-bits, and sets the PORTB output of the slave device based on this.

Example:
-------------
The master sends the following data stream 00110011
The slave would set its PORTB = 00110011

If the slave recieves a "read" command the slave will read its PORTC and compile this into serial data to be sent via I2C to the master.

Note: Bits 3 and 4 of the PORTC data sent from the slave to the master should be ignored by the master because these are the I2C lines.


Top
 Profile  
 
PostPosted: 12 Aug 2008 07:18 
Offline

Joined: 12 Aug 2008 07:08
Posts: 18
Hello Tom

I try to put your code in my program for a slave I2C pic.
But i get never a interrupt.
Do you know what could be the problem?

Code if interrupt has occured:
void interrupt(){
   
    if (PIR1.SSPIF = 1){
   
        static unsigned short reg = SERVO_REG_MAX;
   
        PIR1.SSPIF = 0;
        PORTD.F0 = 1;
       
        //transmit data to master
        if (SSPSTAT.R_W == 1){             // Read request from master
          if (reg < SERVO_REG_MAX){
             SSPBUF = servo_register[reg]; // Get data to send
             reg = SERVO_REG_MAX;
             SSPCON.CKP = 1;               // Release SCL line
             j = SSPBUF;
          }                                // That's it
          return;
        }
        if (SSPSTAT.BF == 0){              // all done,
          j = SSPBUF;                      // Nothing in buffer so exit
          return;
        }

        //recieve data from master
        if (SSPSTAT.D_A == 1){             // Data [not address]
          //PORTD.F0 = 0;
          if (reg < SERVO_REG_MAX){
               servo_register[reg] = SSPBUF;  // get data
               j = SSPBUF;                    // read buffer to clear flag [address]
               reg = SERVO_REG_MAX;
          }
          else {
               reg = SSPBUF;
               j = SSPBUF;                    // read buffer to clear flag [address]
          return;
        }
        }
        j = SSPBUF;                              // read buffer to clear flag [address]
       
    }
}



Code for init:
//* iniyialisieren des I2C Interface *//
    SSPADD =  0xC2;                      // Get address (7bit). Lsb is read/write flag
    SSPCON = 0x34;                       // Set to I2C slave with 7-bit address
   
    //* Interrupts erlauben *//
    INTCON.GIE = 1;
    INTCON.PEIE = 1;
    PIE1.SSPIE = 1;                      // enable SSP interrupts
    PIE1.TMR1IE = 1;
    PIR1.TMR1IF = 0;
    PIR1.SSPIF = 0;



Best regards

Remo Hug


Top
 Profile  
 
 Post subject: Thank you a lot
PostPosted: 12 Aug 2008 10:27 
Offline

Joined: 26 Sep 2007 21:52
Posts: 114
Thank you a lot for example.

It is exactly what i need. I will chect it via proteus soon.

Regards,
Pranas


Top
 Profile  
 
 Post subject: Error
PostPosted: 12 Aug 2008 12:16 
Offline

Joined: 26 Sep 2007 21:52
Posts: 114
Strange but i have some problem.

I am using 4k7 external rezistors and 8MGhz frequency


Image

Trying to find out the problem


Top
 Profile  
 
 Post subject:
PostPosted: 12 Aug 2008 14:15 
Offline

Joined: 12 Aug 2008 07:08
Posts: 18
Hi Pranas

I use the PIC 16F877A (8MHz) with the EasyPIC5-Board.

Regards,
Remo


Top
 Profile  
 
 Post subject: about second pic
PostPosted: 12 Aug 2008 15:05 
Offline

Joined: 26 Sep 2007 21:52
Posts: 114
Hello,

Can you give some explanation how you connected second PIC16F877A?

Thank you
Pranas


Top
 Profile  
 
 Post subject: Re: about second pic
PostPosted: 12 Aug 2008 15:17 
Offline

Joined: 25 Oct 2007 22:22
Posts: 165
Location: Wuppertal, Germany, Earth... :-)
prancius wrote:
Can you give some explanation how you connected second PIC16F877A?

Hi prancius,

simply connect 8):

SDA (Master RC4) <==> SDA (RC4 Slave)
SCL (Master RC3) <==> SCL (RC3 Slave)

Don't forget GND connected to all devices as like as Master and Slave (with resistors from SDA and SCL to Vcc). :roll:

Only the "Master" is the one and only who determines who has anything to send and/or receive. :shock:

_________________
so long,
MasterBlaster.

Using: EasyPIC4 HW. Rev. 1.03, LCD- & GLCD Display, NetWork and SD/MMC Adapter,
reg. MikroC Pro for PIC 2009, PIC 16F877A, 18F452 and 18F4685 with 8/20 MHz Xtal.


Top
 Profile  
 
 Post subject:
PostPosted: 12 Aug 2008 15:41 
Offline

Joined: 12 Aug 2008 07:08
Posts: 18
Hello Pranas

I use the "PC to I2C-Bus Adapter" as Master, not a PIC.

(http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=68)

Best Regards

Remo


Top
 Profile  
 
 Post subject: So
PostPosted: 12 Aug 2008 15:58 
Offline

Joined: 26 Sep 2007 21:52
Posts: 114
So as i understand one pic you a placed on easypic5 second on some dev board. And you connected like this?

Are you using external pull ups or just pull up jumper on port c?

Image

Thank you
Pranas


Top
 Profile  
 
 Post subject:
PostPosted: 12 Aug 2008 17:08 
Offline

Joined: 12 Aug 2008 07:08
Posts: 18
No.
I the PIC on the Board (EasyPic5) is the slave.

I send data from a VB-Programm to the pic over the "PC to I2C-Bus Adapter".

Link to "PC to I2C-Bus Adapter":
http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=68

Best Regards

Remo


Top
 Profile  
 
PostPosted: 14 Aug 2008 01:34 
Offline

Joined: 28 Aug 2006 23:27
Posts: 6
Remoeggel wrote:
Hello Tom

I try to put your code in my program for a slave I2C pic.
But i get never a interrupt.
Do you know what could be the problem?

Code if interrupt has occured:
void interrupt(){
   
    if (PIR1.SSPIF = 1){
   
 




I believe this should be changed to

void interrupt(){
   
    if (PIR1.SSPIF == 1){
   
 


Give it a try and let me know


Top
 Profile  
 
 Post subject: It works now!!!
PostPosted: 14 Aug 2008 14:09 
Offline

Joined: 12 Aug 2008 07:08
Posts: 18
Hello Tom

It works now.
The problem was a false value in the register SSPCON.
:oops: :x :oops:

thanks for all

Remo


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 36 posts ]  Go to page 1, 2, 3  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group