こんにちは。koraです。
今回は、HM-StarterKitの表示用LEDとスイッチを使用できるようにします。これを使うと、動作確認・センサの調整・探索・最短走行などのモードの確認がやりやすくなります。
HM-StarterKitの表示用LEDはD3~D6の4つ、スイッチはSW2~SW4の3つです。これらは直接マイコンにつながっているわけではなく、IOエキスパンダ(PCA9557PW)というデバイスにつながっています。このIOエキスパンダとマイコンはI2Cを使って通信しますので、まずはI2Cの準備をします。
I2Cの準備
i2c.hとi2c.c
サンプルプログラムのStep7からi2c.hとi2c.cをコピーして、現在のプロジェクトに追加します。そのままだとテストするときにスイッチの状態がわかりにくいので、225行目と226行目を次のように書き換えて、IOex_SWITCH関数でスイッチの状態が読み込まれた際にprintfで出力するようにします。
return sw; //SCI_printf("who=%x\n\r",who);
SCI_printf("sw=%x\n\r",sw); return sw;
intprg.c
intprg.cファイルに、externを使ったプロトタイプ宣言を追加します。
extern int_i2c_ee(void); extern int_i2c_rx(void); extern int_i2c_tx(void); extern int_i2c_te(void);
そして次の行を、
// RIIC2 EEI2 void Excep_RIIC2_EEI2(void){ } // RIIC2 RXI2 void Excep_RIIC2_RXI2(void){ } // RIIC2 TXI2 void Excep_RIIC2_TXI2(void){ } // RIIC2 TEI2 void Excep_RIIC2_TEI2(void){ }
以下のように書き換えて、I2C関連の割り込みが発生したときにi2c.cの関数が呼ばれるようにします。
// RIIC2 EEI2 void Excep_RIIC2_EEI2(void){ int_i2c_ee(); } // RIIC2 RXI2 void Excep_RIIC2_RXI2(void){ int_i2c_rx(); } // RIIC2 TXI2 void Excep_RIIC2_TXI2(void){ int_i2c_tx(); } // RIIC2 TEI2 void Excep_RIIC2_TEI2(void){ int_i2c_te(); }
I2Cのテスト
my_hm_starterkit.c
インクルードを追加します。
#include “i2c.h”
そして、テスト用にmain関数を次のように書き換えます。
void main(void) { init_all(); init_I2C(); unsigned long i = 0; IOex_SETTING(); while(1){ IOex_LED(0xF0); // LEDの状態を0xF0~0xFFで指定 IOex_SWITCH(); //この関数を呼び出すとスイッチの状態を シリアル通信で出力 for(i = 0; i < 100*1000*100; i++); //画面クリアシーケンス SCI_printf("\x1b[2J"); //クリアスクリーン[CLS] SCI_printf("\x1b[0;0H"); //カーソルを0,0に移動 } }
プログラムを実行し、問題がなければ写真のように4つのLEDが点灯します。
また、シリアル通信でTeraTerm上にスイッチの状態が画面に出力されます。スイッチSW2~SW4を押すことで、表示される値が変化します。
インターフェースの作成
IOエキスパンダが動作することが確認できましたので、次は使いやすいように、サンプルプログラムのStep7にならってLEDのインターフェースを整えます。
interface.c
i2c.hのインクルードを追加します。
#include "i2c.h"
入力した数値を二進数でLEDに表示する関数を追加します。HM-StarterKitのLEDの並びは二進数とは少し異なるので、ビットの順を入れ替えて対応しています。
void LED(short led_num){ short led_pt = 0x00; if((led_num & 0x01) == 0){ led_pt |= 0x02; } if((led_num & 0x02) == 0){ led_pt |= 0x01; } if((led_num & 0x04) == 0){ led_pt |= 0x08; } if((led_num & 0x08) == 0){ led_pt |= 0x04; } if(led_num == 0){ led_pt = 0xFF; } IOex_LED(led_pt); }
interface.h
ヘッダーファイルにプロトタイプ宣言を追加して、他のソースファイルからもinterface.hをインクルードすればLED関数を呼び出せるようにします。
void LED(short led_num);
init.c
I2C通信とIOエキスパンダの初期化をinit_all関数の中で済ませるために、以下の変更を加えます。まず、i2c.hとinterface.hのインクルードを追加します。
#include "i2c.h" #include "interface.h"
init_all関数に次の行を追加します。
init_I2C(); IOex_SETTING(); LED(0);
my_hm_starterkit.c
LED関数とinit_all関数の動作を確認します。main関数を以下のように書き換えてHM-StarterKitに書き込みます。
void main(void) { unsigned long i, j; init_all(); while(1){ for(j = 0; j < 16; j++){ LED(j); for(i = 0; i < 100*1000*100; i++); } } }
書き込みが終わったら実行します。成功していれば、0から15までの数をLEDで表します。
次回
今回までいろいろ下準備をしてきましたが、次回からいよいよ迷路探索アルゴリズムを追加して、実際の迷路でゴールを探すようにしたいと思います。