Real time clock with alarms using PIC18F46K22 and DS3231

This post shows how to build real time clock/calendar with 2 alarm functions using PIC18F46K22 microcontroller and DS3231 RTC chip. Time, date and alarms are displayed on 20×4 LCD screen.
In the circuit there will be 3 push buttons for setting time, date and alarms, and one LED for indicating the alarms when occurred.
The compiler used in this project is CCS PIC C.

The DS3231 RTC has built-in two alarm functions and a temperature sensor with a resolution of 0.25 °C and an accuracy of ±3 °C. Also, chip temperature will be displayed on the 20×4 LCD.

PIC18F46K22 MCU with DS3231 and LCD circuit

Hardware Required:

  • PIC18F46K22 microcontroller   —->  datasheet
  • 20×4 LCD screen
  • DS3231 board   —>  DS3231 datasheet
  • 3 x push button
  • 2 x 330 ohm resistor
  • LED
  • 10k ohm variable resistor or potentiometer
  • 3V coin cell battery
  • 5V power source
  • Breadboard
  • Jumper wires

PIC18F46K22 with DS3231 and LCD circuit:
The following image shows project hardware circuit diagram.

PIC18F46K22 DS3231 and LCD circuit

All the grounded terminals are connected together.

The DS3231 board is supplied with 5V as the 2004 LCD and the PIC18F46K22 microcontroller, there are 3 data lines connected between this board and the microcontroller, SCL line is connected to pin RC3 (#18), SDA line is connected to pin RC4 (#23) and INT (interrupt) line is connected to external interrupt pin RB0 (#33). The DS3231 interrupts the microcontroller when there is an alarm (alarm 1 or alarm 2).

In the circuit there are 3 push buttons: B1, B2 and B3. These buttons are used to set time, date and alarms. Time and date are set with B1 and B2 where button B1 selects time or date parameter (time parameters: hours and minutes; date parameters: day of the week, date, month and year) and B2 increments the selected parameter. Buttons B3 and B2 set alarm 1 and alarm 2 parameters (hours, minutes and ON/OFF), button B3 selects the parameter and B2 increments the selected parameter.

Also, there is an LED connected to PIC18F46K22 pin RB4 (#37), this LED is used as an alarm indicator (alarm 1 or alarm 2), so if there is an alarm, the DS3231 pulls down the INT line (RB0) which interrupts the microcontroller and the microcontroller turns the LED ON, here button B2 turns both the LED and the occurred alarm OFF.

The 20×4 LCD screen is connected to the PIC18F46K22 microcontroller as follows:
RS —> RD0 pin
RW —> RD1 pin
E  —> RD2 pin
D4 —> RD3 pin
D5 —> RD4 pin
D6 —> RD5 pin
D7 —> RD6 pin
VSS, D0, D1, D2, D3 and K are connected to circuit GND (ground).
VEE to the variable resistor (or potentiometer) output pin.
VDD to +5V and A to +5V through 330 ohm resistor.

VEE pin is used to control the contrast of the LCD. A (anode) and K (cathode) are the back light LED pins.

In this project the PIC18F46K22 microcontroller runs with its internal oscillator @ 8 MHz, MCLR pin is configured as an input pin.

PIC18F46K22 with DS3231 and LCD C code:
The following C code is for CCS C compiler, it was tested with version 5.051.

To be able to compile the C code below, a driver (library) for DS3231 RTC is required, its full name (with extension) is DS3231.C, download link is the one below:
DS3231 CCS C driver

After the download, add it to project folder or CCS C drivers folder (for example C:\Program Files (x86)\CCS\Drivers).

For more information about DS3231 driver for CCS C compiler, visit the following post:
DS3231 RTC driver for CCS C compiler

I2C Bus (using I2C1 module) is initialized in the code as shown below at clock frequency of 100kHz:

Functions used in the code:
int1 debounce (): this function is for button B1 debounce, returns 1 if button is debounced.

void dow_print(): displays day of the week (Monday, Tuesday …) on the LCD.

void wait(): this function is just a delay of 500 ms except that it can be interrupted by the three push buttons (B1, B2 and B3). In this function Timer0 module is used to count the 500 milliseconds, it is used as 16-bit timer with prescaler = 16 (==> 1 tick every 8 microseconds ==> 62500 x 8 = 500000 us = 500 ms).

int8 edit(int8 x_pos, int8 y_pos, int8 parameter): this function is for setting the real time clock, returns the edited parameter.

void alarms_edit(int8 _alarm): this function is for setting the status of alarm 1 and alarm 2 (ON or OFF). If the variable _alarm = 1 the alarm will be set is alarm 1, and if _alarm = 2 the alarm will be set is alarm 2.

Rest of code is described through comments.

Full CCS C code:

The result of this project should be near to the one shown in the following video where PIC16F877A microcontroller is used:

Proteus simulation:
The following video shows Proteus simulation of this project.
Note that Proteus simulation circuit is not the same as real hardware circuit, project hardware circuit is shown above.

PIC18F46K22 + DS3231 RTC + 20×4 LCD

3 comments

  1. hI,
    tHANS for your good tutorials.
    Would u please let me know , what should i change in this code if i use MSSP2 instead of MSSP1 for this “Real time clock with alarms using PIC18F46K22 and DS3231”?
    Beacause i want to use MSSP1 for SPI(to display time/date in P10 DMD Module) and MSSP2 for this i2c clock(to get clock time/date for DMD) in same PIC18F46K22.
    Please help..
    tnx

    1. Yes you can use MSSP2 just in #use I2C change I2C1 to I2C2 (line 27), so it becomes:
      #use I2C(MASTER, I2C2, SLOW = 100000, STREAM = DS3231_STREAM)

Leave a Reply

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