Header Ads

DS3231 RTC Module interfacing with PIC Microcontroller part 2

Welcome to MINA TECHNOLOGY.

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.


Mikro C 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

         }

unsigned short ds3231_write(unsigned short address, unsigned short write_data){    // ds3231 RTC module write

         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);

              }



}


Click the download button for source code:
download

No comments

Theme images by 5ugarless. Powered by Blogger.