IC thời gian thực DS1307 về cơ bản là đồng hồ thời gian độc lập. Về cơ bản, chúng ta có thể sử dụng micrcontroller để giữ thời gian, nhưng giá trị sẽ biến mất ngay sau khi nó bị tắt nguồn.
RTC DS1307 là một giải pháp tiện dụng để giữ thời gian mọi lúc, khi nó được cung cấp năng lượng bởi một ô đồng xu.
Nó sử dụng giao thức I²C (Mạch tích hợp liên thông), được gọi là I-bình phương-C, I-hai-C hoặc IIC để giao tiếp với bộ điều khiển .
Điều đầu tiên mà MCU gửi đến Slave (RTC) là ID thiết bị. ID thiết bị cho DS1307, được hiển thị bên dưới. Nó cũng cho biết thời tiết mà chúng ta muốn viết hoặc đọc từ RTC.
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | 0 | 1 | 0 | 0 | 0 | R/W |
- bit-0 is 0 than we Write to RTC
- bit-0 is 1 we Read from RTC.
Định Nghĩa Như Sau:
- #define C_Ds1307ReadMode_U8 0xD1u // DS1307 ID
- #define C_Ds1307WriteMode_U8 0xD0u // DS1307 ID
ADDRESS | FUNCTION | RANGE |
---|---|---|
00h | Seconds | 00–59 |
01h | Minutes | 00–59 |
02h | Hours | 01-12/00-24 |
03h | Day | 01–07 |
04h | Date | 01–31 |
05h | Month | 01–12 |
06h | Year | 00–99 |
07h | Control | |
08h to 3Fh | RAM | 00h–FFh |
The address 0x07 is a control registered as described below:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
OUT | 0 | 0 | SQWE | 0 | 0 | RS1 | RS0 |
Chúng tôi ghi 0x00 vào thanh ghi Control để vô hiệu hóa SQW-Out. Chúng tôi không sử dụng bất kỳ bit nào khác từ nó, vì vậy bạn không cần phải lo lắng.
Initialize
- void RTC_Init(void)
- {
- I2C_Init(); // Initialize the I2c module.
- I2C_Start(); // Start I2C communication
- I2C_Write(C_Ds1307WriteMode_U8); // Connect to DS1307 by sending its ID on I2c Bus
- I2C_Write(C_Ds1307ControlRegAddress_U8);// Select the Ds1307 ControlRegister to configure Ds1307
- I2C_Write(0x00); // Write 0x00 to Control register to disable SQW-Out
- I2C_Stop(); // Stop I2C communication after initializing DS1307
- }
Set Date and Time
- void RTC_SetDateTime(rtc_t *rtc)
- {
- I2C_Start(); // Start I2C communication
- I2C_Write(C_Ds1307WriteMode_U8); // connect to DS1307 by sending its ID on I2c Bus
- I2C_Write(C_Ds1307SecondRegAddress_U8); // Request sec RAM address at 00H
- I2C_Write(rtc->sec); // Write sec from RAM address 00H
- I2C_Write(rtc->min); // Write min from RAM address 01H
- I2C_Write(rtc->hour); // Write hour from RAM address 02H
- I2C_Write(rtc->weekDay); // Write weekDay on RAM address 03H
- I2C_Write(rtc->date); // Write date on RAM address 04H
- I2C_Write(rtc->month); // Write month on RAM address 05H
- I2C_Write(rtc->year); // Write year on RAM address 06h
- I2C_Stop(); // Stop I2C communication after Setting the Date
- }
- void RTC_GetDateTime(rtc_t *rtc)
- {
- I2C_Start(); // Start I2C communication
- I2C_Write(C_Ds1307WriteMode_U8); // connect to DS1307 by sending its ID on I2c Bus
- I2C_Write(C_Ds1307SecondRegAddress_U8); // Request Sec RAM address at 00H
- I2C_Stop(); // Stop I2C communication after selecting Sec Register
- I2C_Start(); // Start I2C communication
- I2C_Write(C_Ds1307ReadMode_U8); // connect to DS1307(Read mode) by sending its ID
- rtc->sec = I2C_Read(1); // read second and return Positive ACK
- rtc->min = I2C_Read(1); // read minute and return Positive ACK
- rtc->hour= I2C_Read(1); // read hour and return Negative/No ACK
- rtc->weekDay = I2C_Read(1); // read weekDay and return Positive ACK
- rtc->date= I2C_Read(1); // read Date and return Positive ACK
- rtc->month=I2C_Read(1); // read Month and return Positive ACK
- rtc->year =I2C_Read(0); // read Year and return Negative/No ACK
- I2C_Stop(); // Stop I2C communication after reading the Date
- }
- typedef struct
- {
- uint8_t sec;
- uint8_t min;
- uint8_t hour;
- uint8_t weekDay;
- uint8_t date;
- uint8_t month;
- uint8_t year;
- }rtc_t;
#include "rtc.h" #include "lcd.h" int main() { rtc_t rtc; /*Connect RS->PB0, RW->PB1, EN->PB2 and data bus to PORTB.4 to PORTB.7*/ LCD_SetUp(PB_0,PB_1,PB_2,P_NC,P_NC,P_NC,P_NC,PB_4,PB_5,PB_6,PB_7); LCD_Init(2,16); /*Connect SCL->PC0, SDA->PC1*/ RTC_Init(); rtc.hour = 0x10; // 10:40:20 am rtc.min = 0x40; rtc.sec = 0x00; rtc.date = 0x01; //1st Jan 2016 rtc.month = 0x01; rtc.year = 0x16; rtc.weekDay = 5; // Friday: 5th day of week considering monday as first day. /*##### Set the time and Date only once. Once the Time and Date is set, comment these lines and reflash the code. Else the time will be set every time the controller is reset*/ RTC_SetDateTime(&rtc); // 10:40:20 am, 1st Jan 2016 /* Display the Time and Date continuously */ while(1) { RTC_GetDateTime(&rtc); LCD_GoToLine(0); LCD_Printf("time:%2x:%2x:%2x \nDate:%2x/%2x/%2x",(uint16_t)rtc.hour,(uint16_t)rtc.min,(uint16_t)rtc.sec,(uint16_t)rtc.date,(uint16_t)rtc.month,(uint16_t)rtc.year); } return (0); }