A real time clock is basically just like a watch - it runs on a battery and keeps time for you even when there is a power outage. Using an RTC, you can keep track of long timelines, even if you reprogram your micro-controller or disconnect it from USB or a power plug.
Most micro-controllers, have a built-in timekeeper called millis() and there are also timers built into the chip that can keep track of longer time periods like minutes or days. So why would you want to have a separate RTC chip? Well, the biggest reason is that millis() only keeps track of time since the PIC was last powered up. That means that when the power is turned on, the millisecond timer is set back to 0. The PIC doesn't know that it's 'Tuesday' or 'March 8th', all it can tell is 'It's been 14,000 milliseconds since I was last turned on'.
OK so what if you wanted to set the time on the PIC? You'd have to program in the date and time and you could have it count from that point on. But if it lost power, you'd have to reset the time. Much like very cheap alarm clocks: every time they lose power they blink 12:00.
While this sort of basic timekeeping is fine for some projects, while some projects such as data-loggers, clocks, etc will need to have consistent timekeeping that doesn't reset when the PIC battery dies or is reprogrammed. Thus, we include a separate RTC. The RTC chip is a specialized chip that just keeps track of time. It can count leap-years and knows how many days are in a month, but it doesn't take care of Daylight Savings Time (because it changes from place to place).
So Here we are just going to demonstrate the RTC application for displaying time and date on Lcd and serial port, we are going to use DS1307 IC as our RTC IC, this IC is based on i2c communication protocol, so we must use the internal I2C module of PIC16F877A for this project.
The simulation diagram for this is as follow:
Most micro-controllers, have a built-in timekeeper called millis() and there are also timers built into the chip that can keep track of longer time periods like minutes or days. So why would you want to have a separate RTC chip? Well, the biggest reason is that millis() only keeps track of time since the PIC was last powered up. That means that when the power is turned on, the millisecond timer is set back to 0. The PIC doesn't know that it's 'Tuesday' or 'March 8th', all it can tell is 'It's been 14,000 milliseconds since I was last turned on'.
OK so what if you wanted to set the time on the PIC? You'd have to program in the date and time and you could have it count from that point on. But if it lost power, you'd have to reset the time. Much like very cheap alarm clocks: every time they lose power they blink 12:00.
While this sort of basic timekeeping is fine for some projects, while some projects such as data-loggers, clocks, etc will need to have consistent timekeeping that doesn't reset when the PIC battery dies or is reprogrammed. Thus, we include a separate RTC. The RTC chip is a specialized chip that just keeps track of time. It can count leap-years and knows how many days are in a month, but it doesn't take care of Daylight Savings Time (because it changes from place to place).
So Here we are just going to demonstrate the RTC application for displaying time and date on Lcd and serial port, we are going to use DS1307 IC as our RTC IC, this IC is based on i2c communication protocol, so we must use the internal I2C module of PIC16F877A for this project.
Schematic Diagram |
The source code for DS1307 is as follow:
Have a look at this video:
PCF8523 Interfacing with PIC16F877A
1: //Interfacing RTC DS1307 with PIC16F877A Micro-Controller and Displaying TIME and DATE on LCD
2: #include <htc.h>
3: #include<string.h>
4: /*********CRYSTAL FREQUECY**********/
5: #define _XTAL_FREQ 20000000
6: /***********************************/
7: /*********LCD PIN CONNECTION********/
8: #define LCD_DATA PORTD
9: #define RS PORTBbits.RB0
10: #define RW PORTBbits.RB2
11: #define EN PORTBbits.RB1
12: /***********************************/
13: //Function Prototype
14: void lcd_init();
15: void lcdcmd(unsigned char value);
16: void lcddata(unsigned char value);
17: void lcdstr(unsigned char msg[]);
18: void i2c_init();
19: void i2c_start(void);
20: void i2c_restart(void);
21: void i2c_stop(void);
22: void i2c_wait(void);
23: void i2c_send(unsigned char dat);
24: unsigned char i2c_read(void);
25: unsigned char rtc1307_read(unsigned char address); //RTC DS1307 Read Function
26: unsigned char BCD2UpperCh(unsigned char bcd);
27: unsigned char BCD2LowerCh(unsigned char bcd);
28: unsigned char sec,min,hour,date,month,year;
29: void main()
30: {
31: TRISB = 0x00;
32: TRISC = 0xFF;
33: TRISD = 0x00;
34: lcd_init();
35: lcdcmd(0x80);
36: __delay_ms(10);
37: lcdstr("Embedded!!");
38: lcdcmd(0xC4);
39: lcdstr("Laboratory!!");
40: __delay_ms(1000);
41: i2c_init(); //To Generate the Clock of 100Khz
42: i2c_start();
43: i2c_send(0xD0);
44: i2c_send(0x00);
45: i2c_send(0x80); //CH = 1 Stop oscillator
46: i2c_send(0x00); //Minute
47: i2c_send(0x01); //Hour
48: i2c_send(0x01); //Sunday
49: i2c_send(0x01); //1Date
50: i2c_send(0x01); //1 Jan
51: i2c_send(0x12); //2012
52: i2c_stop(); //Stop the I2C Protocol
53: //Have to start the Clock again
54: i2c_start();
55: i2c_send(0xD0);
56: i2c_send(0x00);
57: i2c_send(0x00); //start Clock and set the second hand to Zero
58: i2c_stop();
59: lcdcmd(0x01);
60: //Infinite Loop For Reading Time and Date
61: while(1)
62: {
63: sec = rtc1307_read(0x00);
64: min = rtc1307_read(0x01);
65: hour = rtc1307_read(0x02);
66: date = rtc1307_read(0x04);
67: month = rtc1307_read(0x05);
68: year = rtc1307_read(0x06);
69: __delay_ms(1);
70: lcdcmd(0x80);
71: lcdstr("Time:");
72: lcddata(BCD2UpperCh(hour));
73: lcddata(BCD2LowerCh(hour));
74: lcddata(':');
75: lcddata(BCD2UpperCh(min));
76: lcddata(BCD2LowerCh(min));
77: lcddata(':');
78: lcddata(BCD2UpperCh(sec));
79: lcddata(BCD2LowerCh(sec));
80: lcdcmd(0xC0);
81: lcdstr("DATE:");
82: lcddata(BCD2UpperCh(date));
83: lcddata(BCD2LowerCh(date));
84: lcddata('/');
85: lcddata(BCD2UpperCh(month));
86: lcddata(BCD2LowerCh(month));
87: lcddata('/');
88: lcddata(BCD2UpperCh(year));
89: lcddata(BCD2LowerCh(year));
90: __delay_ms(1000);
91: }
92: }
93: //Fnction Definition
94: void lcd_init()
95: {
96: lcdcmd(0x38);
97: __delay_ms(1);
98: lcdcmd(0x0E);
99: __delay_ms(1);
100: lcdcmd(0x0C);
101: __delay_ms(1);
102: }
103: void lcdcmd(unsigned char value)
104: {
105: LCD_DATA = value;
106: RS = 0;
107: RW = 0;
108: EN = 1;
109: __delay_ms(1);
110: EN = 0;
111: }
112: void lcddata(unsigned char value)
113: {
114: LCD_DATA = value;
115: RS = 1;
116: RW = 0;
117: EN = 1;
118: __delay_ms(1);
119: EN = 0;
120: }
121: void lcdstr(unsigned char msg[])
122: {
123: unsigned int i,len;
124: len = strlen(msg);
125: for(i=0;i<len;i++)
126: {
127: lcddata(msg[i]);
128: __delay_ms(1);
129: }
130: }
Have a look at this video:
The simulation diagram for this is as follow:
Schematic Diagram |
"Great blog created by you. I read your blog, its best and useful information. You have done a great work. Super blogging and keep it up.php jobs in hyderabad.
ReplyDelete"
Good evening,
ReplyDeleteis what you can help me to create the drivers PCF8583P with mplab xc8 compiler (i2c.h, i2c.c, PCF8583.h and PCF8583.c) please ??
it's very urgent
Please use pcf8523 as reference to create drivers.
Delete