PSoCとリアルタイムクロックで日時を表示する

psoc_rtc_01.gif
今回はリアルタイムクロックIC「RTC-8564NB」をPSoCへ接続して日時を液晶モジュールに表示する。

「RTC-8564NB」は秋月電子で500円程度で販売されているもので、PSoCとの接続にはI2Cを利用する。"多機能"を謳うRTCだが...シンプルかつ低機能なモデルだ。

psoc_rtc_02.gif
プログラミングには今回もPSoC Designerを利用する。使用言語もC言語とした。

psoc_rtc_03.gif
「Device Editor」の「Selection」画面が開いたら、まず「Digital Comm」にある「I2Cm」を右クリックして現れたメニューから「Select」を選択してプロジェクトに追加する。

psoc_rtc_04.gif
同様に「Misc Digital」の「LCD」もプロジェクトに追加する。

psoc_rtc_05.gif
これでPSoCとリアルタイムクロックを接続するための「I2Cm」と取得日時を表示するための「LCD」がプロジェクトにつかされた。次に設定を行うため「Config」メニューの「Interconnect」を選択して画面を切り替える。

psoc_rtc_06.gif
まず「LCD_1」の設定を行う。使用するポートは「Port_2」にした。

psoc_rtc_07.gif
次に「I2Cm_1」を設定する。
「I2C_Port」を「Port_0」に、
「SDA_Pin」を「Port_0_0」に、
「SCL_Pin」を「Port_0_1」に設定する。
これで全ての設定が終わった。ソースコードを記述するため「View」メニューの「Application Editor」を選択して画面を切り替える。

psoc_rtc_08.gif
「I2Cm」のサンプルコードを開くためツールバーの「Digital Comm」の「I2Cm」を選択して「User Module Datasheet」ボタンを押す。

psoc_rtc_09.gif
ここにはリアルタイムクロック「DS1307」使用時のサンプルコードが紹介されている。今回利用する「RTC-8564NB」とは若干利用方法が異なるものの基本的な流れはまったく同じだ。

また、今回は「迷走の果て・Tiny Objects」というブログの「リアルタイムクロック::PSoC」も参考にした。このページはそのものずばりの「RTC-8564」を利用したものなのでそのままでも利用できた。

psoc_rtc_10.gif
最終的に以下のようなソースコードとした。エラーや電圧降下による失敗時はそのまま同じ日時を書き込んでいたりするのでそのまま"実用"することはできないソースコードだが使い方の把握はできるだろう。
RTC-8564NBのスレーブアドレスはグループ1が0xA(1010)、グループBが0x1(1)で、全体として2進数で1010001x(xは書き込み時0、読み込み時1)となる。PSoC Designerの「I2Cm」ではxの部分を無視した「1010001」(=0x51)をスレーブアドレスとして用いる。

メイン処理の直前「Timer control」と「Timer data」をコメントアウトしたものに置き換えると、リアルタイムクロックを10秒タイマーとして利用することもできる(フラグを消去する処理は入れていないが)。

//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules

BYTE rxBuf[17];
const BYTE txCBuf[] = { 0x00, //Slave internal sub-address 0
0x00, //control 1
0x00, //control 2
0x56, //Seconds (12:34:56)
0x34, //Minutes
0x12, //Hours
0x17, //Days (2007/6/17 (SUN))
0x00, //Weekdays
0x06, //Months/Century
0x07, //Years
0x80, //Minute Alarm (No Alarm)
0x80, //Hour Alarm
0x80, //Day Alarm
0x80, //Weekday Alarm
0x00, //CLKOUT frequenct (No CLKOUT)
0x00, //Timer control (Disable)
0x00}; //Timer Data
// 0x82, //Timer control (Use 10 Seconds Timer)
// 0x0A}; //Timer Data

const char* ppszWeekday[] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};


void main()
{
BYTE status; // I2C communication status
BYTE i; // Temp counter variable

LCD_1_Start();
I2Cm_1_Start(); // Initialize I2C Master interface
// Set the time
status = I2Cm_1_bWriteCBytes(0x51,txCBuf,17,I2Cm_1_CompleteXfer);
// In a endless loop, keep reading the time from the DS1307
do
{
// Write sub-address to DS1307
// Perform a combined transfer by leaving off the Stop on the Write
// command and beginning the Read with a Repeat Start.
I2Cm_1_bWriteCBytes(0x51,txCBuf,1,I2Cm_1_NoStop );
status = I2Cm_1_fReadBytes(0x51,rxBuf,16,I2Cm_1_RepStart );

if(status == 0 || rxBuf[2] & 0x80) //check VL flags of seconds' data
{
// Flag an error condition
LCD_1_Position(0,0);
LCD_1_PrCString("Error");

//retry
status = I2Cm_1_bWriteCBytes(0x51,txCBuf,17,I2Cm_1_CompleteXfer);
continue;
}

LCD_1_Position(0,0);
LCD_1_PrHexByte(rxBuf[4] & 0x3f); // Hours
LCD_1_PrCString(":");
LCD_1_PrHexByte(rxBuf[3] & 0x7f); // Muinutes
LCD_1_PrCString(":");
LCD_1_PrHexByte(rxBuf[2] & 0x7f); // Seconds
LCD_1_PrCString(" ");
LCD_1_PrHexByte(rxBuf[0]); //control 1
LCD_1_PrCString(" ");
LCD_1_PrHexByte(rxBuf[1] & 0xbf); //control 2

LCD_1_Position(1,0);
LCD_1_PrHexByte(rxBuf[8]); // Years
LCD_1_PrCString("/");
LCD_1_PrHexByte(rxBuf[7] & 0x1f); // Months
LCD_1_PrCString("/");
LCD_1_PrHexByte(rxBuf[5] & 0x3f); // Days
LCD_1_PrCString(" ");
LCD_1_PrCString(ppszWeekday[rxBuf[6] & 0x07]); // Weekdays
LCD_1_PrCString(" ");
LCD_1_PrHexByte(rxBuf[15]); // Timer
} while(1);
}





_DSC9011.JPG
「RTC-8564NB」のデータシートの中のレジスタテーブルが時刻書き込みや読み出し時の書式になる。ソースコード上でもこの順番通りに「txCBuf」変数などを設定した。

_DSC9005.JPG
動作確認はCY8C29466とPSoCMiniEval基板、秋月電子で購入したリアルタイムクロック「RTC-8564NB」とキャラクタ液晶モジュールで行った。

_DSC9009.JPG
電源を入れるとすぐにソースコード上で指定した日時「2007/06/17 12:34:56」が表示された。時刻の右側の数値はControl1とControl2の値、曜日の右側はTimerの値を示す。

当然のことながら1秒ごとに秒針が進む。

_DSC9010.JPG
これが利用したリアルタイムクロック。変換基板により8ピンDIPで、そのままブレッドボードに挿せる。

4ピンをGND、5ピンをポート00、6ピンをポート01、8ピンをVCCにそれぞれ接続する。今回はさらに5ピンとVCC、6ピンとVCCの間にそれぞれ2.2kΩのプルアップ用抵抗を接続した。

コメント (1)

edy:

初めまして、edyと申します。
PSoCで検索してこちらを見つけました、刺激になりました。
引越の準備と職探しのため(今、無職です)全く実験ができない毎日なのですが、落ち着いたらまたいじってみたいです。
曜日の表示の方法は参考にさせて頂きます。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)


カテゴリー「電子工作」 のエントリー