スイッチとロータリエンコーダの入力を処理するH8で学ぶマイコン開発入門(12)(2/4 ページ)

» 2007年09月19日 00時00分 公開

H8マイコンとトグルスイッチの接続

 トグルスイッチは図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)。


H8マイコンとスイッチの接続イメージ 図2 H8マイコンとスイッチの接続イメージ

※注1:
ポート7は入力ポートとしての機能のほかに、H8/3048F-ONEのA/D(アナログ/デジタル)変換入力、D/A変換出力としての信号端子も兼用しています。


トグルスイッチの状態を監視するサンプルプログラム

 トグルスイッチの状態を監視するプログラムをリスト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 トグルスイッチの状態を監視するプログラム

 スイッチの状態を監視するプログラムの中で重要なことは、監視している本体よりもむしろポートを定義している部分にあります。過去の連載でも解説していますが、ここでしっかり復習しておきましょう。

ポートの構造体

 リスト中の(1)(2)ではポート7の構造を定義しています。ポート7は8ビットの入力専用のポートでデータディレクションレジスタ(DDR)はありません。あるのはポート7データレジスタ(P7DR)のみです(表1)。各ビットが図2で図示した1つ1つのトグルスイッチの状態を表しています。

ポート7データレジスタ 表1 ポート7データレジスタ

 リスト中の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レジスタが存在しています。

volatileを付ける意味

 ここでもう1つ大事な「volatile」について復習しておきます。volatileは変数の型に対して付ける修飾子で、コンパイル時にその変数を使った処理に対する最適化を行わないようにします。

 例えばリスト2のような処理は、volatileを付けていないとCコンパイラによってリスト3のように最適化されてしまいます。最適化によってプログラムの実行速度が上がることが期待できるのですが、今回のポート入力の監視のような処理では最適化されることでかえって思ったとおりの動作をしないことがあります。そういうときに最適化を行わないようにするために付けるのがvolatileです。

while(1){
  if(P7.DR.BIT.B1==1){
    ……
  }
} 
リスト2 volatileを付けていないコード。if文の中でP7.DR.BIT.B1変数に値を代入することがない場合(ポート7は入力ポート、つまり値を参照するだけなので代入操作はない)、P7にvolatileを付けていなかった場合はリスト3のようにコンパイラが親切で最適化してしまう

   if(P7.DR.BIT.B1==1){
  while(1){
    ……
  }
}
リスト3 コンパイラがリスト2を最適化。プログラムだけを見た場合、P7.DR.BIT.B1変数への代入がないので、その変数を使ったif判定はwhileの外でやった方が効率がいいと判断されてしまう。しかし、実際にはこの変数はポート7の端子状態によって、プログラムとは関係ない部分で値が変わるため、ifの判定は毎回行わなければならない

 こういった定義を行うことで(注2)プログラムがIsSwOn()関数の(4)を通るたびに、引数に指定した番号のトグルスイッチの状態を知ることができます。配列no_to_bit[]はP7DRレジスタの値を8ビットまとめて取得したときに、引数に指定した番号のトグルスイッチの状態のみを知るためのビットマスクとなります。

 以上でトグルスイッチからの入力が使えるようになります。これまでの連載で紹介してきたモータ制御のサンプルプログラムに上記の関数を追加することで、モータをより自由に操作できるようになることでしょう。

※注2:
H8マイコンは第5回で紹介したHEWという開発環境を使うことで、このあたりの定義を開発環境が自動的に作成してくれるので、われわれの手間はだいぶ省けてしまいます。


Copyright © ITmedia, Inc. All Rights Reserved.