PIC MCU with I2C LCD and DS3231/DS1307 RTC | mikroC Projects

This project shows how to build a simple real time clock using PIC12F1822 microcontroller and DS3231 RTC chip (or DS1307 RTC) where time and date are displayed on 16×2 LCD. The DS3231 as well as the 16×2 LCD are connected to the same I2C bus with the PIC12F1822 microcontroller. The LCD is provided with PCF8574 I/O expander which makes it an I2C LCD. This project works also with DFRobot I2C LCD displays.
The compiler used in this project is mikroElektronika mikroC PRO for PIC.

In this project the DS3231 (or DS1307) and the I2C LCD share the same I2C bus which means the SDA lines of the two devices are connected together and the SCL lines also, this connection minimizes number of pins used.
Time and date are displayed on the 16×2 LCD screen and they can be set with two push buttons connected to the PIC12F1822 microcontroller. With two pins for the I2C bus and two other pins for the push buttons, the microcontroller will use 4 pins (if internal oscillator is used).

Hardware Required:
The components required for this project are listed below.

The PIC12F1822 microcontroller has one hardware I2C module with SDA on pin RA2 (#5) and SCL on pin RA1 (#6).

The I2C LCD and the DS3231 (or DS1307) board share the same I2C bus which means the SDA line of the I2C LCD (presented by PCF8574) and the DS3231 RTC chip are connected together with RA2 pin of the PIC12F1822 MCU, the SCL line of the I2C LCD and the SCL line of the DS3231 are connected together with RA1 pin of the PIC12F1822 MCU.

The two push buttons in the circuit are used to set time and date of the real time clock, button 1 (B1) is connected to RA5 pin (#2) and button 2 (B2) is connected to RA4 pin (#3) of the PIC12F1822 MCU.

PIC12F1822 internal oscillator is used (@ 8MHz) and MCLR pin (RA3) is configured as an input pin.

Interfacing PIC12F1822 MCU with I2C LCD and DS3231/DS1307 C code:
The following C code is for mikroC PRO for PIC compiler, it was tested with version 7.2.0.

after the download, add the library file (I2C_LCD.c) to project folder.

The I2C LCD driver file is included with the line:#include “I2C_LCD.c”

The hardware I2C module of the PIC12F1822 is initialized with a clock frequency of 100KHz (100000Hz):I2C1_Init(100000);

The I2C LCD is initialized with an I2C address of 0x4E:LCD_Begin(0x4E);

The two buttons are connected to RA4 and RA5, they are defined as:

C

1

2

3

// button definitions

#define button1 RA5_bit // button B1 is connected to RA5 pin

#define button2 RA4_bit // button B2 is connected to RA4 pin

Internal weak pull-ups are enabled for pin RA4 and pin RA5 with the following lines:

C

1

2

3

// enable RA4 and RA5 internal pull ups

NOT_WPUEN_bit=0;// clear WPUEN bit (OPTION_REG.7)

WPUA=0x30;// WPUA register = 0b00110000

Functions used in the C code:The RTC chip (DS1307 or DS3231) works with BCD format only, to convert BCD to decimal and vise versa I used the 2 functions below. Before displaying (after reading from RTC IC), the data have to be converted from BCD to decimal, and before writing to the RTC IC (after editing the parameters) the data have to be converted from decimal to BCD:char bcd_to_decimal (char number);char decimal_to_bcd (char number);
Each function returns the converted value of the variable number.

void RTC_display() : displays time and date, before printing time and date on the screen, they are converted from BCD format to decimal format using the function bcd_to_decimal(char number) .

char edit(char x, char y, char parameter) : I used this function to edit time and date parameters (minutes, hours, date, month and year). I used a variable named i to distinguish between the parameters:
i = 0, 1 : hours and minutes respectively
i = 2, 3, 4: date, month and year respectively

After the edit of time and date, the data have to be converted back to BCD format using the function decimal_to_bcd(char number) and written to the RTC chip.

void delay() : this small function works as a delay except that it can be interrupted by buttons B1 (connected to RA5) and B2 (connected to RA4). When called and without pressing any button the total time is approximately 250 milliseconds. With this function we can see the blinking of the selected parameter with a frequency of 2 Hz. So a delay of 250ms comes after the print of the selected parameter and after that delay, 2 spaces are printed which make the parameter disappears from the screen and another 250ms delay comes after the print of the 2 spaces.

In this function I used Timer1 module (16-bit timer) for the 250 ms delay. Timer1 module is configured to increment by 1 every 4 microseconds (1 tick per 4 us). That means Timer1 input clock frequency is 250kHz. The configuration is shown below: