2014/01/14

Raspberry Pi與即時時鐘RTC

一般電腦主機板上都會有即時時鐘,通常會再加上一顆扁圓狀的鋰電池,如此一來,即便電腦關機、拔掉電源插頭,即時時鐘仍會繼續運作,維持正確的日期時間。但為了成本考量,Raspberry Pi板子並無內建即時時鐘(RTC,real-time clock),解決辦法有兩種,第一種是若擁有網路連線,開機時便執行相關的服務程式,向網路上的NTP(Network Time Protocol)時間伺服器詢問日期時間,也就是說,每次開機後便上網校準日期時間,另一種則不需要網路連線,自行加入即時時鐘IC與鋰電池,這也是本篇將要介紹的內容。

零件列表:
  • DS1307,即時時鐘IC。
  • 陶瓷電容0.1μF(104)。
  • 石英晶體32.768 KHz,12.5 pF。
  • CR1220,3V鋰電池。
  • 鋰電池座。
即時時鐘DS1307,有八個腳位,傳輸介面為I2C,可記錄年、月、日、時、分、秒,當第一次使用時,其記錄的日期時間會是00(2000)年、01月、01日、00時、00分、00秒,有效日期時間可達到2100年,可在-40°C至85°C的環境溫度下正常運作,非常適合一般需求的電子專案。另外,若需要更精確的即時時鐘,可改用DS3231,但也較貴。
石英晶體32.768 KHz,12.5 pF,這是DS1307規格書註明需要的震盪晶體規格。

鋰電池CR1220,電壓為3V,在室溫下應可供應電源給DS1307達10年之久。若要製作出成品,則需要鋰電池座,若只是想先在麵包板上玩玩即時時鐘,只需一般膠帶用來固定連接線與鋰電池的正負極即可。

陶瓷電容0.1uF(104),讓電路更穩定。

電路圖如下:
線路連接後的樣子:
DS1307的Vcc為電源輸入,所需電壓為5V,所以接到Raspberry Pi的GPIO針腳的5V。GND為接地,接到GPIO針腳的GND。X1與X2需接石英震盪晶體,不分極性。Vbat接鋰電池的正極,鋰電池的負極需跟GND接在一起,共同接地。SQW/OUT為方波輸出腳位,此處不使用。SCL與SDA為I2C傳輸介面的腳位,直接接到GPIO針腳的SCL與SDA即可。

硬體部分完成後,接下來便是軟體的部份。在此以Raspberry Pi基金會官方推薦使用的Linux發行套件Raspbian為例。

首先是作業系統核心的部分,Linux核心已經含有支援I2C與DS1307的驅動程式模組,以如下指令便能手動載入模組:

$ sudo modprobe i2c-bcm2708
$ sudo modprobe i2c-dev
$ sudo modprobe rtc-ds1307

然後手動加入裝置(即時時鐘DS1307),需具有系統管理者權限。

$ sudo bash
# echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
$ exit

注意,Raspberry Pi板子的GPIO針腳有兩個版本,其實體針腳3與5為SDA與SCL,但兩個版本卻接在不同的I2C通道上,若您的板子是Rev 1請使用上述指令,若是Rev 2則需使用下列指令。

$ sudo bash
# echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
$ exit

那麼,如何判斷手上的板子是Rev 1還是Rev 2呢?請在命令列裡輸入如下指令:

$ cat /proc/cpuinfo

螢幕上便會輸出類似底下的資訊:

Processor       : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS        : 464.48
Features        : swp half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xb76
CPU revision    : 7

Hardware        : BCM2708
Revision        : 0002
Serial          : 000000006fcde2bd

我們可從其中的「Revision」得知板子的版本,這是個16進位數值,若是0x2或0x3,代表這塊本子是Model B Rev 1(記憶體為256MB),若是0xd、0xe、0xf,則是Model B Rev 2(記憶體512MB),若是0x7、0x8、0x9則代表Model A,其GPIO腳位配置與Model B Rev 2相同。(0x4、0x5、0x6則是Rev 2且記憶體為256 MB的Model B,但市面上似乎沒有這種板子。)

因為有些發行套件預設關閉Raspberry Pi板子的某些功能,所以,請修改/etc/modprobe.d/raspi-blacklist.conf這支檔案,若出現底下這兩行:

blacklist spi-bcm2708
blacklist i2c-bcm2708
   
請加上「#」註解掉。

#blacklist spi-bcm2708
#blacklist i2c-bcm2708

完成以上動作後,我們可使用底下指令檢查I2C上是否有裝置:

$ sudo i2cdetect -y 0
(若是Rev 1,參數是0,若是Rev 2,參數是1)

但會出現錯誤訊息「i2cdetect: command not found」,代表您尚未安裝相關軟體套件,請執行底下指令安裝安裝:

$ sudo apt-get install python-smbus i2c-tools

然後再執行一次

$ sudo i2cdetect -y 0
(若是Rev 1,參數是0,若是Rev 2,參數是1)

若出現錯誤訊息Error: Could not open file `/dev/i2c-0' or `/dev/i2c/0': No such file or directory,代表您尚未加入裝置(即時時鐘DS1307)。若成功了,則會出現底下的訊息:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

00:          -- -- -- -- -- -- -- -- -- -- -- -- --

10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --

70: -- -- -- -- -- -- -- --

其中68代表ds1307的位址,因為I2C可同時連接多個裝置,需以位址區分彼此,本專案只有一個裝置。

注意,若執行後出現UU字樣:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

00:          -- -- -- -- -- -- -- -- -- -- -- -- --

10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --

70: -- -- -- -- -- -- -- --


代表i2cdetect 跳過該位址不做偵測,因為該位址已經被某驅動程式佔用了,通常表示該位址上已經有個裝置了。

然後我們可以使用指令hwclock來查詢與設定即時時鐘的日期時間。

以底下指令可查詢目前記錄的日期時間。

$ sudo hwclock -r
Sat 01 Jan 2000 08:03:10 AM CST  -0.296255 seconds

第一次使用時,大概會是2000年左右的日期時間。

以底下指令則可查詢系統目前的日期時間。

$ date
Fri Mar 29 13:44:06 CST 2013

我們可手動設定系統的日期時間,譬如:

$ date --set="2013-03-29 13:39:25"

然後以底下指令將「系統的日期時間」寫入「即時時鐘」:

$ sudo hwclock -w

然後你可再以指令$ sudo hwclock -r查詢即時時鐘的日期時間,應該就會跟系統的一樣了。

之前以手動方式載入模組,若想讓系統在開機時時自動載入模組,請修改/etc/modules,加入底下這幾行內容。

i2c-bcm2708
i2c-dev
rtc-ds1307

若想在開機時開機時自動加入裝置DS1307,請以
$ sudo nano /etc/rc.local
修改/etc/rc.local檔。

在exit 0之前,插入底下內容。

若是Rev 1:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
sudo hwclock -s

若是Rev 2:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
sudo hwclock -s

其中指令hwclock的參數-s,代表要「sync(同步)」,會從即時時鐘讀取日期時間、設定系統的日期時間。這麼一來,每次開機後就都能擁有正確的日期時間囉。

完成囉。

1 comment:

  1. Anonymous6/10/20 13:16

    請問 網路上有的電路 會在 SDA , SCL 接電阻 到 5V ,
    在 DS1307 的規格文件的參考電路也有加電阻 ,
    在您的電路 , 沒有使用電阻 , 請問差別在哪裡?

    ReplyDelete