102.PIOからスイッチ情報を入力する


2001/02/25 【ソフトウエア編TOPに戻る】

102−1.PIOを入力として使う

これから紹介するプログラムでは、4個のスイッチからそれぞれボタンが押されたことを検知して、押されたボタンによってLED1とLED2の点灯のしかたに変化を持たせます。ハードウエアは電子回路編 3.AKI-H8開発キットの回路 を参照して下さい。

ここをクリックすると、ダウンロードできます。(piotest1.c)

/**************************************************/
/* PIOテスト                     RIKIYA 2001.2.25 */
/*                                     piotest1.c */
/*                                      H8-3048/F */
/* port4から                                      */
/* port5のLED1とLED2を点灯する。                  */
/* sw1 を押すと 消灯する。                        */
/* sw2 を押すと LED1を点灯する。                  */
/* sw3 を押すと LED2を点灯する。                  */
/* sw4 を押すと 点滅する。                        */
/**************************************************/

#include <3048f.h>

/* メイン関数 ****************************************/
void main(void){

P4.DDR = 0x00;           /*port4入力に設定 操作用sw1〜4*/
P4.PCR.BYTE = 0xff;      /*port4プルアップon           */
P5.DDR = 0xff;           /*port5出力に設定 表示LED     */
P5.PCR.BYTE = 0x00;      /*port5プルアップoff          */

     while(1){

          if (P4.DR.BIT.B4 == 0){      /*sw1の入力検出         */
               P5.DR.BYTE = 0x00;      /*port5のLEDを消灯      */
          }
          else if (P4.DR.BIT.B5 == 0){ /*sw2の入力検出         */
               P5.DR.BYTE = 0x01;      /*port5のLED1を点灯     */
          }
          else if (P4.DR.BIT.B6 == 0){ /*sw3の入力検出         */
               P5.DR.BYTE = 0x02;      /*port5のLED2を点灯     */
          }
          else if (P4.DR.BIT.B7 == 0){ /*sw4の入力検出         */
               P5.DR.BYTE = 0x01;      /*port5のLEDを交互に点滅*/
               wait();
               P5.DR.BYTE = 0x02;
               wait();
               P5.DR.BYTE = 0x01;
               wait();
               P5.DR.BYTE = 0x02; 
               wait();
               P5.DR.BYTE = 0x01;
               wait();
               P5.DR.BYTE = 0x02; 
               wait();
           }

          else {                       /*sw入力が無いときの処理*/

               P5.DR.BYTE = 0x03;      /*port5のLED1と2を点灯  */

          }
     }
}

/*時間稼ぎ関数*************************************/
wait(){
long i;
     for (i=0;i<0x2ffff;i++){
          /*なにもしない*/
     }
return;
}

【先頭に戻る】


102−2.プログラムの説明

 

【1】ヘッダーファイルの取り込み

#include <3048f.h>

先ず始めに3048f.hのヘッダーファイルを読み込む宣言をします。これでポート操作を行なうための変数が使用できるようになります。

 

【2】ポートの初期化

P4.DDR = 0x00;           /*port4入力に設定 操作用sw1〜4*/
P4.PCR.BYTE = 0xff;      /*port4プルアップon           */
P5.DDR = 0xff;           /*port5出力に設定 表示LED     */
P5.PCR.BYTE = 0xff;      /*port5プルアップoff          */

次に、各ポートの初期化を行ないます。port4を入力に設定し、port5を出力に設定します。

 

【3】sw1の検出と処理

次のwhile(1){  }の中で、押されたスイッチに応じた処理をしています。

if (P4.DR.BIT.B4 == 0){      /*sw1の入力検出     */
     P5.DR.BYTE = 0x00;      /*port5のLEDを消灯  */
}

ここでは、「もしport4bit40の場合は、port5からデータ0x00 (0000 0000)を出力しなさい。」と言っています。port4bit4にはスイッチ1(sw1)が接続されていて、押されていない間はbit4DC5Vが加わり、押されるとbit40(ゼロ)Vになります。つまり、bit40であるということは、スイッチが押されていることを示します。ここでは、sw1が押されていたら、LEDの1と2が消灯されることになります。

 

【4】sw2の検出と処理

else if (P4.DR.BIT.B5 == 0){ /*sw2の入力検出     */
     P5.DR.BYTE = 0x01;      /*port5のLED1を点灯 */
}

次は、「もしそうでないなら、今度はport4bit50の場合は、port5からデータ0x01 (0000 0001)を出力しなさい。」と言っています。port4bit5にはスイッチ2(sw2)が接続されていて、sw1と同様に押されたことが検出できます。ここでは、sw2が押されていたら、LED1が点灯することになります。

ここで、「もしそうでないなら(else if)」というのは、先ほどの条件「もしport4bit40の場合は」に該当しない場合を指します。つまり、この命令文は、sw1が押されている場合には実行されません。

 

【5】sw3の検出と処理

else if (P4.DR.BIT.B6 == 0){ /*sw3の入力検出      */
     P5.DR.BYTE = 0x02;      /*port5のLED2を点灯  */
}

次も、「もしそうでないなら、今度はport4bit60の場合は、port5からデータ0x02 (0000 0010)を出力しなさい。」と言っています。port4bit6にはスイッチ3(sw3)が接続されていて、sw1sw2と同様に押されたことが検出できます。ここでは、sw3が押されていたら、LED2が点灯することになります。

この命令文は、sw1sw2の時よりも、更に優先順位が低くなります。つまり、sw1sw2が押されているときには実行されません。

 

【6】sw4の検出と処理

else if (P4.DR.BIT.B7 == 0){ /*sw4の入力検出         */
     P5.DR.BYTE = 0x01;      /*port5のLEDを交互に点滅*/
     wait();
     P5.DR.BYTE = 0x02;
     wait();
     P5.DR.BYTE = 0x01;
     wait();
     P5.DR.BYTE = 0x02; 
     wait();
     P5.DR.BYTE = 0x01;

     wait();

     P5.DR.BYTE = 0x02;
     wait();
}

次も、「もしそうでないなら、port4bit70の場合は、port5からデータ0x010x02を交互に出力しなさい。」と言っています。データを切り替える際、wait();の時間稼ぎ関数を入れて、点滅の早さを調整しています。ここでは、sw4が押されたら、LED1とLED2が交互に3回点滅を繰り返します。

この命令文は、sw1sw2そしてsw3よりも優先順位が低くなります。

 

【7】sw入力がない場合の処理

   else {

        P5.DR.BYTE = 0x03;      /*port5のLED1と2を点灯*/

   }

最後に、どのスイッチも押されていない場合に、ここが処理されます。ここでは「どれにも該当しない場合は、port5から0x03 (0000 0011)を出力しなさい。」と言っています。なので、どのスイッチも押してない場合、LED1とLED2がふたつとも点灯します。

 

【8】時間稼ぎ関数

wait(){
long i;
     for (i=0;i<0x2ffff;i++){
          /*なにもしない*/
     }
return;
}

時間稼ぎ関数については、101.PIOでLEDを光らせるでもご紹介しています。ただしここでは、数を数えるための変数 i 32bitlong型で宣言し、0x2ffff (196,607)まで数えて点滅の速度を少しゆっくりに設定しています。

【先頭に戻る】


入力に設定したPIOのポートは、このようにして外部からのハードウエア入力の状態を、そのままソフトウエアに取り込むことが出来ます。今回の例ではBIT単位での取り込みをご紹介しましたが、P4.DR.BYTEとすることで、8bit分をまとめて入力することも可能になります。

 

【ソフトウエア編TOPに戻る】

 


【表紙に戻る】