Using Real Time Clock (RTC) DS3231 with 8051 Microcontroller

You might be seeing a wall clock running with a 1.5V battery or a digital watch running with lithium or silver oxide. But, an interesting thing is, if you want to tick a clock in real time applications, the only solution is to use RTC (Real Time Clock) to get Date and Time.

In the previous tutorial, I have explained how to use RTC DS3231 with microcontroller and display date and time on LCD.

In this article, I will show how to display date and time on PC using 8051 serial communication.

RTC Schematic of DS3231

Interfacing RTC DS3231 with 8051 Microcontroller using Serial Communication

RTC code for DS3231

This embedded C program evaluates the working of DS3231 RTC with 8051 Microcontroller and displays time and date on PC.

#include<reg51.h>
#include"header.h"
unsigned char stringvalue[20];       //String to be displayed on PC
void main()
{
  
Baudrate_9600( );                 //9600 baud rate (8 data bits, 1start and 1 stop bit)//
msdelay(2000);
PC_Write(" DS3231 RTC interfacing with 8051 \r\n");
PC_Write(" Written By Codrey.com");
PC_Write ("\r\n "); 	
msdelay(2000);	
PC_Write ("\r\n  "); 
PC_Write("Initializing DS3231 RTC");
PC_Write ("\r\n \r\n "); 	
Initialize_RTC( );                  //Initializing RTC DS3231
setTime( 10,20,25,0,0);            //Set Hour,Minute,Second 
setDate( 2,23,05,18);             //Set Day,Date,Month,Year
  while(1)                     
   {
     ReadTime( );               //Gets the time from DS3231   
     ReadDate();               //Gets the Day,month and year
   }
}

The below code snippet shows the macros used for RTC registers. The addresses correspond to the slave address of DS3231, second, minute, hour, second, date, month, and year, hour format.

#include<reg51.h> 
#define RTC_Address                0x68             //Slave address of ds3231                                         
                                                  
#define DS3231_Read  (RTC_Address << 1) | 0x01)      //Read address for RTC            
#define DS3231_Write               ((RTC_Address << 1) & 0xFE)      //Write address for RTC               

#define date                        0x04                              
#define month                       0x05                            
#define year                        0x06                                                                  
#define second                      0x00 
#define minute                      0x01 
#define hour                        0x02 
#define control_Register            0x0E      
#define day                         0x03           
#define Status_Register             0x0F                                              
#define _24_hour_format         0 
#define _12_hour_format         1 
#define am                      0 
#define pm                      1

The below code shows the macros used for i2c communication with 8051.

#include<reg51.h>
#define SDA_OUT          P1=0x00                  // Configuring Port 1 as Output
#define SDA_IN              P1=0XFF              // Configuring Port 1 as Input
sbit SCL=P1^4;                                  //SCL connected to Port 1.4 of 8051
sbit SDA=P1^5;                                 //SDA connected to port 1.5 of 8051
#define SCL_ENABLE       SCL=1                   //Make the SCL HIGH
#define SCL_DISABLE      SCL=0                   //Make the SCL LOW
#define SDA_ENABLE       SDA=1                   //Make the SDA HIGH
#define SDA_DISABLE      SDA=0                   //Make the SDA LOW

The below code explains the serial communication with 8051 and RTC.

#include<reg51.h>
void PC_Write(unsigned char *str);
void PC_Write_SendByte(unsigned char d);
void msdelay(int);

/* A Function to send a string to the PC terminal */
void PC_Write(const unsigned char *str)	
{  
   while(1)
   {  
      if(*str =='\0') break;
      PC_Write_SendByte(*str++);
      msdelay(10);		 
   }
}
/*A Function to send a single byte to PC*/

void PC_Write_SendByte(unsigned char d)
{  
SBUF=d;             //Put single byte in SBUF (serial Buffer memory)
while(TI==0);       //Wait until the byte is transmitted from serial buffer to PC
TI=0;               //clear TI flag to send next byte to the SBUF    	   
}
/*This function converts a integer value of RTC to ascii value */
/*The purpose of this function is to convert the integer value of RTC to string*/

/*Note: LCD only display strings*/

void Convert_Int_To_String(unsigned int intvalue, unsigned char *inttoascii )
{
unsigned char i=0, k=0, finalstring[10];
unsigned char g1=0, g2=0;
do
  {
   finalstring[i] = (intvalue%10) + 0x30;     /*Converting integer to ascii format*/
   intvalue = intvalue/10;                           /*Divide the integer value*/
            i++;                                   /*increment the count*/
  }while(intvalue!=0);                     /*Loop untill all integers are converted to ascii*/
  
      
for (g1 = i-1; g1 >= 0; g1--)              /*Reversing the array for original ascii format*/   
      {	
      inttoascii[g2] = finalstring [g1];
      g2++;
    if (g1 == 0)
        break;
      }
   inttoascii[g2] = '\0';                 /*Placing Null for the last character*/                  
}

/* This function generates baud rate of 9600 bits per second */

/*Displays serial character on to the PC hyper terminal*/

void Baudrate_9600 (void )
{
 /*--------------------------------------
  Set serial port for 9600 baud at
  11.0592 MHz.   
  ------------------- -------------------*/
  SCON = 0x50;              /*Sets the Serial Control Register*/
  TMOD |= 0x20;             /*Configuring the Timer register in Timer mode*/
  TH1   = 0xFD;             /*Higher byte of Timer 1*/
  TR1   = 1;                /*This will start the timer 1 in run mode*/    
  P3=0X03;                  /*Setting the TXD pin*/  
}

 

The header file has been created for accessing the global variables.

#include<reg51.h>
extern void msdelay (int milli_sec);
extern void Baudrate_9600(void);                                   
extern void Convert_Int_To_String(unsigned int intvalue, unsigned char *inttoascii);
extern void PC_Write(unsigned char *str);
extern void PC_Write_SendByte(unsigned char d);
extern unsigned char Convert_BCD_DECIMAL(unsigned char val);                       
extern unsigned char Convert_DECIMAL_BCD(unsigned char val);    
extern unsigned char stringvalue[20];
extern unsigned char RTCsec,RTChour,RTCmonth,RTCyear,RTCday,RTCdate,RTCmin;
extern void msdelay(int milli_sec);
/*Delay generation of millisecond with for loop*/

The delay function has been used to set some lag for sending byte by byte to PC.

void msdelay(int milli_sec)
{
unsigned char j ;
for(;milli_sec>0;milli_sec--)
  {
    for(j=255;j>0;j--);
        for(j=232;j>0;j--);
  }
}

Proteus Simulation

Using Real Time Clock (RTC) DS3231 with 8051 Microcontroller - Proteus Schematic

Conclusion

I hope you understand how to use Real Time Clock (RTC) to display the date and time on the serial terminal.

There are multiple ways to monitor the data. It might be an LCD, PC or a serial debugger.

This DS3231 RTC code is tested on 8051 microcontroller. The date and time will be shown on the serial terminal at 9600 baud rate. The software can be putty, real term, dock light, and hyper terminal, etc.

1 Comment

  1. Hi!
    How can i stop the clock and using the serial communication to set a new time then continuing the clock ? can it be done ?

Leave a Reply

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