• AVR Freaks

Hot!I2C communications of PIC (Master) to PIC (Slave)

Author
stormin2
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2018/10/04 12:09:29
  • Location: 0
  • Status: offline
2018/10/06 02:27:25 (permalink)
0

I2C communications of PIC (Master) to PIC (Slave)

Hi all
 
I'm trying to communicate from one PIC (PIC18F45K22) to another PIC of the same device via I2C. I'm using the MPLAB X IDE with the latest XC8 v2 compiler. I've tried using the MCC but there seems very little if no documentation using the preferred on the foundation services library. I also note that the other alternative is no longer supported. Also the peripheral library is not supported on the v2 library due to C99. I've written some code which I've put below but the bus just hangs waiting a reply from the slave. Could someone point me in the right direction to foundation services library or another alternative could be to use the C18 compiler.
 
Many thanks
 
Paul.
******MASTER CODE*********
#include "mcc_generated_files/mcc.h"
#include <xc.h>

void I2C_Master_Init(const unsigned long c)
{
    SSP1CON1 = 0b00101000;  //Master mode
    SSP1CON2 = 0;           //Initialise
    SSP1ADD = 0x35;         // 100kHz @ 16MHz clock
    SSP1STAT =0;            //Initialise
}
 
void I2C_Master_Wait()
{
    while((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
    //    R_nW bit = 1      or        ACKEN=1 Initiate Acknowledge sequence
    //                                RCEN=1 Enables receive mode I2C
    //                                PEN=1 Initiate stop condition
    //                                RSEN=1 Initiate repeated start
    //                                SEN=1 Start condition enabled
}

void I2C_Master_Start()
{
    I2C_Master_Wait();
    SSP1CON2bits.SEN = 1;   //Start condition
}

void I2C_Master_Repeated_Start()
{
    I2C_Master_Wait();
    SSP1CON2bits.RSEN = 1;
}

void I2C_Master_Stop()
{
    I2C_Master_Wait();
    SSP1CON2bits.PEN = 1;   //Stop condition
}

void I2C_Master_Write(unsigned d)
{
    I2C_Master_Wait();
    SSP1BUF = d;            //Write data
}

unsigned short I2C_Master_Read(unsigned short a)
{
    unsigned short temp;
    I2C_Master_Wait();
    SSP1CON2bits.RCEN = 1;
    I2C_Master_Wait();
    temp = SSP1BUF;
    I2C_Master_Wait();
    SSP1CON2bits.ACKDT = (a)?0:1;
    SSP1CON2bits.ACKEN = 1;
    TRISC = 0x18;
    return temp;
}




/*
                         Main application
 */
void main(void)
{
    
        SYSTEM_Initialize();
    LATB = 0;       //LEDs off
    int i = 0;


    while (1)
    {
        LATB = 1;
        I2C_Master_Start();     //Start comdition
        //LATB = 2;
        I2C_Master_Write(0x30);  //7 bit address + write
        LATB = 2;
        I2C_Master_Write(i);     //Write data
        I2C_Master_Stop();       //Stop condition
        __delay_ms(200);
        LATB=2;
        LATB = i;
        i = i++;
        if(i > 255)
        {
            i = 0;
        }
    }
}

/**
 End of File
*/
 
******SLAVE CODE******
#include "mcc_generated_files/mcc.h"
#include <xc.h>

int z;

/*
                         Main application
 */

void __interrupt() I2C_Slave_Read()
{
    if(PIR1bits.SSP1IF == 1)
    {
        SSP1CON1bits.CKP = 0;       //Hold the SCK
        if((SSP1CON1bits.SSPOV) || (SSP1CON1bits.WCOL))
        {
            z = SSP1BUF;            //Read the value to clear the buffer
            SSP1CON1bits.SSPOV = 0; //Clear the overflow flag
            SSP1CON1bits.WCOL = 0;  //Clear the collision bit
        }
        
        if(!SSP1STATbits.D_nA && !SSP1STATbits.R_nW)
        {
            z = SSP1BUF;            //Empty the buffer of the slave address
            while(SSP1STATbits.BF); //Wait until buffer is full
            LATB = SSP1BUF;         //LEDs with values of data buffer
            SSP1CON1bits.CKP = 1;   //Release the clock
        }
        
    }
}

void I2C_Slave_Init(short address)
{
    SSP1STAT = 0x80;                //Slew rate control bit
    SSP1ADD = address;              //Set slave address
    SSP1CON1 = 0x36;
    SSP1CON2 = 0x01;
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    PIR1bits.SSP1IF = 0;
    PIE1bits.SSP1IE = 1;
}

      

void main(void)
{
    // Initialize the device
    SYSTEM_Initialize();

I2C_Slave_Init(0x30);
        while (1);
        {}
}

// If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
    // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global and Peripheral Interrupts
    // Use the following macros to:

    // Enable the Global Interrupts
    //INTERRUPT_GlobalInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Enable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptEnable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();

/**
 End of File
*/
#1

3 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: I2C communications of PIC (Master) to PIC (Slave) 2018/10/06 02:42:57 (permalink)
    0
    I don't know why everyone skips the most obvious part of debugging an I2C connection.
    When the Master sends a slave address, the very next think you should do is:
    • Wait for the address to finish sending (i.e. call I2C_Master_Wait() )
    • Read the ACKSTAT flag to see if you got an ACK or a NAK back from the Slave.
    If you don't get an ACK, there's no point trying to continue, either the bus isn't working or you have the wrong address (so the slave won't respond).
     

    Nearly there...
    #2
    meanilkp
    New Member
    • Total Posts : 23
    • Reward points : 0
    • Joined: 2018/08/19 22:12:10
    • Location: India
    • Status: offline
    Re: I2C communications of PIC (Master) to PIC (Slave) 2020/07/05 21:39:30 (permalink)
    +2 (2)
    I would recommend you to use MCC generated code, it works perfectly for me.
    Here is my Master-Slave EEPROM example implementation using MCC generated code.
     
     
    post edited by meanilkp - 2020/07/05 21:48:55

    Attached Image(s)

    #3
    RISC
    Super Member
    • Total Posts : 5776
    • Reward points : 0
    • Status: offline
    Re: I2C communications of PIC (Master) to PIC (Slave) 2020/07/06 04:30:20 (permalink)
    0
    Hi,
    There are examples of I2C Master & Slave for PIC18 family in the MPLABXPRESS online IDE :
    https://mplabxpress.microchip.com/mplabcloud/ide
    Regards

    For support make sure to check first here : http://microchipdeveloper.com
    There are hundreds of PIC, AVR, SAM...which one do YOU use ?
    #4
    Jump to:
    © 2020 APG vNext Commercial Version 4.5