
写真1 AD9833 DDS MSOP 0.5ピッチ 変換基板に乗せる
それはさておき、
このチップは10ピンのMSOPで、写真にようにピンセットの先ほどの大きさです。
変換基板に取り付けましたが、ピンのピッチは0.5なので、半田付けにはちょっと技術が必要です。
まずチップをゲルタイプの瞬間接着剤で正確な位置に仮止めしておきます。
フラックスをほんのわずか塗って、すべてのピンにわざとまたがるくらい半田を盛ります。
半田吸い取り線で、余分な半田を吸い取って、出来上がり。
慣れれば簡単ですが、最初は数個パーにする覚悟がいります(笑)。
このDDSは、マスタクロック(MCLK)周波数は最高25MHzで、その場合最高発振周波数(ナイキスト周波数)は12.5MHzとなり、分解能は0.1Hzです。
今回は手持ち部品の関係で、20MHzのクリスタルを使用したので、10MHzまでのプログラマブルオシレータとして、実験してみました。この場合の分解能は約0.075Hzです。
PSoC3 RTCコンポーネントを使用した時計
投稿日 2012/05/17
PSoC3のRTC(リアルタイムクロック)コンポーネントを使用した時計を作ってみました。
名付けて「ピーソックロック PSoClk」です。
源振は外付けの32.768KHzの水晶発振子です。精度はこの水晶発振子に依存します。PSoC3評価ボードのY1に取り付けます。
表示はI2C LCDに行います。

写真1 RTCコンポーネントを使用したデジタル時計
このRTCコンポーネントは、秒、分、時、日、月、年毎に割り込みをハンドリングできるほか、アラームの設定、サマータイムの設定にも対応しています。
今回使用するのはRTCコンポーネントとI2Cコンポーネントです。
I2Cコンポーネントは表示に使うLCDのためのもので、RTCには直接関係ありません。
32.768KHzの水晶発振を有効にするため、cydwタブのClocks画面を開いて、その中の表をダブルクリックし、configure system clocks画面を表示し、その中のXTAL 32Kにチェックを入れておきます。
RTCコンポーネントの説明書は、RTCコンポーネントをダブルクリックして表示されるconfigure 'RTC'画面のDatasheetボタンをクリックすると表示されます。ここには用意されている関数などが説明されています。
プログラミングの手順は、
まず、時刻、年月日の初期値をセットする構造体に初期値をセットしておきます。
構造体はRTC.hの中で以下のように宣言されています。
typedef struct _RTC_TIME_DATE
{
uint8 Sec;
uint8 Min;
uint8 Hour;
uint8 DayOfWeek;
uint8 DayOfMonth;
uint16 DayOfYear;
uint8 Month;
uint16 Year;
} volatile RTC_TIME_DATE;
これに必要なデータをセットして、RTC_WriteTime()をコールします。
グローバル割り込みを有効にし、さらにRTC_WriteIntervalMask(RTC_INTERVAL_SEC_MASK);
関数で1秒毎の割り込みを有効にしておきます。
RTC_Start()関数を呼んで起動します。
割り込み処理は、Generated Sourceの下の、RTC_INT.cの中にある割り込みハンドラで行えるようになっています。そこに直接コーディングするか、必要なハンドラのみmain.cにコピーして(元はコメントにする)、必要な処理をコーディングします。
今回は1秒単位で表示を変更したいので、RTC_EverySecondHandlerをmain.cにコピーして使いました。
RTC_INT.cの中にあるRTC_EverySecondHandlerの中で1秒毎にフラグinterval_flagをセットします。メインループの中で、そのフラグが立ったら、その時の時刻をRTC_ReadTime関数で読んで、LCDに表示します。
//RTC_INT.c 部分
extern uint8 interval_flag;
void RTC_EverySecondHandler(void)
{
/* Place your every second handler code here.*/
/* #START EVERY_SECOND_HANDLER_CODE */
interval_flag = 1;
/* #END */
}
曜日の表示は、RTC_DayOfWeek関数を呼んで行っています。この関数はRTCコンポーネントの説明書(DATASHEET)には出てきませんが、RTC.cの中にあります。
今回は現在時刻を自由に設定できるようにはしていません。
アラームなどは使用していません。
【schematic】

【program】
I2C LCDの部分は省略
//main.c
#include <device.h>
#include <stdio.h>
#include <RTC.h>
void I2C_LCD_Init(void);
void I2C_LCD_WriteString(uint8, uint8, uint8*);
uint8 RTC_DayOfWeek(uint8, uint8, uint16);
RTC_TIME_DATE RTC_InitVal; //時刻初期値用構造体
RTC_TIME_DATE *RTC_Current; //現在時刻構造体へのポインタ
uint8 interval_flag = 0; //1秒毎にセットされるフラグ
void RTC_Setup(){
RTC_InitVal.Year = 2012;
RTC_InitVal.Month = 12;
RTC_InitVal.DayOfMonth = 31;
RTC_InitVal.Hour = 23;
RTC_InitVal.Min = 59;
RTC_InitVal.Sec = 30;
RTC_WriteTime(&RTC_InitVal); //時刻の初期値を設定する
RTC_WriteIntervalMask(RTC_INTERVAL_SEC_MASK); //秒毎の割り込み許可
RTC_Start(); //RTC起動
}
void DispClock(){
char string[5];
uint8 week;
char week_name[7][4] = {"SUN","MON","TUE","WED","THU","FRI","SAT"};
RTC_Current = RTC_ReadTime();
sprintf(string, "%4d", RTC_Current->Year);
I2C_LCD_WriteString(1, 1, string);
sprintf(string, "%02d", (uint16)RTC_Current->Month);
I2C_LCD_WriteString(6, 1, string);
sprintf(string, "%02d", (uint16)RTC_Current->DayOfMonth);
I2C_LCD_WriteString(9, 1, string);
sprintf(string, "%02d", (uint16)RTC_Current->Hour);
I2C_LCD_WriteString(7, 0, string);
sprintf(string, "%02d", (uint16)RTC_Current->Min);
I2C_LCD_WriteString(10, 0, string);
sprintf(string, "%02d", (uint16)RTC_Current->Sec);
I2C_LCD_WriteString(13, 0, string);
week = RTC_DayOfWeek(RTC_Current->DayOfMonth, RTC_Current->Month, RTC_Current->Year);
I2C_LCD_WriteString(12, 1, week_name[week]);
}
void main(){
CyGlobalIntEnable; //グローバル割り込み許可
RTC_Setup(); //RTCを初期化
I2C_Start(); //I2Cを初期化
I2C_LCD_Init(); //I2C LCDを初期化
I2C_LCD_WriteString(0, 0, "PSoClk" );
I2C_LCD_WriteString(5, 1, "/" );
I2C_LCD_WriteString(8, 1, "/" );
I2C_LCD_WriteString(9, 0, ":" );
I2C_LCD_WriteString(12, 0, ":" );
for ( ;; ){
if(interval_flag){
DispClock(); //時刻を表示
interval_flag = 0;
}
CyDelay(100);
}
}
変更履歴: 2012/05/29 誤り箇所修正
(JF1VRR)