This post provides the i2c bit banging code for PIC16F84A microcontroller. As we know, PIC16F84A microcontroller doesn’t have any built in i2c modules, so we have to create it in the software. This code is written in C language using MPLAB with HI-TECH C compiler. You can download this code from the ‘Downloads‘ section at the bottom of this page.
It is assumed that you know how to blink an LED with PIC16F84A microcontroller. If you don’t then please read this page first, before proceeding with this article. It is also assumed that you know how i2c protocol works, if you don’t then please read this page first.
The result of simulating the code in Proteus is shown below.
In the above circuit, RA4 pin is being used as SDA pin and RB0 pin is the SCK pin. Both of these pins are pulled up using 10K resistors as required for i2c protocol. Proteus provides an ‘I2C Debugger Tool‘ which is attached on the SDA and SCK pins in the above circuit. This i2c debugger tool receives all the i2c messages and displays them on the ‘I2C Debug‘ window displayed in above figure. Close up image of this ‘I2C Debug‘ window is shown below in the figure.
In the above figure, ‘I2C Debugger Tool‘ is telling us that first of all it received i2c start bit S. Then a value of 0xA0 was received. After that, there was a NACK bit (named as N in the above figure). After the NACK, a value of 0xFF was there on i2c bus. After that, an ACK was there (named as A) in the above figure, and in the end i2c stop bit (named as P) was received. When this Proteus simulation started then after 54.801usec PIC16F84A started sending this i2c data and stopped at 2.149msec time.
The code for the main function is shown below.
In the main function, firstly i2c pins are initialized using InitI2C() function. Then I2C_Start() function sends a start bit S on i2c bus. Then a value of 0xA0 is written on the i2c bus using I2C_Write_Byte(0xA0); statement. After that, I2C_Read_Byte() function reads a byte from the i2c bus, because there is no slave attached on the i2c bus, that is why RxByte will receive a value of 0xFF. After that, an ACK ‘A‘ is transmitted on i2c bus using I2C_Send_ACK() function. And in the end a stop bit ‘P‘ is transmitted on i2c bus using I2C_Stop() function.