DS3231 RTC driver for CCS C compiler

This topic shows how to make a simple real time clock using DS3231 and PIC16F877A microcontroller where time and date are displayed on 20×4 LCD screen.
The compiler used in this example is CCS C.

General Description (from the DS3231 datasheet):
The DS3231 is a low-cost, extremely accurate I2C real-time clock (RTC) with an integrated temperature compensated crystal oscillator (TCXO) and crystal.
The device incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted. The integration of the crystal resonator enhances the long-term accuracy of the device as well as reduces the piece-part count in a manufacturing line.

The DS3231 RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year.

The following image shows a typical operating circuit of the DS3231:

DS3231 typical operating circuit

DS3231 RTC driver (library) for CCS C compiler:
Library functions are listed below.

void RTC_Set(RTC_Time *time_t): this function sets time and date (writes time and date to the DS3231) where the variable time_t of type struct (structure) collects the following integer variables:
seconds, minutes, hours, dow, day, month and year.
Where dow is day of the week (Monday, Tuesday …) and day is month day.
seconds and minutes range: 0 – 59
hours range: 0 – 23 (24-hour format)
dow range: 1 – 7 (1 equals Sunday, 2 equals Monday …)
day range: 1 – 31 (depends on month)
month range: 1 – 12 (1 equals January)
year range: 0 – 99.

RTC_Time *RTC_Get(): reads time and date from the DS3231, this function returns them as a variable of type struct (same as the previous function).

void Alarm1_Set(RTC_Time *time_t, al1 _config): sets alarm1 of the DS3231 where the variable time_t of type struct and _config is alarm1 configuration which should be one of the following:
ONCE_PER_SECOND  —> alarm every 1 second
SECONDS_MATCH  —> alarm when seconds match
MINUTES_SECONDS_MATCH  —> alarm when minutes and seconds match
HOURS_MINUTES_SECONDS_MATCH  —> alarm when hours, minutes and seconds match
DATE_HOURS_MINUTES_SECONDS_MATCH  —> alarm when date (month day), hours, minutes and seconds match
DAY_HOURS_MINUTES_SECONDS_MATCH  —> alarm when day (week day), hours, minutes and seconds match.

RTC_Time *Alarm1_Get(): reads time and date of alarm1, this function returns them as a variable of type struct.

void Alarm1_Enable(): enables alarm1 (writes 1 to A1IE bit).
void Alarm1_Disable(): disables alarm1 (writes 0 to A1IE bit).

int1 Alarm1_IF_Check(): returns 1 (TRUE) if alarm1 occurred, otherwise it returns 0 (FALSE).
void Alarm1_IF_Reset(): resets alarm1 flag bit (writes 0 to A1IF bit).
int1 Alarm1_Status(): returns 1 if alarm1 is enabled and 0 if disabled (reads A1IE bit).

void Alarm2_Set(RTC_Time *time_t, al2 _config): sets alarm2 of the DS3231 where the variable time_t of type struct and _config is alarm2 configuration which should be one of the following:
ONCE_PER_MINUTE —> alarm every 1 minute
MINUTES_MATCH  —> alarm when minutes match
HOURS_MINUTES_MATCH  —> alarm when hours and minutes match
DATE_HOURS_MINUTES_MATCH  —> alarm when date (month day), hours and minutes match
DAY_HOURS_MINUTES_MATCH  —> alarm when day (week day), hours and minutes match.

RTC_Time *Alarm2_Get(): reads time and date of alarm2, this function returns them as a variable of type struct.

void Alarm2_Enable(): enables alarm2 (writes 1 to A2IE bit).
void Alarm2_Disable(): disables alarm2 (writes 0 to A2IE bit).

int1 Alarm2_IF_Check(): returns 1 if alarm2 occurred, otherwise it returns 0.
void Alarm2_IF_Reset(): resets alarm2 flag bit (writes 0 to A2IF bit).
int1 Alarm2_Status(): returns 1 if alarm2 is enabled and 0 if disabled (reads A2IE bit).

void IntSqw_Set(INT_SQW _config): this function configures INT/SQW pin of the DS3231 where _config should be one of the following:
OUT_OFF  —> output is off (internally attached to ground)
OUT_INT  —> output is active low interrupt when alarm (alarm1 or alarm2)
OUT_1Hz  —> output is a square wave with frequency of 1Hz
OUT_1024Hz  —> output is a square wave with frequency of 1024Hz
OUT_4096Hz  —> output is a square wave with frequency of 4096Hz
OUT_8192Hz  —> output is a square wave with frequency of 8192Hz

void Enable_32kHZ(): enables 32kHz output (32kHz pin is open drain).
void Disable_32kHZ(): disables 32kHz output (internally attached to ground).

OSC_Start(): enables the DS3231 oscillator (writes 0 to ESOC bit).
OSC_Stop(): disables the DS3231 oscillator (writes 1 to ESOC bit).

int16_t Get_Temperature(): returns chip temperature. Temperature is stored in hundredths C (output value of “3125” equals 31.25 °C).

uint8_t RTC_Read_Reg(uint8_t reg_address): this function returns the value stored in register of address reg_address.
void RTC_Write_Reg(uint8_t reg_address, uint8_t reg_value): writes reg_value to register of address reg_address.

DS3231 driver for CCS C compiler download:
Driver source file download link is below, installation of this driver is easy, just add it to project folder or CCS C drivers folder (for example C:\Program Files (x86)\CCS\Drivers). Driver name is: DS3231.c.
DS3231 CCS C driver

DS3231 RTC Library Example:
This is a small example that shows how to use this library.
In this example PIC16F877A microcontroller is used, hardware circuit diagram is shown below.

Interfacing DS3231 with PIC16F877A and LCD circuit

All grounded terminals are connected together.

The 20×4 LCD screen (4 rows and 20 columns) is used to display time and date where:
RS —> pin RD0
RW —> pin RD1
E   —> pin RD2
D4 —> pin RD3
D5 —> pin RD4
D6 —> pin RD5
D7 —> pin RD6
VSS, D0, D1, D2, D3 and K are connected to circuit ground
VEE to the variable resistor (or potentiometer) output
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 PIC16F877A microcontroller runs with 8 MHz crystal oscillator.

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

To be able to compile project C code with no error, a driver (library) for the DS3231 RTC is required, download link is above.
After you download the driver file which named DS3231.c, add it to your project folder.

Proteus simulation as well as hardware circuit of the example should give the result shown below (RTC starts updating immediately).
Note that Proteus simulation circuit is not the same as real hardware circuit, project hardware circuit is shown above.

Interfacing DS3231 with PIC16F877A and LCD Proteus simulation circuit

PIC Projects where DS3231 RTC driver is used:
Real time clock with alarms using PIC18F46K22 and DS3231

Leave a Reply

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