PR

【ライブラリ未使用】DS3231の使い方

ライブラリないから自作せないかんやん。。。

ということで、手持ちのpsoc6とDS3231と通信できるようにします。

立プロ

姫野 秀徳(ひめの ひでのり)
組み込みエンジニア。
第二種電工事士、基本情報技術者、Code.org認定教師。
microbitを用いた電子工作&プログラミング教室を開校。
組み込み開発の実際を発信するyoutuber。

立プロをフォローする

DS3231とは

DS3231とは、リアルタイムクロック(RTC)モジュールです。

I2Cでマイコンと通信させて時刻情報の設定・取得ができます。スレーブアドレスは0x68。

電源は3.3V、5Vともに可、400kHz通信で信号レベルは電源電圧と同等。

時刻誤差は2ppm。枝番があるようで末尾がSNだと2ppm、Mだと5ppm、Nだと偽物らしいです。

amazonだとボタン電池付きで1つ300円で手に入ります。

データシートは日本語化したので、こちら参照ください。

使い方

DS3231のレジスタマップを見てもらえればと思いますが、00番地は秒、01番地は分、のように決められています。

BCD方式

まず理解しておきたいのが、このICで設定する時刻情報はBCD方式を採用していて、

1バイトのうち、十の位を上位4ビット、一の位を下位4ビットで表現します。

そのため、45秒と秒レジスタに書き込みたい(←後述)場合、十の位の4と一の位の5を作って1バイト化しないといけないので、ちょっとめんどくさいです。

45の4は、10で割って4ビット左にシフトさせる、45の5は10で割った余りですね。

読み込むときもめんどくさいです。

0x45だったら、40は右に4ビットシフトして10倍して得られ、5は0x0Fの論理和をとればいいですね。

時刻情報を設定する

i2cの基本ですが、まずスレーブアドレス + R/Wビット0を送ってアクノリッジを確認します。

続いて、書込みの始点になるアドレスを送ります。

たとえば、0x02番地だったら、00000002ですね。

その後、書き込むデータを送ります。

このとき1バイトだけでなく、複数バイト書き込みすることもできます。

1バイト書き込むと、次のレジスタに向くので、また1バイト送るとそのレジスタに書き込まれます。

int8_t arr[4] = {0x02, 0x34, 0x12}

たとえば、この配列を送ると、

最初の1バイトが書き込みレジスタ指定で0x02番地が指定され、次の0x34で0x02番地に0x34を書き込みます。

DS3231は0x03番地に向くので、0x12が0x03番地に書き込まれる、ということです。

だから私は一回の書き込みで8バイト(レジスタ指定1バイト+データ7バイト)送って、0x00番地から0x06番地まで一気に書き込んでます。

時刻情報を取得する

時刻情報設定の最初にもやりましたが、まずスレーブアドレス + R/Wビット0を送ってアクノリッジを確認します。

続いて、読み込みの始点になるアドレスを送ります。

これをやらないと、直近の操作で向いたレジスタからの情報を取得してしまいます

つづいて、まずスレーブアドレス + R/Wビット1を送ってアクノリッジを確認します。

すると、このあとDS3231が始点のアドレスの中身を送ってくるので、マイコン側で受信処理します。

DS3231はマイコンが返すアクノリッジを確認すると、次のレジスタの中身を送ってきます。

ほしいバイトサイズ分のデータを配列に入れるなりして受け取ったら、マイコン側の受信処理を止めます。

DS3231はマイコンからのアクノリッジが返ってこないことを確認すると、データの送信を停止します。

まとめ

時刻の設定・取得はBCD方式なので、ちょっとめんどくさいです。

ただ一度コード作っちゃえば、すごく便利なICなのは間違いない!

FATFSでf_utimeと組み合わせて、ファイルに正確なタイムスタンプ機能を実装することもできます!

コメント

タイトルとURLをコピーしました