Arduino本身可以透過delay函數進行簡單的計時,但是本身卻沒有時鐘的功能,也沒有記憶目前時間的功能,因此就算是我們利用程式模擬出時鐘的功能,一旦失去了電源,下次再回來程式的時候,又要重頭開始設定時間了,此種情形在製作和時鐘相關的應用專題時就非常地不方便。所幸,有一個模組可以解決這個問題,那就是DS1302 RTC(Real Time Clock)模組。下圖就是我們這次實習的主角:
它有總共有5支接腳,如上圖所示由上而下分別是5V正電源以及GND接地,然後是CLK、DAT、以及RST三支連線用的接腳。和大部份的Arduino模組一樣,此模組也有程式庫可以使用,只要到「這裡」下載壓縮檔,再到Arduino的libraries之下解壓縮就可以使用了。
為了能夠順利地顯示出現在時刻,我們把之前練習的LCD模組再一次拿來使用,連接如下:
以下是完整的程式:
#include <stdio.h> #include "DS1302.h" #include "Wire.h" #include "LiquidCrystal_I2C.h" const int kCePin = 4; // RST const int kIoPin = 3; // DAT const int kSclkPin = 2; // CLK LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE); DS1302 rtc(kCePin, kIoPin, kSclkPin); String dayAsString(const Time::Day day) { switch (day) { case Time::kSunday: return "Sunday"; case Time::kMonday: return "Monday"; case Time::kTuesday: return "Tuesday"; case Time::kWednesday: return "Wednesday"; case Time::kThursday: return "Thursday"; case Time::kFriday: return "Friday"; case Time::kSaturday: return "Saturday"; } return "(unknown day)"; } void printTime() { Time t = rtc.time(); const String day = dayAsString(t.day); char line1[50], line2[50]; snprintf(line1, sizeof(line1), "%04d-%02d-%02d", t.yr, t.mon, t.date); snprintf(line2, sizeof(line2), "%02d:%02d:%02d %s", t.hr, t.min, t.sec, day.c_str()); lcd.setCursor(0,0); lcd.print(line1); lcd.setCursor(0,1); lcd.print(line2); } void setup() { lcd.begin(16,2); lcd.backlight(); delay(1000); rtc.halt(false); rtc.writeProtect(false); Serial.begin(9600); /*Time t(2018, 5, 27, 8, 25, 50, Time::kSunday); rtc.time(t); */ } void loop() { printTime(); delay(1000); }
要特別留意的是程式中的這幾行:
const int kCePin = 4; // RST const int kIoPin = 3; // DAT const int kSclkPin = 2; // CLK
這就是那個DS1302模組的幾支接腳和Arduino連線的號碼,千萬不要接錯了。以下是執行的範例影片:
程式中的第45~46行我們註解起來的程式碼是用來設定時間用的,如果有需要設定持間的話就可以把這個註解符號移除,然後用自己要設定的時間去呼叫rtc.time()函數。要留意的是,由於這個時鐘模組本身自己有一個電池可以記錄目前的時間,而且會持續地自行運作,因此在程式中只要在需要的時間執行一次設定時間的程式碼,接下來只要讀取目前的數值就好了,這也是我們把這兩行程式註解起來的原因。
在完成了程式的燒錄工作之後,把 Aarduino和電腦之間的連接線移除,然後把電源模組的5V再連接到Arduino的Vin接腳,同學們就可以看到一個不需要個人電腦即可自行運作的時鐘了。
(8591)
近期留言