Make Digital Clock use DS3231 RTC module, PIC16F877A microcontroller and mikorC compiler - Part 2
In this tutorial we will learn how to interfacing DS3231 RTC Module with PIC Microcontroller. DS3231 RTC module is Real Time Clock module. Here I am use PIC16F877A Microcontroller and LM16x2 Lcd display. You can watch the following video or read the written tutorial below.
In our previous tutorials I am showing how to make digital clock use Microcontroller. The first question that comes here is why we actually need a separate RTC for our digital clock. When the Microcontroller itself has built-in timekeeper. Well the point is that the RTC module runs on a battery and can keep truck of the time even if we disconnect the main power.
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 of the device is interrupted.
The RTC module maintains second, minute, hour, day, date and year information. The date at end of the month is automatically adjusted for month with fewer than 31 days, including corrections for leap year. The clock operates in either the 24-hour and 12-hour format with an AM/PM indicator.
This our second part of DS3231 RTC module interfacing. You can read 1st Part of DS3231 RTC module interfacing.
Circuit Schematic:
Programming:
Once we connect the module we need to program the Microcontroller to working with real time clock (RTC) module. However, when it comes to programming a communication between Microcontroller and RTC module.
I am use MikroC PRO for PIC compiler for code editing. The mikroC PRO for PIC is a powerful, feature-rich development tool for PIC microcontrollers. It is designed to provide the programmer with the easiest possible solution to developing applications for embedded systems, without compromising performance or control.
Here first time we define Lcd module connections. The RS pin of Lcd is connected to RB0 pin of Microcontroller. The EN pin of Lcd is connected to RB1 pin of Microcontroller. Next, D4 to D8 pin of Lcd is connected to RB2 to RB5.
Then we write a code for I2C communication between Microcontroller and DS3231 RTC module. The Microcontroller read the RTC module of specific locations
Show the address map for the DS3231 timekeeping registers.
The timekeeping register is width 8-bit. It contain BCD ( Binary Coded to Decimal ) format of time
Next, we write a function for MSB(Most Segnificant Bit) and LSB( Lest Segnificant Bit).
In main function we initialize I2C communication with 100KHz and Lcd module.
Other part of digital clock use DS3231 RTC module
- 1st part of DS3231 RTC module interfacing
- 3rd part of DS3231 RTC module interfacing
- 4th part of DS3231 RTC module interfacing
Source Code
// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// end lcd module connection9
unsigned short ds3231_read(unsigned short address){ // ds3231 RTC module read
unsigned short read_data;
I2C1_Start(); // Start I2C signal
I2C1_Wr(0xD0); // Device address + W
I2C1_Wr(address); // Data address
I2C1_Repeated_Start();
I2C1_Wr(0xD1); // Device address + R
read_data=I2C1_Rd(0); // no acknowladge
I2C1_Stop(); // Stop I2C signal
return(read_data); // return read data
}
// ds3231 RTC module write
unsigned short ds3231_write(unsigned short address, unsigned short write_data){
I2C1_Start(); // I2C start signal
I2C1_Wr(0XD0); // Device address + W
I2C1_Wr(address); // Data adress
I2C1_Wr(write_data); // Data write
I2C1_Stop(); // stop I2C signal
}
unsigned char LSB(int x){ // Right digit of times
return((x & 0x0F) + '0');
}
unsigned short MSB(int x){ // Left digit of times
return((x>>4) + '0');
}
int second;
int minute;
int hour;
char time[]="00:00:00"; // time arrey
short set;
unsigned short set_count = 0;
void main() {
Lcd_Init(); // Initialize Lcd module
I2C1_Init(100000); // Initialize I2C signal at 100KHz
I2C1_Start(); // Start I2C signal
Lcd_Cmd(_LCD_CLEAR); // Clear Lcd display
Lcd_Cmd(_LCD_CURSOR_OFF); // Lcd Cursor off
Lcd_Out(1,3,"Developed By");
Lcd_Out(2,1,"MINA TECHNOLOGY");
delay_ms(2000); // 2 second delay
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,3,"Digital Clock");
Lcd_Out(2,1,"Time:");
TRISD = 0X07; // RB0-RB2 is input
PORTD = 0X00; // Clear PORTD
while(1){ // Endless loop
set = 0;
if(PORTD.F0==0){
Delay_ms(100);
if(PORTD.F0==0){
set_count++;
if(set_count>=4) set_count=0;
}
}
if(set_count){
if(PORTD.F1==0){
Delay_ms(100);
if(PORTD.F1==0) set = 1;
}
if(PORTD.F2==0){
Delay_ms(100);
if(PORTD.F2==0) set = -1;
}
if(set_count && set){
switch(set_count){
case 1: // change hour
hour = ds3231_read(2);
hour = Bcd2Dec(hour);
hour = hour+set;
if(hour>=24) hour=0;
if(hour<0) hour=23;
hour = Dec2Bcd(hour);
ds3231_write(2,hour);
break;
case 2: // change minute
minute = ds3231_read(1);
minute = Bcd2Dec(minute);
minute = minute+set;
if(minute>=60) minute = 0;
if(minute<0) minute = 59;
minute = Dec2Bcd(minute);
ds3231_write(1,minute);
break;
case 3: // Reset second
if(abs(set))
ds3231_write(0,0x00);
break;
}
}
}
second = ds3231_read(0);
minute = ds3231_read(1);
hour = ds3231_read(2);
time[0] = MSB(hour);
time[1] = LSB(hour);
time[3] = MSB(minute);
time[4] = LSB(minute);
time[6] = MSB(second);
time[7] = LSB(second);
Lcd_Out(2,6,time);
delay_ms(250);
}
}
Download free source code
Post Comments