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