Interfacing PIC16F877A with SSD1306 OLED display

This is an example shows how to write texts on SSD1306 OLED display (128×64 pixel) using PIC16F877A microcontroller. In this project the SSD1306 OLED is configured to work in I2C mode. So, make sure that your SSD1306 OLED display is configured to work in I2C mode, some displays need jumper placing or some soldering.
A small video shows Proteus simulation of this project at the end of the post.

This topic is for interfacing PIC microcontroller devices with limited RAM with SSD1306 OLED display, if the MCU device has sufficient RAM (as an example with more than 1024 byte for 128×64 Pixel display) it is recommended to use the library described in the post below:
SSD1306 OLED Library for CCS C compiler

The SSD1306 OLED display communicates with the master device over I2C mode, SPI mode or 8-bit parallel mode.
Generally the SSD1306 OLED requires a RAM buffer with all screen data, for example if we’ve a 128×64 Pixel display then we’ve to use a buffer of 1024 bytes (128×64/8). The problem is when we want to write a single pixel we’ve to overwrite another 7 pixels, therefore we need to know the status of the other 7 pixels.
Another problem with this type of displays (the SSD1306 controller chip) is it doesn’t allow any reading from its RAM when it works in serial mode (I2C or SPI).

In this example the SSD1306 works in I2C mode and the PIC16F877A has a limited RAM of 368 bytes which means using a buffer of 1024 byte is not possible.

I wrote a small driver for the SSD1306 OLED in order to be able to write texts, this driver works with SSD1306 displays with resolution of 128×64, 128×32 and 96×16 pixel, it splits the 128×64 pixel display into 21 columns and 8 rows, the 128×32 pixel into 21 columns and 4 rows, the 96×16 pixel into 16 columns and 2 rows. So in a display of 128×64 pixel we can write up to 168 character (21×8). The driver has a built-in font of 5×7.

SSD1306 OLED display driver functions:
This is a list of all user functions of the driver.

SSD1306_Init(vccstate, i2caddr); initializes the display, i2caddr is the display address.

SSD1306_StartScrollRight(start, stop); scroll right
SSD1306_StartScrollLeft(start, stop); scroll left
SSD1306_StartScrollDiagRight(start, stop); scroll diagonal right
SSD1306_StartScrollDiagLeft(start, stop); scroll diagonal left
SSD1306_StopScroll(); stop scrolling

SSD1306_ClearDisplay(); clears the display.
SSD1306_FillScreen(); fills the whole screen.
SSD1306_Dim(dim); dim the display, dim can be 1 (true) or 0 (false).
SSD1306_InvertDisplay(i); inverts the display, i can be 1 or 0.

SSD1306_GotoXY(x, y); move cursor to position (x, y).
SSD1306_PutC(c); draws a character c on the screen position (x, y).
SSD1306_PutCustomC(char *c); draws a custom character c on the screen. c dimension should be 5×7.

The library supports 3 types of the SSD1306 OLED display depending on the screen resolution, these types are: 128×64 pixel, 128×32 pixel and 96×16 pixel. The default type is: 128×64 pixel.
If you want to use it with the 128×32 pixel type just define it in the main code as:
#define SSD1306_128_32

and if the 96×16 pixel type is used, the definition becomes:
#define SSD1306_96_16

Note that the library doesn’t support defining both previous types at once and compiling a code with the two definitions (#define SSD1306_128_32 and #define SSD1306_96_16) will give an error.

Interfacing PIC16F877A with SSD1306 OLED display:

Hardware Required:

  • PIC16F877A microcontroller
  • SSD1306 OLED display
  • 20MHz crystal oscillator
  • 2 x 22pF ceramic capacitor
  • 10k ohm resistor
  • 5V source
  • Breadboard
  • Jumper wires

SSD1306 OLED display with PIC16F877A microcontroller circuit

The Circuit:
Project circuit diagram is shown below.

PIC16F877A SSD1306 OLED display interfacing circuit

(All grounded terminals are connected together)

The PIC16F877A microcontroller has one hardware I2C module with SDA on pin RC4 (#23) and SCL on pin RC3 (#18). The SDA pin of the MCU is connected to the SDA pin of the display and the SCL pin of the MCU is connected to the SCL pin of the display.
The reset pin of the display is connected to pin RD4 (#27) of the microcontroller.

The SSD1306 OLED display DC pin is connected to VDD which means the I2C slave address of the display is 0x7A.

The Code:
The C code below is for CCS C compiler, it was tested with version 5.051.

To be able to compile the C code below with no error, a driver for the SSD1306 OLED display is required, it’s name is SSD1306.C, its download link is below:
SSD1306 OLED display driver

after the download, add the driver file to project folder or CCS C compiler drivers folder.

CCS C code:

PIC16F877A + SSD1306 OLED Proteus simulation:
This project can be simulated with Proteus simulation software, but it will not give a prefect result as the real hardware circuit. The simulation file can be downloaded from the link below, use Proteus version 8.6 or higher to open it:
PIC16F877A + SSD1306 OLED

and the video below shows the simulation result:

Other examples with PIC16F877A microcontroller and SSD1306 OLED display:
PIC16F877A with DHT11 sensor and SSD1306 OLED
PIC16F877A with DHT22 (AM2302) sensor and SSD1306 OLED display
Real time clock with PIC16F877A, SSD1306 OLED and DS1307
Temperature monitor with PIC16F877A, SSD1306 and DS18B20 sensor
Interfacing PIC16F877A with SSD1306 OLED and DS3231 RTC

15 thoughts on “Interfacing PIC16F877A with SSD1306 OLED display”

  1. Hola, una pregunta, de que depende el FAST=400000? en las instrucciones de la libreria dice que debe trabajarse a 100000 y en varios proyectos usas 400000 y 800000
    Muchas gracias por el aporte

    1. 400000 means the clock frequency in Hz (400000 = 400kHz). The higher clock frequency the faster data transfer.
      The setting of the clock frequency depends of the slave device, you’ve to put a frequency where the slave device is able to work with.

    1. The SSD1306 OLED board should have a 3V3 regulator to supply the display with 3V3.
      I2C Communication is an open drain/collector which means there are two pull-up resistors that raise the lines to 3.3V (or 5V …). These resistors (10k ohm each) are placed on the SSD1306 board and they are connected to 3V3 line that comes from the regulator.

  2. Hi bro.
    Can you sent to me hex file of this project.
    When I built your project with ccs5.015 and wrote to pic, It don’t display any thing.

    1. Miguel C. Garcia

      Hi, I was the same issue, but I solved it changin the SSD1306_I2C_ADDRESS it was 0x7A and I changed by 0x78 and wala it works.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top