PSoC Expressで標準に用意されていない機能を実装する

psoc_new_func_01.gif
今回はPSoC Express 2.2に含まれていない機能を自分で作り出して使う方法を紹介する。

PSoCの開発環境と言うとほとんどの開発者がPSoC Designerを挙げる。PSoC Designerは無料の状態ではアセンブラ、1万6000円程度のフルライセンスもしくは2000円程度の限定ライセンスを購入すればC言語による開発ができ、PSoCの機能をほぼすべて利用できる。

対してPSoC Expressでは"ソースコードを書かずに開発ができる"という特徴を持つため、Cypressによって用意された汎用的な機能しか利用できない。言い換えると応用的な独自機能は使うことができない...と思われがちだが実は違う。PSoC Expressは内部的には"自動的にソースコードを生成するCコンパイラ"なため、自動的にソースコードを生成する部分をユーザーが指定してしまえば、C言語を使って独自の機能を追加できる。

PSoC Designerのように(仮想的な)内部のブロック配置をPC上で見ながら1本1本配線するというような細かいことはGUIではできない。しかし無料で扱えるPSoC Expressでもそれなりに細かい設定ができる。

今回はLEDを2回の連続点滅を繰り返す処理を例に簡易的な方法で独自機能を実装する。

psoc_new_func_02.gif
PSoC Express上でLEDを配置する。画面左下の「OUTPUT」から「Output Driver Catalog」を開き、「On/Off with blink」を選択する。右側の設定欄では初期値を「BLINKING」、点滅周期を「4」Hzに設定する。

PSoC Expressではこの画面左側のツリーに表示されるモジュールもユーザーが自由に追加できる。ただしシュミレーションや回路図生成などに対応しなければいけない関係上、モジュールの追加はかなり面倒になっている。

psoc_new_func_03.gif
LEDを示す「Output1」が配置されたら「Build」をクリックしてビルドする。

psoc_new_func_04.gif
今回はMiniEvalで動作確認をするため出力ポートをLEDが搭載されているP23に設定する。ちなみにデバイスはCY8C29466を利用した。

psoc_new_func_05.gif
これでビルドが実行された。内部的にはビルド時に毎回ソースコードの自動生成が行ない、そのソースコードをビルドしている。

psoc_new_func_06.gif
ビルドが終了するとプロジェクトフォルダの中に、プロジェクト名と同じフォルダ(ここでは「Untitled」)が作られ、その中にCやアセンブラのソースコードが格納されている。

psoc_new_func_07.gif
ちなみにLEDの点滅処理は「CMX_BLINKINGLED.c」に実装されている。

グローバル変数BlinkingLedStateに対して1をXORしてその値を元にDISetPin関数でポートのHigh/Lowを切り替えている。
点滅周期はグローバル変数BlinkingLedCountとSystemTimer_bGetTickCntr関数の差から得ている。

残念なことにこのファイルを編集しても意味がない。PSoC Expressではビルドするたびに新しくソースコードを自動生成するためだ。

psoc_new_func_08.gif
編集するのは「\Program Files\ Cypress MicroSystems\ PSoC Express\ CMXData\ CMXDRV\ CMX\ BLINKINGLED\」にある「BLINKINGLED.c」になる。

Program Files以下のファイルを編集するため、きちんとバックアップを取ってから行うか、Virtual PCのように簡単に元の状態に戻せる環境下で開発するといいだろう。

psoc_new_func_09.gif
ソースコードは先ほどプロジェクトファイルの中にあったものと(ほぼ)同じだ。

psoc_new_func_10.gif
このソースコードを2回点滅を繰り返させるためこのように修正した。

void CMX_BLINKINGLED_SetValue(const CMX_BLINKINGLED_ParameterBlock * pPBlock, BYTE bMode)
{
    BYTE bPinPort;
    BYTE bInstance;

bInstance = pPBlock->BLINKINGLED_INSTANCE;

if (bMode >= 2)
{ // If Value is 2 or great, put LED in blink mode.

if ( (SystemTimer_bGetTickCntr() - BlinkingLedCount[bInstance]) >= pPBlock->BLINKINGLED_BlinkRate)
{
BlinkingLedCount[bInstance] = SystemTimer_bGetTickCntr();
BlinkingLedState[bInstance]++;

bPinPort = DIOChannelPins[(pPBlock->BLINKINGLED_ChannelID)];
switch(BlinkingLedState[bInstance] % 7)
{
case 0: DISetPin(bPinPort,1); break;
case 1: DISetPin(bPinPort,0); break;
case 2: DISetPin(bPinPort,1); break;
default: DISetPin(bPinPort,0); break;
}
}
}
else
{
bPinPort = DIOChannelPins[(pPBlock->BLINKINGLED_ChannelID)];
if ((pPBlock->BLINKINGLED_DRIVESENSE ^ bMode ) == 0) { // Set LED to ON or OFF depending on mode.
DISetPin(bPinPort,1);
} else {
DISetPin(bPinPort,0);
}
}
}


psoc_new_func_11.gif
ソースコードの修正が済んだらPSoC Expressに戻りビルドを行う。すると修正したソースコードを元にHEXファイルが生成され、PSoCへ書き込むとLEDが2回点滅する動作が繰り返される。


今回の実装方法はかなり邪道で「プロジェクト」として保存するのが面倒な方式だ。しかし「PSoC ExpressはCコンパイラ!」という認識が加わり、PSoC Expressの可能性がさらに高まるだろう。


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