Real time clock and calendar using DS3231 and PIC16F877A – CCS C

Interfacing PIC16F877A with DS3231

The DS3231 is a low cost , extremely accurate real time clock with a built-in crystal oscillator. The characteristics of the DS3231 make it one of the best choices for real time clock chips.
This project shows how to build is simple real time clock and calendar (RTCC) using PIC16F877A microcontroller and DS3231.
The DS3231 uses I2C protocol to interface with the master device which is in our example the PIC16F877A which has one I2C module.
The I2C protocol uses only two lines: SCL (Serial Clock) and SDA (Serial Data) which are in the PIC16F877A RC3 and RC4 respectively.

Simple real time clock and calendar using DS3231 and PIC16F877A circuit:

The 16×2 LCD has 7 data lines which are connected to pins RD0~6, the DS3231 SCL pin is connected to pin RC3 (#18) and SDA is connected to pin RC4 (#23) of the PIC16F877A.
In the circuit there are 2 push buttons (B1 & B2) connected to pin RB0 and pin RB1, the two push buttons are used to set the time as well as the calendar parameters. The button B1 selects the parameter and B1 increments the selected parameter as shown in the videos below.
The 3V cell battery is used as a backup to keep time and date running in case of main power failure. The circuit can work without this battery but its pin (#14) has to be grounded.
In this example the PIC16F877A runs with 8MHz crystal oscillator.

Simple real time clock and calendar using DS3231 and PIC16F877A CCS C code:
The following C code was tested with CCS PIC C compiler version 5.051.
The hardware I2C module of the PIC16F877A is initialized and configured using the function below with a speed of 100KHz:#use I2C(master, I2C1, FAST = 100000)master: set the microcontroller to the master mode
I2C1: use first I2C module.
The DS3231 works with BCD format only and to convert the BCD to decimal and vise versa I used the following functions (example for minute variable):minute = (minute >> 4) * 10 + (minute & 0x0F); // Convert BCD to decimalminute = ((minute / 10) << 4) + (minute % 10); // Convert decimal to BCD
The complete C code is the one below.