【使用 TIMER 副程式】
    1. 延遲一段時間的方法
    2. 固定一段時間處理事情的方法
    3. 測量處理一件事情所花的時間的方法

    範例程式中 DEMO90-99 都是跟 timer 副程式的使用有關的。請自行參考。

    回主目錄

    延遲一段時間的方法

    1. 如果要延遲一段很短的時間,大概就是用一行組合語言來寫
      _asm nop
      了,他延遲的時間也幾乎是在程式中所能延遲的最短時間了。
    2. Turbo C 有提供一個副程式 delay(),延遲的時間單位是 ms,但是很可惜的在 I-7188 上無法使用,因為他會去讀 PC 上的 8254 來計時。
      有一個方法也可以用來 dleay 大約 1 ms 的時間。
      for(i=0;i<cnt1;i++) {
        for(j=0;j<cnt2;j++) {
          for(k=0;k<cnt3;k++) ;
        }
      }
      但是cnt1, cnt2, cnt3 需要想辦法找出來。所以不容易找到準確值,且會因編譯程式不同而有不同的結果。
      但是如果只是要延遲一段時間,但不需精確的時間,倒也是一個容易用的方法。
    3. I-7188 提供一個單位為 ms 的時間延遲程式 Delay()(第一個 D 是大寫), 另一個單位為 0.1ms 的時間延遲程式 Delay_1()。兩個都是利用系統的 timer 來計時,所以精確度沒問題。
      如果要delay 0.5 秒就呼叫 Delay(500); 即可。
    4. 另一種方法就是用 C 提供的副程式 clock(),他是讀取系統的 time ticks 來計時的。這個值存放在記憶體位置 0040:006C ,也可以直接去存取該值來計時。這個 time tick 的時間單位大約是 55 ms 。
    5. 再來就是使用 I-7188 程式庫提供的 Timer 副程式了。
      使用前要先呼叫 TimerOpen(); 程式結束前再呼叫 TimerClose() 就可以。
      Timer 副程式提供了 1 ms 精度的計時。有 8 個計時碼錶及 8 個倒數計時的計時器可以使用。
      使用計時碼錶來 DELAY 5 秒鐘的方法如下:
       StopWatchStart(0); // 使用第 0 個計時馬錶
       do {
         StopWatchReadValue(0,&value);
       } while(value < 5000);
      
      使用倒數計時器 DELAY 5 秒鐘的方法如下:
       CountDownTimerStart(0,5000); // 使用第 0 個倒數計時器,倒數計時 5000 ms。
       do {
         CountDownTimerReadValue(0,&value);
       } while(value != 0);
      
    回本頁目錄

    固定一段時間處理事情的方法
    底下的例子將主要用 LED 的 on/off 為範例。分別用 Timer,stopwath 及 countdowntimer 來寫程式。 方法有很多種,就看使用者喜歡(習慣)用哪一種。

    1. 讓 LED 每隔一秒閃一次(亮 0.5 秒,暗 0.5 秒)。
      1. 使用 delay 副程式。
      2. quit=0;
        while(!quit){
          Delay(500);     // 等待 0.5 秒,無法做其他事。
          LedToggle();    // 切換 led 的狀態。
          ... // 這個時候當然可以做其他事,但是對 0.5 秒的計時是直接的影響。
        }
        
      3. 使用 timer 。
      4. quit=0;
        start=TimerReadValue();
        while(!quit){
          if(TimerReadValue()-start >=500) {
             start=TimerReadValue();  // 0.5 秒到了,重新記下開始時間。
             LedToggle();             // 切換 led 的狀態。
          }
          ... // 這個時候還可以做其他事,只要不花太多時間的話,對 0.5 秒的計時影響不大。
        }
        
      5. 使用 stopwatch 。
      6. quit=0;
        StopWatchStart(0);  // use channel 0
        while(!quit){
          StopWatchReadValue(0,&time);
          if(time >=500) {       // 數到 500 就是 0.5 秒到了。
             StopWatchStart(0);  // 0.5 秒到了就重新計時。
             LedToggle();        // 切換 led 的狀態。
          }
          ... // 這個時候還可以做其他事,只要不花太多時間的話,對 0.5 秒的計時影響不大。
        }
        
      7. 使用 countdowntimer 。
      8. quit=0;
        CountDownTimerStart(0,500);  // use channel 0
        while(!quit){
          CountDownTimerReadValue(0,&time);
          if(time ==0) {                  // 倒數到 0 就是 0.5 秒到了。 
             CountDownTimerStart(0,500);  // 0.5 秒到了就重新倒數計時。
             LedToggle();                 // 切換 led 的狀態。
          }
          ... // 這個時候還可以做其他事,只要不花太多時間的話,對 0.5 秒的計時影響不大。
        }
        
      9. 寫 user 自己的timer 副程式。使用 InstallUserTimer(); 來安裝自己的計時副程式。
      10. void MyTimerFun(void)
        { static unsigned count=0;
          count++;
          if(count>=500){
             count=0;
             LedToggle();
          }
        }
        
        main()
        {
          quit=0;
          TimerOpen();
          InstallUserTimer(MyTimerFun); // 安裝自己的計時副程式 "MyTimerFun"
          while(!quit){
            ... // 這個時候可以做其他事,只要不把timer 中斷關掉的話就對 0.5 秒的計時沒有影響。
          }
          TimerClose();
        }
        
        這個方法應該是計時最準的,但是要注意一點:所做的工作不可花太多時間。 因為每隔 1 ms 就會被呼叫一次,如果花太多時間,超過 1 ms 將會影響下一次的 timer 中斷的進入。 所以比較適合做一些簡單的事情。
    2. 在使用 User Timer Functions 有一個一定要注意的事:不要同時在這個副程式裡頭 呼叫有關 5DigitLed 或 eeprom 的副程式,又在主程式裡頭使用。 例如主程式呼叫 Show5DigitLed(), 當執行到一半時 timer 中斷進來,user 的 timer副程式又再呼叫 Show5DigitLed() 一次,這樣顯示就一定出問題。 要就通通放在主程式中顯示,不然就通通在user 的 timer 副程式中處理。
    回本頁目錄

    測量處理一件事情所花的時間的方法
    在這裡 countdowntimer 就比較不適合,其他方法應該都可以使用,不過還是 stopwath 最適合。

    1. 一些簡單的計時方法。
      1. 使用 timer 。
      2. quit=0;
        start=TimerReadValue();
        ... // 設定要記時的工作開始
        while(!quit){
          if(work_is_ok()) {  // 判斷工作是否完成
             TIME=TimerReadValue()-start;  // 算出所花的時間 TIME
          }
          ... // 這個時候還可以做其他事,只要不花太多時間的話,對計時影響不大。
        }
        
      3. 使用 stopwatch 。
      4. quit=0;
        StopWatchStart(0);  // use channel 0
        ... // 設定要記時的工作開始
        while(!quit){
          if(work_is_ok()) {  // 判斷工作是否完成
             StopWatchReadValue(0,&TIME);  // 讀回所花的時間 TIME
          }
          ... // 這個時候還可以做其他事,只要不花太多時間的話,對計時影響不大。
        }
        
    2. 另一個方法就是寫 user 自己的timer 副程式。使用 InstallUserTimer(); 來安裝自己的計時副程式, 每隔 1ms 就會被呼叫一次,也就是每被呼叫一次就是 1 ms 過去了。藉由計數及判斷工作是否完成就可以測量時間了。
    回本頁目錄

    回主目錄
    I-7188入門課程 1.10版 〔by:蔡坤廷〕 〔本檔最後修改日期:02/20/2001〕