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
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
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.
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 ?