4. プログラムの動作

戻る (本を出しました: はじめてのPICアセンブラ入門| センサとデジカメで遊ぶ電子工作入門)

Copyright(c) 2007 光永 法明

 

 プログラムの流れは、以下の擬似プログラムとmain関数の解説で示すようになっています。

 

3-1 プログラム動作説明の擬似プログラム

// I/O の初期化

 for(;;) // Forever

  {   約50Hz (20ms) に1ループ実行される

// A/D 変換する

   vr = (ADP1 の値)   // A/D 変換

   cds = (ADP3 の値)   // A/D 変換

// 変化のチェック (蛍光灯のフリッカを消すように 10Hz でサンプリングする

つまり、ループ5回に1回のみ実行する)

    cds の値が一定時間内に VR1 以上、変化したら、サーボを動かすフラグを立てる

    一定時間が経過したら、CdS の値の変化を記録する変数をリセット

// サーボを動かす

   サーボを動かすフラグがたっていれば、PTA2 を H レベルにし、   

1        左いっぱい

2        右いっぱい

3        左いっぱい

4        右いっぱい

   に相当する長さ(0.7-2.1[ms])だけ待ち、 PTA2 を L レベルにする。

   フラグがたっていなければ、 PTA2 は L を保つ(R/Cサーボはフリー状態)。

 

// LED の点滅

    サーボ動作中なら、LED を点灯する (PTA0 = H)

    非動作中なら、 VR1 に比例して点滅させる

 

// 20ms 待ち (R/C サーボのために必要。またループの周期を決める)

   }

 


main 関数の解説

 

void

main(void)

{  // 変数の宣言

  unsigned char vr, cds, ocds = 0, j = 0, k = 0;

  unsigned char changecount = 0;

  unsigned char mov = 0, movcount = 0;

  short change = 0;

 

  // マイコンの初期化

  EnableInterrupts;

  PeriphInit();

 

  for(;;) // Forever                    // メインループ(無限ループになっている)

    {                                // 1ループは約20ms (50Hz)

      unsigned char pos = 128;          // 変数の初期化

      

// A/D 変換

      ADCSC1 = 0x1;              // ADC conversion start        (開始)

      while ((ADCSC1 & 0x80) == 0)     // Wait for conversion to complete (終了待ち)

                ;

      vr = ADCRL;                    // 結果の代入  

 

      k ++;

      if ((k % 5) == 0) {                  // 5回に1回だけ(10Hz) CdSの値を読む

               // Check CdS every 5 loops to avoid fluolucent fricker

               // (make the sampling rate 10Hz)

               k = 0;

 

// A/D 変換

               ADCSC1 = 0x3;            // ADC conversion start        (開始)

               while ((ADCSC1 & 0x80) == 0) // Wait for conversion to complete (終了待ち)

                 ;

               cds = ADCRL;             // 結果の代入  

 

               if (ocds == 0)

                 ocds = cds;

 

     // 変化を累積していく

               if (ocds > cds)

                 change = change + (ocds - cds);

               else

                 change = change + (cds - ocds);

               ocds = cds;

               changecount ++;

 

               if (mov == 0 && change > vr) {  // 変化が vr 以上になったらフラグを立てる

                 movcount = 0;

                 mov = 1;

               }

   

               if (changecount > 20) { // reset count when 2s elaps

                 change = 0;

                 changecount = 0;

               }

    }

   

    if (mov>0) {

               // Move the R/C servo when flag is on

 

               // Change position as time pases   // R/C サーボの角度を決める

// 時間と共に変える

               movcount ++;

               if (movcount<10) {       ; < 0.2s

                 pos = 150;

               } else if (movcount<20) {  ; < 0.4s

                 pos = 100;

               } else if (movcount<30) {  ; < 0.6s

                 pos = 150;

               } else if (movcount<40) {  ; < 0.8s

                 pos = 100;

               } else if (movcount<60) {  ; < 1.2s

                 // Keep the same position

               } else {

                 // reset the flag

                 mov = 0;

                 change = 0;

               }

 

               // Make a pluse (0.7ms - 2.1ms)        // パルスを作る

               PTAD |= 0x4;       // set H         ポートを1にして

     

               Delay_100us(7);    // 0.7ms delay    しばらく待ち

               Delay_servo(pos);  // 0-1.4ms delay (0x5.5us - 255x5.5us)

 

               PTAD &= 0xfb;      // set L        ポートを0にする

    }

 

    // set LED

    if (mov) {

               // Make LED on when servo is moving

               PTAD |= 0x01;       // サーボを動かしているときは LED ON

    } else {

               // Otherwise flash LED

               j ++;

               vr = vr/8;    //          vr/8*20ms が経過するたびに

               if (j > vr) {

                 // Once for vr/8*20ms

                 // Toggles LED

                 PTAD ^= 0x01;            // LED のビットを反転する

                 j = 0;

               }

    }

    Delay_100us(200); // 20ms delay       // サーボに必要な 20ms のパルスの L 期間

  }

}

 

戻る (本を出しました: はじめてのPICアセンブラ入門| センサとデジカメで遊ぶ電子工作入門)

Copyright(c) 2007 光永 法明 non <at mark > ever.sanda.gr.jp