QC

Đồng hồ Thời gian thực DS1307 AVR

 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.

76543210
1101000R/W
  • bit-0 is 0 than we Write to RTC
  • bit-0 is 1 we Read from RTC.

Định Nghĩa Như Sau:

  1. #define C_Ds1307ReadMode_U8 0xD1u // DS1307 ID
  2. #define C_Ds1307WriteMode_U8 0xD0u // DS1307 ID
RTC giữ ngày và giờ được sắp xếp trong bộ nhớ của nó như hình dưới đây:
ADDRESSFUNCTIONRANGE
00hSeconds00–59
01hMinutes00–59
02hHours01-12/00-24
03hDay01–07
04hDate01–31
05hMonth01–12
06hYear00–99
07hControl
08h to 3FhRAM00h–FFh

Ghi đến các địa chỉ ở trên, chúng tôi có thể đặt thời gian, và khi chúng tôi đặt nó, chúng tôi có thể đọc nó bất cứ lúc nào chúng tôi cần.

The address 0x07 is a control registered as described below:

76543210
OUT00SQWE00RS1RS0

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


Bây giờ chúng ta có thể khởi tạo RTC bằng đoạn mã bên dưới


  1. void RTC_Init(void)
  2. {
  3. I2C_Init(); // Initialize the I2c module.
  4. I2C_Start(); // Start I2C communication
  5.  
  6. I2C_Write(C_Ds1307WriteMode_U8); // Connect to DS1307 by sending its ID on I2c Bus
  7. I2C_Write(C_Ds1307ControlRegAddress_U8);// Select the Ds1307 ControlRegister to configure Ds1307
  8.  
  9. I2C_Write(0x00); // Write 0x00 to Control register to disable SQW-Out
  10.  
  11. I2C_Stop(); // Stop I2C communication after initializing DS1307
  12. }

Set Date and Time

  1. void RTC_SetDateTime(rtc_t *rtc)
  2. {
  3. I2C_Start(); // Start I2C communication
  4.  
  5. I2C_Write(C_Ds1307WriteMode_U8); // connect to DS1307 by sending its ID on I2c Bus
  6. I2C_Write(C_Ds1307SecondRegAddress_U8); // Request sec RAM address at 00H
  7.  
  8. I2C_Write(rtc->sec); // Write sec from RAM address 00H
  9. I2C_Write(rtc->min); // Write min from RAM address 01H
  10. I2C_Write(rtc->hour); // Write hour from RAM address 02H
  11. I2C_Write(rtc->weekDay); // Write weekDay on RAM address 03H
  12. I2C_Write(rtc->date); // Write date on RAM address 04H
  13. I2C_Write(rtc->month); // Write month on RAM address 05H
  14. I2C_Write(rtc->year); // Write year on RAM address 06h
  15.  
  16. I2C_Stop(); // Stop I2C communication after Setting the Date
  17. }

Lưu ý: Ngày và giờ đọc từ Ds1307 sẽ có định dạng BCD, như:

0x12,0x39,0x26 ghi12 giờ, 39 phút và 26 giây.
0x15,0x08,0x47 ghi ngày thứ 15, tháng thứ 8 và năm thứ 47

Get Date and Time

  1. void RTC_GetDateTime(rtc_t *rtc)
  2. {
  3. I2C_Start(); // Start I2C communication
  4.  
  5. I2C_Write(C_Ds1307WriteMode_U8); // connect to DS1307 by sending its ID on I2c Bus
  6. I2C_Write(C_Ds1307SecondRegAddress_U8); // Request Sec RAM address at 00H
  7.  
  8. I2C_Stop(); // Stop I2C communication after selecting Sec Register
  9.  
  10. I2C_Start(); // Start I2C communication
  11. I2C_Write(C_Ds1307ReadMode_U8); // connect to DS1307(Read mode) by sending its ID
  12.  
  13. rtc->sec = I2C_Read(1); // read second and return Positive ACK
  14. rtc->min = I2C_Read(1); // read minute and return Positive ACK
  15. rtc->hour= I2C_Read(1); // read hour and return Negative/No ACK
  16. rtc->weekDay = I2C_Read(1); // read weekDay and return Positive ACK
  17. rtc->date= I2C_Read(1); // read Date and return Positive ACK
  18. rtc->month=I2C_Read(1); // read Month and return Positive ACK
  19. rtc->year =I2C_Read(0); // read Year and return Negative/No ACK
  20.  
  21. I2C_Stop(); // Stop I2C communication after reading the Date
  22. }


Cả hai hàm trên đều sử dụng cấu trúc đơn giản được hiển thị bên dưới để dễ dàng truy cập

  1. typedef struct
  2. {
  3. uint8_t sec;
  4. uint8_t min;
  5. uint8_t hour;
  6. uint8_t weekDay;
  7. uint8_t date;
  8. uint8_t month;
  9. uint8_t year;
  10. }rtc_t;




CODE


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





Nap Code vào PY32F003 dùng Stlink

 Nap Code vào PY32F003 dùng Stlink Bước 1: Cài đặt  KeilC v5.39 theo link sau ( chú ý 5.39 keil c mới nạp ok). https://edge07.111.ir.cdn.ir/...