I²C Communication with PIC Microcontroller – MPLAB XC8
Contents
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 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 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.
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
- 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
- Bit 0 ~ 3 SSPM0 ~ SSPM3 : These are synchronous serial port mode select bits.
- 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
- 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
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.
Thank you so much works perfectly
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
I look at the same. Send more variable to the Slave
You can understand and make necessary changes to the above program.
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.
? is conditional operator in C
(condition)?true part;false part
same as if(condition) {true part;} else {false part};
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?
Thanks. Work fine!!
proteus file is not working properly.
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.
how if slave as transmitting only sir ?
thank you, It is very helpful to me, hehe
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…..
Could you please take a look at the next problem related with your post?
https://electrosome.com/topic/i2c-pic18f4550-to-pic18f4550/
In this tutorial slave is transmitting and receiving data. In I2C communication always master has to initiate data transfer.
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
You can download it above.
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
RSEN SEN and other bits are not taken by my xc8 compiler it is giving error of “UNIQUE IDENTIFIER https://uploads.disquscdn.com/images/d49aa46689c78312b5a82b7805e2b87eef818dfa8bfc4af20af2c63600defb4b.png “
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);
}
}
Cant find proteus simulation files
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?
Sorry, I don’t understand your question. Please use our forums ( https://electrosome.com/forums/ ) if your doubt is outside the scope of above article.
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!
Okay, thanks, one more thing: you can only read one byte with this code,right?
I can’t help you unless you provide complete details including the code.
Kindly use our forums (https://electrosome.com/forums/) for that.
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?
Thanks for it.
Acutually it was unnecessary. I removed it now.
Thanks for the feedback. I will try my best to make it possible based on my free time.
I would like to invite you to write some articles here. Just drop a mail to [email protected].
You need to take care of voltage levels.
Those pins are set as inputs as prescribed in the datasheet.
Kindly use our forums ( https://electrosome.com/forums/ ) for asking doubts outside the scope of above article.
Sorry, that was a mistake. I removed it now.
Why do you set SSPM3 to 0? Making sure only 7-bit addresses are used?
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 ?
Sir pls give me master to slave mplab program for pic24hj256gp210
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 ??)
}”
Thanks for the feedback.
Thank you now that was a tricky one but it makes sense now 🙂
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.
It means.
if(a == 1)
ACKDT = 0;
ese
ACKDT = 1;
Thanks for the feedback.
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!
Check the pullup resistors of I2C lines.
Thanks for the feedback. 🙂
Yes, separate project files are required.
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…..
DO WE NEED TO HAVE SEPARATE PROJECT FILES FOR MASTER AND SLAVE?
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
You’re a legend. 😉
It is 100% working. It may freeze if the slave device is not responding.
Not working! The program freezes in Wait function