I²C Communication with PIC Microcontroller – MPLAB XC8

I²C Communication with PIC Microcontroller – MPLAB XC8

I2C or IIC or I2C stands for Inter-Integrated Circuit. It is a very popular multi-master, multi-slave serial communication interface developed by Philips. I2C uses two bidirectional open drain data lines, Serial Data (SDA) and Serial Clock (SCL) with pull up resistors as shown below. Unlike UART, you can connect and communicate to multiple devices using the same I2C bus.

I2C Communication
I2C Communication

I2C is a master slave protocol. It means that devices connected to I2C bus will be either master or slave. The master is the device which initiate communication and it drives clock (SCL) line. Slaves are the devices which responds to master and it cannot initiate a communication. An I2C bus can have multiple masters and multiple slaves. But commonly we are using single master and multiple slaves. Each slaves are identified or addressed by a unique address. The master will send address of slave + R/W bit first, then followed by other data. So the slave with that particular address will be activated at that moment. R/W bit indicates whether the master wants to read data from or write data to the slave. For example, we can have a microcontroller or host device which is connected to different slave devices like I/O Port Expanders, LED/LCD Drivers, ADCs, DACs, EEPROMs, Real Time Clock (RTC) etc.

Most of the PIC microcontrollers have built in Master Synchronous Serial Port (MSSP) module which can be configured to operate in following modes.

  • Serial Peripheral Interface (SPI)
  • Inter-Integrated Circuit (I2C) – Slave, Master & Multi-master modes

In this tutorial we will learn how to operate MSSP module of PIC Microcontroller as I2C master or slave. For demonstration we are using PIC 16F877A microcontroller. You can easily convert it for other microcontrollers if you understand it clearly.


MSSP Module in I2C Mode

Let’s see in detail about working of MSSP module of PIC Microcontroller in I²C mode. MSSP module can be configured to operate in both 10 bit and 7 bit address mode. In this example we are demonstrating 7 bit mode only as it is the commonly used one. You can easily modify the program to work in 10 bit mode.

I2C Master

We need to write to SSPCON1 and SSPADD registers to configure MSSP module as I²C Master and to set the clock frequency of I²C communication respectively.

I2C Master Block Diagram - PIC Microcontroller
I2C Master Block Diagram – PIC Microcontroller

I2C Slave

Similar to above, we need to write to SSPCON1 and SSPADD registers to configure MSSP module in I²C slave mode and to set the slave device address respectively.

I2C Slave Block Diagram - PIC Microcontroller
I2C Slave Block Diagram – PIC Microcontroller

Clock generated by the master on SCL line will cause the data to shift in and shift out of the SSPSR register which makes the I2C communication happen.

I2C Registers

SSPSTAT – MSSP Status Register

SSPSTAT Register MSSP Module PIC 16F877A
SSPSTAT Register MSSP Module PIC 16F877A
  • Bit 0 BF : This is the Buffer Full status bit. In the transmit mode this bit will set when we write data to SSPBUF register and it is cleared when the data is shifted out. In the receive mode this bit will set when the data or address is received in the SSPBUF register and it is cleared when we reads the SSPBUF register.
  • Bit 1 UA : This is the Update Address bit and is used only in 10 bit address mode. It indicates that user needs to update the address in the SSPADD register.
  • Bit 2 R/W : This is the Read/Write bit information. In the slave mode it indicates the status of R/W bit during the last address match. In the master mode, 1 indicates that transmit is in progress and vice versa.
  • Bit 3 S : This bit indicates that a Start bit is detected last and it will automatically cleared during Reset.
  • Bit 4 P : As above, this bit indicates that a Stop bit is detected last and it will automatically cleared during Reset.
  • Bit 5 D/A : This is the data or address indicator bit and it is used only in slave mode. If it is set, the last byte received was data otherwise it will be address.
  • Bit 6 CKE : Setting this bit enables SMBus specific inputs. SMBus is an another bus similar to I2C, which are compatible each other.
  • Bit 7 SMP : Setting this bit disables slew rate control and vice versa.

SSPCON1 – MSSP Control Register 1

SSPCON1 Register MSSP Module PIC 16F877A
SSPCON1 Register MSSP Module PIC 16F877A
  • Bit 0 ~ 3 SSPM0 ~ SSPM3 : These are synchronous serial port mode select bits.
Synchronous Serial Port Select bits - PIC 16F877A
Synchronous Serial Port Mode Select bits – PIC 16F877A
  • Bit 4  CKP : This is SCL clock release control bit. It is used only in slave mode. Setting this bit releases the clock. If zero, it holds the clock (clock stretch).
  • Bit 5 : SSPEN :  This is the synchronous serial port enable bit. Setting this bit enables the serial port.
  • Bit 6 : SSPOV : This is receive over flow indicator bit. If this bit is set during receive mode, it indicates that a byte is received while SSPBUF is holding the previous value. And it has no application in transmit mode. We must clear this bit in software.
  • Bit 7 WCOL : It is the write collision detect bit. If this bit is set during master transmit mode, it indicates that a write to SSPBUF register was attempted when I2C conditions was not valid for a transmission to be started. And if it is set during a slave transmit mode, it indicates that SSPBUF register is written when it is transmitting the previous word. We must clear this bit in software.

SSPCON2 – MSSP Control Register 2

SSPCON2 MSSP Module PIC 16F877A
SSPCON2 MSSP Module PIC 16F877A
  • Bit 0 SEN : Start Condition or Stretch Enable bit. In master mode, setting this bit initiate start condition on SCL & SDA pins and it will be automatically cleared by the hardware. And in slave mode setting this bit enables clock stretching for both slave receive and slave transmit. If it is cleared in slave mode, clock stretching is enabled only for slave transmit.
  • Bit 1 RSEN : Repeated start condition enable bit. This bit has application only in master mode. Setting this bit will initiate repeated start condition on both SCL & SDA pins and it will automatically cleared in hardware.
  • Bit 2 PEN : Stop condition enable bit. This bit has application only in master mode. Setting this bit will initiate stop condition on both SCL & SDA pins and it will be automatically cleared in hardware.
  • Bit 3 RCEN : Receive enable bit. This bit also has application only in master mode. Setting this bit enables receive mode for I2C.
  • Bit 4 ACKEN : Acknowledge sequence enable bit. Setting this bit initiates acknowledge sequence on SCL & SDA lines and it will send ACKDT (see below) bit. This bit will be automatically cleared in hardware. It has application only in master receive mode.
  • Bit 5 ACKDT : Acknowledge data bit. 1 means not acknowledge and 0 means acknowledge. This value will be transmitted when we set the ACKEN bit (above). This bit has application only in master receive mode.
  • Bit 6 ACKSTAT : Acknowledge status bit. 1 indicates that acknowledge was not received from the slave and vice versa. This bit has application in master transmit mode only.
  • Bit 7 GCEN : General call enable bit. Setting this bit enables interrupt when a general call address is received in the register SSPSR.

I2C Library for MPLAB XC8

Master Functions

Initialize I2C Module as Master

void I2C_Master_Init(const unsigned long c)
{
  SSPCON = 0b00101000;            //SSP Module as Master
  SSPCON2 = 0;
  SSPADD = (_XTAL_FREQ/(4*c))-1; //Setting Clock Speed
  SSPSTAT = 0;
  TRISC3 = 1;                   //Setting as input as given in datasheet
  TRISC4 = 1;                   //Setting as input as given in datasheet
}

For Waiting

void I2C_Master_Wait()
{
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); //Transmit is in progress
}

Start Condition

void I2C_Master_Start()
{
  I2C_Master_Wait();    
  SEN = 1;             //Initiate start condition
}

Repeated Start

void I2C_Master_RepeatedStart()
{
  I2C_Master_Wait();
  RSEN = 1;           //Initiate repeated start condition
}

Stop Condition

void I2C_Master_Stop()
{
  I2C_Master_Wait();
  PEN = 1;           //Initiate stop condition
}

Write Data

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

Read Data

unsigned short I2C_Master_Read(unsigned short a)
{
  unsigned short temp;
  I2C_Master_Wait();
  RCEN = 1;
  I2C_Master_Wait();
  temp = SSPBUF;      //Read data from SSPBUF
  I2C_Master_Wait();
  ACKDT = (a)?0:1;    //Acknowledge bit
  ACKEN = 1;          //Acknowledge sequence
  return temp;
}

Slave Functions

Initialize module as slave

void I2C_Slave_Init(short address) 
{
  SSPSTAT = 0x80;    
  SSPADD = address; //Setting address
  SSPCON = 0x36;    //As a slave device
  SSPCON2 = 0x01;
  TRISC3 = 1;       //Setting as input as given in datasheet
  TRISC4 = 1;       //Setting as input as given in datasheet
  GIE = 1;          //Global interrupt enable
  PEIE = 1;         //Peripheral interrupt enable
  SSPIF = 0;        //Clear interrupt flag
  SSPIE = 1;        //Synchronous serial port interrupt enable
}

On Receive interrupt

Note : This is not a general function, so you need to modify it according to your application.

void interrupt I2C_Slave_Read()
{
  if(SSPIF == 1)
  {
    SSPCONbits.CKP = 0;

    if ((SSPCONbits.SSPOV) || (SSPCONbits.WCOL)) //If overflow or collision
    {
      z = SSPBUF; // Read the previous value to clear the buffer
      SSPCONbits.SSPOV = 0; // Clear the overflow flag
      SSPCONbits.WCOL = 0; // Clear the collision bit
      SSPCONbits.CKP = 1;
    }

  if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW) //If last byte was Address + Write
  {
    z = SSPBUF;
    while(!BF);
    PORTD = SSPBUF;
    SSPCONbits.CKP = 1;
  }
  else if(!SSPSTATbits.D_nA && SSPSTATbits.R_nW) //If last byte was Address + Read
  {
    z = SSPBUF;
    BF = 0;
    SSPBUF = PORTB ;
    SSPCONbits.CKP = 1;
    while(SSPSTATbits.BF);
  }

  SSPIF = 0;
  }
}

PIC to PIC Communication using I2C

In this example we have bidirectional communication between two pic microcontrollers. 8 bit switches and 8 LEDs are connected to each microcontroller. We will be controlling LEDs connected to a PIC with switches connected to other microcontroller.

Circuit Diagram

PIC to PIC Communication using I2C - Circuit Diagram
PIC to PIC Communication using I2C – Circuit Diagram

Hope you can easily understand above circuit diagram. You can make any of above 2 microcontroller as master, it depends only on the program written on it. 8MHz crystals are used for providing required clock for the operation of microcontrollers. An RCR (Resistor-Capacitor-Resistor) made using 10KΩ, 0.1µF, 4.7KΩ is connected to MCLR pin of PIC Microcontroller as recommended by Microchip. It will work fine even if you tie MCLR pin directly to VDD but Microchip doesn’t recommends it. 680Ω resistors are used to limit current through LEDs which are connected to PORTD of PIC microcontroller. 8 bit dip switches are connected to the PORTB of PIC microcontroller. Here we are using Internal Pull Up of PORTB. Hence no external resistors are required for switches.

MPLAB XC8 – Code

Since circuit of both microcontrollers are identical, you can use any of the 2 microcontrollers are master or slave.

Master

// PIC16F877A Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
#include <pic16f877a.h>

#define _XTAL_FREQ 8000000

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG
#pragma config FOSC = XT   // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF  // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF   // Low-Voltage In-Circuit Serial Programming Enable bit
#pragma config CPD = OFF   // Data EEPROM Memory Code Protection bit 
#pragma config WRT = OFF   // Flash Program Memory Write Enable bits 
#pragma config CP = OFF    // Flash Program Memory Code Protection bit

void I2C_Master_Init(const unsigned long c)
{
  SSPCON = 0b00101000;
  SSPCON2 = 0;
  SSPADD = (_XTAL_FREQ/(4*c))-1;
  SSPSTAT = 0;
  TRISC3 = 1;        //Setting as input as given in datasheet
  TRISC4 = 1;        //Setting as input as given in datasheet
}

void I2C_Master_Wait()
{
  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
}

void I2C_Master_Start()
{
  I2C_Master_Wait();
  SEN = 1;
}

void I2C_Master_RepeatedStart()
{
  I2C_Master_Wait();
  RSEN = 1;
}

void I2C_Master_Stop()
{
  I2C_Master_Wait();
  PEN = 1;
}

void I2C_Master_Write(unsigned d)
{
  I2C_Master_Wait();
  SSPBUF = d;
}

unsigned short I2C_Master_Read(unsigned short a)
{
  unsigned short temp;
  I2C_Master_Wait();
  RCEN = 1;
  I2C_Master_Wait();
  temp = SSPBUF;
  I2C_Master_Wait();
  ACKDT = (a)?0:1;
  ACKEN = 1;
  return temp;
}

void main()
{
  nRBPU = 0;                    //Enable PORTB internal pull up resistor
  TRISB = 0xFF;                 //PORTB as input
  TRISD = 0x00;                 //PORTD as output
  PORTD = 0x00;                 //All LEDs OFF
  I2C_Master_Init(100000);      //Initialize I2C Master with 100KHz clock
  while(1)
  {
    I2C_Master_Start();         //Start condition
    I2C_Master_Write(0x30);     //7 bit address + Write
    I2C_Master_Write(PORTB);    //Write data
    I2C_Master_Stop();          //Stop condition
    __delay_ms(200);
    I2C_Master_Start();         //Start condition
    I2C_Master_Write(0x31);     //7 bit address + Read
    PORTD = I2C_Master_Read(0); //Read + Acknowledge
    I2C_Master_Stop();          //Stop condition
    __delay_ms(200);
  }
}

Slave

// PIC16F877A Configuration Bit Settings
// 'C' source line config statements

#include <xc.h>
#include <pic16f877a.h>
#define _XTAL_FREQ 8000000

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG
#pragma config FOSC = XT    // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF   // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF  // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF  // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF    // Low-Voltage In-Circuit Serial Programming Enable bit
#pragma config CPD = OFF    // Data EEPROM Memory Code Protection bit
#pragma config WRT = OFF    // Flash Program Memory Write Enable bits
#pragma config CP = OFF     // Flash Program Memory Code Protection bit
short z;
void interrupt I2C_Slave_Read()
{
  if(SSPIF == 1)
  {
    SSPCONbits.CKP = 0;

    if ((SSPCONbits.SSPOV) || (SSPCONbits.WCOL))
    {
      z = SSPBUF; // Read the previous value to clear the buffer
      SSPCONbits.SSPOV = 0; // Clear the overflow flag
      SSPCONbits.WCOL = 0;  // Clear the collision bit
      SSPCONbits.CKP = 1;
    }

    if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW)
    {
      z = SSPBUF;
      while(!BF);
      PORTD = SSPBUF;
      SSPCONbits.CKP = 1;
    }
    else if(!SSPSTATbits.D_nA && SSPSTATbits.R_nW)
    {
      z = SSPBUF;
      BF = 0;
      SSPBUF = PORTB ;
      SSPCONbits.CKP = 1;
      while(SSPSTATbits.BF);
    }

    SSPIF = 0;
  }
}

void I2C_Slave_Init(short address)
{
  SSPSTAT = 0x80;
  SSPADD = address;
  SSPCON = 0x36;
  SSPCON2 = 0x01;
  TRISC3 = 1;   //Setting as input as given in datasheet
  TRISC4 = 1;   //Setting as input as given in datasheet
  GIE = 1;
  PEIE = 1;
  SSPIF = 0;
  SSPIE = 1;
}

void main()
{
  nRBPU = 0;            //Enables PORTB internal pull up resistors
  TRISB = 0xFF;         //PORTB as input
  TRISD = 0x00;         //PORTD as output
  PORTD = 0x00;         //All LEDs OFF
  I2C_Slave_Init(0x30); //Initialize as a I2C Slave with address 0x30
  while(1);
}

I hope that you understand above programs. Please do comment if you have any doubts.

Download Here

You can download the complete MPLAB program and Proteus simulation files here.

Share this post

  • Firstly above example uses PIC 16F877A while 16F877 is a different microcontroller and above code is tested too.
    This tutorial is intended for beginners/students who are new to these.

    If you want more efficient code for your project you should utilize interrupts for that. That was not in the scope of above tutorial.

  • Pity that this code is not utilizing the power of a true hardware I2C MASTER mode; when working it is the most efficient way to implement I2C; instead it waits for each state to complete; very inefficient; Also PIC16F877 is obsolete now; would be nice to see a newer PIC micro with full I2C MASTER mode ; I am working on it right now but it does not work properly – that’s the reason I came across this page – searching for hints re what I might be doing wrong

  • If i want to send more than one variable from master to slave and save them on diffrent variable on slave
    how i can do it.

  • Great job !! otherwise i am still surprised that it’s working for you.
    + slave should release SCL stretch by setting CKP flag at data reception in this case => SSPSTAT.D/A = true. //data
    + also in this case if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW) after address+write byte reception (0x30), if SCL is kept stretched by slave, master won’t be able to set clock again.

    NB:
    SSPCON.CKP flag In I2C Slave mode:
    SCK release control
    1 = Enable clock
    0 = Holds clock low (clock stretch). (Used to ensure data setup time.)

  • Hello, I am studying the RTC code and did not understand what it means (a)? 0: 1;
    Can someone explain me?

  • Hello, I intend to interface a LCD with PIC16f877 through I2C module. the LCD has a 250 KHz internal clock. the qustion is: i’m I supposed to work in the fast mode ? if so, is this possible only by putting I2C_Master_Init(100000); ? any other considerations should I take when working in fast mode like the slew rate control feature?
    Thank you.

  • Hello sir, i have a project about i2c master as read and two slave as write for send data sensor, i have a problem with send data sensor analog to digital sir (lm35 sensor) on slave, the code data sensor on slave cant working, can you help me sir for learn me to send data with i2c communication.
    Thank you

  • Hi Ligo,
    I’m trying to resue the code but for different set of master and slave MCU.

    Master is getting stuck in wait call. Can you help me with some inputs
    I’m using PIC16F15356 as master and PIC16F1513 as slave.

    Your response would be very helpful

  • Hi Ligo, You won…I found your code very helpful to understand I2C between two PIC microcontroller. Can you please share the code for writing & reading multiple data bytes to & from slave. Many thanks in advance…..

  • Hello, this great tutorial, I was try that code but I have a problem, may I ask you sir ?, I try that code in my project, that tutorial is slave as read, right ? But in my project a slave as write, can you help me sir for give me example slave as write sir ?
    Thank you

  • Above program is tested only in PIC 16F877A. It might also work in other microcontrollers having the same set of register configurations. You can check the datasheet of 16F1789 and do appropriate configurations.

  • Hi,
    thank you very much for this tutorial, it was very useful. I’m anyway having problems in making it work on a different PIC 16F1789. I though it would have worked fine but actually the slave gets stuck in the ISR…and so communication stops because the line remains always busy. I’m not sure if you can help me…or if someone experienced the same problem…

  • Hi. i have made the library of uart. but can u tell me where i can find the libraries of SPI and I2C. i have to make libraries of both. In your SPI library there are just two files c and h. but in I2C file there are no libraries. hoping for your positive response !!!

  • i keep getting the error Target Device ID (0x2080) is a valid Device ID but does not match the expected Device ID (0x9a0) as selected.

    what am i doing wrong?

  • Hi how can I use it if I want to use the PIC as masteer communicating with a slva PCA9685 and not with other PIC

  • Hi, excuse me…..in SPADD mode salve can I write any number like binari or a word?….I have been failed in that register and I don’t have the concept very well…Sorry for my appalling inglish

  • with out using interrupt in slave. can we get the data from master. just one byte of data like read function in master. plz help me. thank you

  • Can you help me out for my problem ?
    Please provide your email address.
    Thanks in advance!!

  • Hii Ligo,
    I want to send character from master to slave by i2c.
    So i have done, following changes.
    Can you tell me any other changes are required ?
    Because i am not getting anytjhing on master/slave!!

    Master main code:
    while(1)
    {
    I2C_Master_Start(); //Start condition
    I2C_Master_Write(0x30); //7 bit address + Write
    data = ‘d’;
    I2C_Master_Write(data); //Write data
    I2C_Master_Stop(); //Stop condition

    __delay_ms(200);
    I2C_Master_Start(); //Start condition
    I2C_Master_Write(0x31); //7 bit address + Read
    PORTD = I2C_Master_Read(0); //Read + Acknowledge
    I2C_Master_Stop(); //Stop condition
    __delay_ms(200);
    }
    }

    In salve any changes are required ?
    Please reply me 🙁

  • Hello Ligo,
    Thanks for the program but, i am not able to see any response on my master as well as salve.
    I just want to send some character from master to slave. For which no input and output is required, right ?
    So just made following changes, is there any other changes required ?
    I dont have to change anything on slave, correct ?
    Please let me know… and help me!!

    In master code:
    unsigned char data;
    while(1)
    {
    I2C_Master_Start(); //Start condition
    I2C_Master_Write(0x30); //7 bit address + Write
    data = ‘r’;
    I2C_Master_Write(data); //Write data
    I2C_Master_Stop(); //Stop condition

    __delay_ms(200);
    I2C_Master_Start(); //Start condition
    I2C_Master_Write(0x31); //7 bit address + Read
    PORTD = I2C_Master_Read(0); //Read + Acknowledge
    I2C_Master_Stop(); //Stop condition
    __delay_ms(200);
    }
    }

  • Sir your project work perfectly with proteus but not with hardware .
    I am using 10k. I am check your code with hardware step by step then I found a problem in this section

    if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW)
    {
    z = SSPBUF;
    while(!BF); ————–> at this line controller stuck
    PORTD = SSPBUF;
    SSPCONbits.CKP = 1;
    }
    please help
    thanxxx

  • This is an excellent tutorial on I2C. Thanks for putting it together.
    It was very helpful how you covered the overall structure of the protocol and the registers. The example code is great as well. Keep up the awesome work!

  • In the receive section for the slave you have “while(!BF)”. At this point clock stretching is enabled (CKP = 0) so how will the buffer ever become full if there is no clock to clock the data in?

  • Hi. Thank you so much for this article. But i have problem with I2C device. What should i write to internet or ask to a shop to find I2C device in this circuit? Have a nice day!

  • I tried implementing your code for Master(with 4×4 Keypad) and Slave with LCD. I didn’t get any output on Proteus simulation. I carefully followed all your instructions but the LCD does not show any keypad presses. What might I be doing wrong?

  • Hello once again. I’m a little confused, the interrupt I2C_Slave_Read() is never called in the slave example? How come?

  • Thank you so much ! these tutorials are very helpful and well explained. Might it be possible to write a tutorial on the SPI communication ?

  • So it is possible to assign an address to a slave? I have been lead to believe that every device comes with its own address for I²C? Or does that not count for microcontrollers?

  • This is a wonderful explanation Thank you for that!
    However, I have a couple of questions:

    I’m trying to connect a Raspberry Pi (Master) to an 18F4550 (Slave) which in turn is connected to an LCD. So I will be sending data from my Pi to the Pic and have them displayed on the LCD. In such a case, would it be enough to simply connect the SDA and SCL pins on both devices? also, in the slave code, you’ve included setting TRIS4 and 5 as inputs. Why is that?
    Thank you.,

  • ” if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW)
    {
    z = SSPBUF;
    while(!BF);
    PORTD = SSPBUF;
    SSPCONbits.CKP = 1;
    SSPM3 = 0; ( why you need SSPM3 = 0 here ??)
    }”

  • Thank you very clear for a newbie like myself to understand. I have come from a different mcu and C compiler, but I am finding the xc8 syntax cleaner, and the documentation is easier to understand as well.

  • I am not that good at programming so anybody can explain this line found at Master Read function

    ACKDT = (a)?0:1;

  • Awesome job my friend!! You outlined, explained, and provided the code for a tough subject to understand on one’s own. Thank you!

  • Dear Ligo, pls Help me..
    i will try above codes on hardware but it was not working, simulation was execute perfectly…
    what i can do, for obtain o/p on hardware…..

  • I NEED CODE IN MP LAB FOR INTERFACING PIC16F18855 WITH RTC THROUGH I2C PROTOCOL

  • CAN I GET A CODE FOR INTERFACING PIC16F18855 WITH DS1307(RTC). PLEASE HELP ME


  • >