2019-09-30

Arduino 控制 DS1302 實時晶片模組

最近在下嘗試在 Arduino 編寫一些自動在特定時間自動運作的程式
但發現 Arduino 標準函式庫只有 millis 傳回 Arduino 的啟動時間長度,沒有實際時間
若果需要讓 Arduino 讀取實際時間,便需要有時間晶片幫助……

零件

見下文
在下使用 DS1302時間晶片
DS1302是一種常見常用的時間晶片,共有 8支引腳

引腳功用

引腳8引腳7引腳6引腳5
引腳1引腳2引腳3引腳4
用途
(缺口在左邊)
後備電源Clock (SCLK, CLK)Data (I/O, DAT)Reset (CE / RST)
主電源振盪器正極振盪器負極接地

編號方向用途
1輸入主電源,接受 2.0V 至 5.5V
2輸入振盪器正極
3輸入振盪器負極
4輸入接地
5輸入設定 或 重設 (Reset) ,控制 指令訊號 及 資料訊號 週期範圍
6輸入 或 輸出指令 或 資料 (Data) ,發出指令 或 接受資料
7輸入定時 (Clock) ,控制 發出指令訊號 及 接收資料訊號 的狀態
8輸入後備電源,接受 2.0V 至 5.5V
當 主電源 大於 後備電源 0.2V ,便會使用 主電源 啟動 DS1302時間晶片,否則便會使用 後備電源

引腳訊號

引腳初始化指令訊號 及 資料訊號 週期
開始指令 位元組 週期寫入 或 讀取 位元組 週期完成
Time延遲2微秒延遲2微秒延遲2微秒延遲2微秒
RST
CLK
DAT高/低高/低

開始 及 完成 只需要使用 RST引腳 控制 ,開始 為 高電壓,完成 為 低電壓
比較簡單,因此沒有展示 訊號波紋時序圖

而 指令 及 寫入 或 讀取 則需要配合 CLK引腳 及 DAT引腳
設定次序為 第0位元 至 第7位元
  1. 將 RST引腳 保持 高電壓
  2. 調整 CLK引腳 為 高電壓
  3. 調整 DAT引腳 為 高或低電壓 以設定 位元資料
  4. 調整 CLK引腳 為 低電壓,完成1位元設定
訊號波紋時序圖
RST CLK DAT

指令訊號

第n位元76543210
用途1RAM (1)A4A3A2A1A0Get (1)
CLK (0)Set (0)

第n位元用途
0設定為 0 時,為寫入狀態;設定為 1 時,為讀取狀態
1第0位位元地址或指令
2第1位位元地址或指令
3第2位位元地址或指令
4第3位位元地址或指令
5第4位位元地址或指令
6設定為 0 時,控制時間或日期資料;設定為 1 時,控制隨機存取記憶體資料
7設定為 0 時,將資料鎖定;設定為 1 時,可以控制資料

寫入時間的訊號波紋時序圖
RST CLK DAT

讀取隨機存取記憶體的訊號波紋時序圖
RST CLK DAT

涓流差電模式

讓 DS1302時間晶片 替 後備電源差電
(後備電源能夠差電才有效,不能差電的電池只會保持平衡狀態,以免放電現象導致失去所有能量)
第n位元功能
76543210
11111個二極管 2kΩ電阻
165(Dec) 0xA5(Hex)
11111個二極管 4kΩ電阻
166(Dec) 0xA6(Hex)
111111個二極管 8kΩ電阻
167(Dec) 0xA7(Hex)
11112個二極管 2kΩ電阻
169(Dec) 0xA9(Hex)
11112個二極管 4kΩ電阻
170(Dec) 0xAA(Hex)
111112個二極管 8kΩ電阻
171(Dec) 0xAB(Hex)
1111開機啟動狀態
92(Dec) 0x5C(Hex)

資料訊號

時間或日期資料
地址
(Hex)
第n位元
76543210
0x80十位秒數
0 至 5
個位秒數
0 至 9
0x82十位分數
0 至 5
個位分數
0 至 9
0x84十位時數
0 至 2
個位時數
0 至 9
0x86十位日數
0 至 3
個位日數
0 至 9
0x88十位月數
0 至 1
個位月數
0 至 9
0x8A個位週數
1 至 7
0x8C十位年數
0 至 9
個位年數
0 至 9
0x8E0 取消保護
1 啟用保護
0x90TCSTCSTCSTCSDSDSRSRS
  • 秒 - 預設為 0 ,第0至3位元 為個位秒數,第4至6位元 為十位秒數
  • 分 - 預設為 0 ,第0至3位元 為個位分數,第4至6位元 為十位分數
  • 時 - 預設為 0 ,第0至3位元 為個位時數,第4至5位元 為十位時數
  • 日 - 預設為 1 ,第0至3位元 為個位日數,第4至5位元 為十位日數
  • 月 - 預設為 1 ,第0至3位元 為個位月數,第4位元 為十位月數
  • 週 - 預設為 1 ,第0至2位元 為個位週數
  • 年 - 預設為 0 ,第0至3位元 為個位年數,第4至7位元 為十位年數
  • 保護 - 預設為 0 (不保護) ,第7位元 0 為不保護, 1 為保護
  • TCS - 預設為 92 (開機啟動狀態) ,參巧本文的 涓流差電模式
時間及日期不是使用 二進制數值 ,而是使用 二進碼十進數 (Binary-Coded Decimal (BCD))
BCD 將 8位元資料 分開兩組 4位元,第0至3位元 為第一部分 是個位數,第4至7位元 為第二部分 是十位數
4位元 可以顯示 0 至 9 (只取至十進制最大位值)
例如 設定資料 是 37 即是 00110111(bcd) = 55(dec) = 0x37
例如 傳回資料 是 89 即是 01011001(bcd) = 59(dec) = 0x3B
在下編寫了簡單的 C++ 程式可以將 BCD 與 十進數 互換
unsigned char ByteToBCD(unsigned char value) {
    return ((value >> 4) * 10) + (value & 0x0F);
}

unsigned char BCDtoByte(unsigned char value) {
    return ((value / 10) << 4) + (value % 10);
}

DS1302時間晶片 會自動計算 24小時 後的日期,但並不會檢查寫入的時間或日期資料是否正確
例如可以寫入 19年 2月 30日 ,亦不能保證 24小時 後的日期是正確
年數 最大值為 99 ,因此不能計算超過 100年 的 閏年
週數 並沒有規範 星期名稱,例如 1 不一定代表 星期一 ,只在經過 24小時 會更新

關於 DS1302時間晶片 ,可以搜尋 DS1302 Datasheet 獲得詳細資料
隨機存取記憶體資料
DS1302時間晶片 提供 由 0xC0 至 0xFC 的偶數地址 共31個位元組 (31個8位元) 隨機存取記憶體空間

見下文
CR2032 3V鋰電池
C 表示 正極使用 ,負極使用 二氧化錳 ,稱為 鋰二氧化錳電池
R 表示 圓形 (Round)

見下文
使用 32768 Hz 頻率 石英晶體振盪器
32768 是 2的15次方 (2^15) 方便除 2 至 1 Hz

見下文
接駁方法
DS1302時間晶片 需要有電力才能保存資料
後備電源可以在沒有主電源下仍能提供電力讓 DS1302時間晶片 不會遺失資料

模組

見下文
DS1302模組 正面

見下文
DS1302模組 背面

DS1302模組 已經制訂

見下文
安裝 3V鋰電池、DS1302晶片、石英晶體振盪器 到 DS1302模組

見下文
接駁方法
DS1302模組 同樣制訂引腳座,方便連接到其他裝置

見下文
將 DS1302模組 接駁到 Arduino 引腳

見下文
由於 DS1302模組 電源引腳 及 接地引腳 不是使用 Arduino 的 電源引腳 及 接地引腳
因此需要使用 Arduino 的 數碼引腳 或 模擬引腳 替代 電源引腳 及 接地引腳

見下文
接駁方法
在下因為懶惰,直接將 DS1302模組 接駁到 Arduino 上
其中 2支引腳 需要提供 電力 及 接地

見下文
使用 序列輸出 效果,或配合如 七段顯示器 顯示時間
閣下應該發現在下使用 delay(1000) ,但延遲時間並不是穩定 1秒,而且與初始時間相差越來越遠
由於 DS1302時間晶片 發出指令 與 接受資料 都需要有延遲,要絕對及穩定相差 1秒 是非常困難

總結

Arduino Playground 有提供 DS1302時間晶片函式庫
但在下希望了解清楚 DS1302時間晶片 的運作方式,因此在下沒有使用 DS1302時間晶片函式庫
在下單是查看 DS1302時間晶片 的文件,只是應用部分已經需要一日時間
在下終於可以自行編寫另一個 DS1302時間晶片函式庫
有興趣可以到 https://bitbucket.org/hkgoldenmra/ds1302module
https://create.arduino.cc/editor/hkgoldenmra/70475f78-df8f-495e-89ee-b35ca0e5ba70/preview 了解
或在 Terminal 輸入
git clone "https://hkgoldenmra@bitbucket.org/hkgoldenmra/ds1302module.git" --depth=1
下載專案

時間及日期資料 及 隨機存取記憶體資料 與電腦的隨機存取記憶體資料 (Random Access Memory (RAM) 相同,電力中斷後會失去資料
要更換電池又不希望失去資料,需要在主電源提供電力狀態下更換

沒有留言 :

張貼留言