Basic Tutorial for Arduino, 感測器 Sensor, 進階篇

【Arduino進階教學】DS1302 RTC 時鐘模組:即時時間顯示、備用電池與 RtcDS1302 函式庫實作

一、 DS1302 即時時鐘模組 (RTC) 運作原理

DS1302 是 Arduino 實作電子時鐘、定時開關與資料記錄器(Data Logger)常用的 RTC(Real-Time Clock,即時時鐘)晶片。

模組核心特色

  1. 獨立計時能力: 內建計時器可計算秒、分、時、日、月、星期與年份,並自動處理閏年修正(計算至 2100 年)。

  2. 雙電源供電設計: 板載 CR2032 鈕扣電池座,當 Arduino 主板斷電或拔除 USB 時,備用電池會繼續維繫 RTC 晶片運作,確保時間不會重置。

  3. 三線式 SPI 溝通: 使用 CE (RST)、SCLK (CLK) 與 IO (DAT) 三根訊號線與微控制器進行串列通訊,佔用 GPIO 資源少。

二、 實驗所需材料與電路接線圖 (Hardware Setup)

本實作使用 RtcDS1302 函式庫進行時間自動校正與 Serial 序列埠顯示。

準備材料

  • Arduino Uno 開發板 x 1

  • DS1302 RTC 時鐘模組(含 CR2032 電池) x 1

  • 杜邦線

準備好你的硬體工具了嗎? 推薦選購:米羅科技 – Arduino 程式學習爆款套件組(包含豐富驅動專案模組)

爆款推薦:程式學習套件組 

購買網址:shop.mirotek.com.tw

 

腳位對接說明 (Pin Mapping)

DS1302 模組引腳 Arduino Uno 引腳 說明
VCC 5V 電源正極 (5V)
GND GND 電源接地
DAT / IO D4 串列資料腳位
CLK / SCLK D5 串列時脈腳位
RST / CE D2 晶片致能/復位腳位

三、 安裝 DS1302 程式庫與完整程式碼實作

在編譯程式前,需先安裝對應的 DS1302 程式庫。

安裝 DS1302 程式庫步驟

  1. 開啟 Arduino IDE 軟體

  2. 點選頂部選單的 「草稿碼 (Sketch)」 「匯入程式庫 (Include Library)」 「管理程式庫 (Manage Libraries…)」

  3. 在右上方搜尋框輸入「DS1302」,下方會列出所有符合條件的程式庫,找到 RTC by Makuna 程式庫後,點選 「安裝 (Install)」 完成匯入。

 

完整程式碼

程式燒錄後,會自動比對電腦編譯時間與 DS1302 內部的時間;若編譯時間較新,則會自動將當前時間寫入晶片。

#include <RtcDS1302.h> 

ThreeWire myWire(4,5,2); // IO, SCLK, CE
RtcDS1302 <ThreeWire> Rtc(myWire);

void setup () 
{
    Serial.begin(9600);

    Serial.print("compiled: ");
    Serial.print(__DATE__);
    Serial.println(__TIME__);

    Rtc.Begin();

    //compiled變數設為電腦的程式碼編譯時的日期和時間
    RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); //
    printDateTime(compiled);
    Serial.println();

    //判斷DS1302是否接好
    if (!Rtc.IsDateTimeValid()) 
    {
        // Common Causes:
        //    1) first time you ran and the device wasn't running yet
        //    2) the battery on the device is low or even missing

        Serial.println("RTC lost confidence in the DateTime!");
        Rtc.SetDateTime(compiled);
    }

    if (Rtc.GetIsWriteProtected())
    {
        Serial.println("RTC was write protected, enabling writing now");
        Rtc.SetIsWriteProtected(false);
    }

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC was not actively running, starting now");
        Rtc.SetIsRunning(true);
    }
    /*如果程式編譯當時的時間與DS1302上的時間不同,
     *將比較DS1302上紀綠的時間和編譯時的時間哪個比較新,
     *若編譯時間比較新,則將DS1302模組內存的時間更改成編譯的時間
     */
    //now:DS1302模組內存紀綠的時間,compiled:編譯時的時間
    RtcDateTime now = Rtc.GetDateTime();
    //編譯時間比較新,把DS1302模組內存的時間更改成編譯的時間
    if (now < compiled) { Serial.println("RTC is older than compile time! (Updating DateTime)"); Rtc.SetDateTime(compiled); } else if (now > compiled) 
    {
        Serial.println("RTC is newer than compile time. (this is expected)");
    }
    else if (now == compiled) 
    {
        Serial.println("RTC is the same as compile time! (not expected but all is fine)");
    }
}

void loop () 
{
    RtcDateTime now = Rtc.GetDateTime();

    printDateTime(now);
    Serial.println();

    if (!now.IsValid())
    {
        // Common Causes:
        //    1) the battery on the device is low or even missing and the power line was disconnected
        Serial.println("RTC lost confidence in the DateTime!");
    }

    delay(10000); // ten seconds
}

#define countof(a) (sizeof(a) / sizeof(a[0]))

void printDateTime(const RtcDateTime& dt)
{
    char datestring[20];

    snprintf_P(datestring, 
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    Serial.print(datestring);
}

 

Serial 序列埠監測顯示結果:

 

四、 常見問題與除錯 (FAQ)

Q1:出現 “RTC lost confidence in the DateTime!” 警告訊息是什麼原因?

  • 解答:

    1. 首次通電: 模組剛接到 Arduino 時晶片尚未啟動計時,屬於正常現象,程式會自動將編譯時間寫入。

    2. 電池無電: 模組上的 CR2032 電池電量過低或未裝電池,導致斷電後內部晶片重置失步。

Q2:序列埠監視器顯示的時間沒有每秒更新,而是好幾秒才印一次?

  • 解答: 原始程式中的 loop() 函式最後設定了 delay(10000);(等候 10 秒),因此每 10 秒才會在序列埠印出一次最新時間。若需每秒更新,可調小 delay 數值。

Q3:序列埠輸出亂碼或無法顯示時間?

  • 解答: 請檢查 IO(D4)、SCLK(D5) 與 CE(D2) 腳位是否接錯,並確認 Serial Monitor 的波特率設定為 9600 baud。

延伸閱讀與推薦課程