トグルスイッチは図2のようにH8/3048F-ONEのポート7の0〜7端子に接続されています。
トグルスイッチからH8マイコンにHighを入力したいときはスイッチのレバーを何もつながっていない側へ倒します。そうすることで10kΩのプルアップ抵抗を間に挟んだ5Vの電圧がH8マイコンのポート7に入力されます。そしてH8マイコンにLowを入力したいときはスイッチのレバーをグランド(GND)とつながっている側に倒します。そうすることで、いままで5Vが入力されていたポート7はLow(0V)に落ちることになります。
また、H8マイコンとトグルスイッチの間にはDIPスイッチが挟まれています。ポート7は入力専用のポートですが、トグルスイッチからの入力だけでなく自由に入力ポートとして使えるように、DIPスイッチをOFFにすることでトグルスイッチとの接続を切ることができます。これはスイッチの使い方で最初に示した用途といえます(注1)。
トグルスイッチの状態を監視するプログラムをリスト1に示します。
struct st_p7 { // struct P7 union { // P7DR unsigned char BYTE; // Byte Access struct { // Bit Access unsigned char B7:1; // Bit 7 unsigned char B6:1; // Bit 6 unsigned char B5:1; // Bit 5 unsigned char B4:1; // Bit 4 unsigned char B3:1; // Bit 3 unsigned char B2:1; // Bit 2 unsigned char B1:1; // Bit 1 unsigned char B0:1; // Bit 0 } BIT; } DR; }; ……(1) #define P7 (*(volatile struct st_p7 *)0xFFFFCE) // P7 Address ……(2) const char no_to_bit[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; ……(3) //---------------------------------------------------------------------- // IsSwOn //---------------------------------------------------------------------- // [説明] // 指定したスイッチの状態を検査します // sw=0のときトグルスイッチ0、sw=1のときトグルスイッチ1を検査します // スイッチはON(上向き)でP7より1が、OFF(下向き)でP7より0が読み出されます // [入力] // sw :検査するスイッチを指定します(0〜7) // [出力] // なし // [戻り値] // スイッチがONのとき (上向き) :TRUE // スイッチがOFFのとき(下向き) :FALSE //---------------------------------------------------------------------- int IsSwOn(int sw) { if((sw<0) || (sw>7)){ // スイッチ番号が不正のときはFALSEを返す return FALSE; } // 各スイッチに対応するビットが1のときTRUE if(P7.DR.BYTE & no_to_bit[sw]){ ……(4) return TRUE; } // 各スイッチに対応するビットが0のときFALSE return FALSE; }
スイッチの状態を監視するプログラムの中で重要なことは、監視している本体よりもむしろポートを定義している部分にあります。過去の連載でも解説していますが、ここでしっかり復習しておきましょう。
リスト中の(1)(2)ではポート7の構造を定義しています。ポート7は8ビットの入力専用のポートでデータディレクションレジスタ(DDR)はありません。あるのはポート7データレジスタ(P7DR)のみです(表1)。各ビットが図2で図示した1つ1つのトグルスイッチの状態を表しています。
リスト中のunion(共用体)は1つのメモリ領域に複数の変数を割り当てます。つまりP7.DR.BYTEとP7.DR.BITは同じアドレスになります。そしてリスト1のように記述することで、表1のP7DRを8ビットまとめて扱うか1ビットずつ個別に扱うかを選べるようになります。例えば「x=P7.DR.BYTE;」と記述するとP7DRの8ビットの状態を0x00〜0xffの値として一括して取得できますし、「x=P7.DR.BIT.B5;」と記述するとP7DRのビット5の状態だけが0か1で取得できます。
そしてP7のアドレスは(2)で定義しています。これはH8/3048F-ONEのハードウェアマニュアルで定義されているアドレスで、H8マイコンのメモリ上のこの番地にP7DRレジスタが存在しています。
ここでもう1つ大事な「volatile」について復習しておきます。volatileは変数の型に対して付ける修飾子で、コンパイル時にその変数を使った処理に対する最適化を行わないようにします。
例えばリスト2のような処理は、volatileを付けていないとCコンパイラによってリスト3のように最適化されてしまいます。最適化によってプログラムの実行速度が上がることが期待できるのですが、今回のポート入力の監視のような処理では最適化されることでかえって思ったとおりの動作をしないことがあります。そういうときに最適化を行わないようにするために付けるのがvolatileです。
while(1){ if(P7.DR.BIT.B1==1){ …… } }
if(P7.DR.BIT.B1==1){ while(1){ …… } }
こういった定義を行うことで(注2)プログラムがIsSwOn()関数の(4)を通るたびに、引数に指定した番号のトグルスイッチの状態を知ることができます。配列no_to_bit[]はP7DRレジスタの値を8ビットまとめて取得したときに、引数に指定した番号のトグルスイッチの状態のみを知るためのビットマスクとなります。
以上でトグルスイッチからの入力が使えるようになります。これまでの連載で紹介してきたモータ制御のサンプルプログラムに上記の関数を追加することで、モータをより自由に操作できるようになることでしょう。
Copyright © ITmedia, Inc. All Rights Reserved.