時間待ち

別スレッドで時間待ちについて盛り上がったので、私はこうしてます。のサンプルソースです。

コンペアマッチタイマを常時動作中を前提にしています。(1ms周期。CMT1.CMCOR=6249の場合)

CPU違い、設定違いは適度に調整してね。 関数が超短いっす。

-----------------------------------------------------------------------------------

typedef unsigned short int  ushort;

typedef unsigned int        uint;

typedef unsigned long int   ulong;

volatile static  ushort  Tm1;    // TMカウンタ(1ms ushort型)

volatile static  ulong      Tm1L;   // TMカウンタ(1ms ulong型)

コンペアマッチタイマを常時動作(例:1ms周期。CMT1.CMCOR=6249の場合)

//*******************************************************************************

// インターバル(1.0ms)割込み

void   Int_CMT1(void)               // 144 CMT CMI1

{

    Tm1++;                          // TMカウンタを無限に更新(ushort型)

//  Tm1L++;                         // TMカウンタを無限に更新(ulong型)

}

// ↑例では、割込みフラグのクリアを省略

 

//*******************************************************************************

// タイマ監視開始

void    Tm1_Start(ushort *ptm1)

{

    *ptm1 = Tm1;                    // タイマ開始時のTm1値

}

// タイマ経過時間演算

ushort Tm1_Check(ushort tm1)

{

    return((ushort)(Tm1 - tm1));    // 経過時間演算(1ms分解能)

}

//*******************************************************************************

// CMCNT利用:タイマ開始    分解能:160ns=0.16us=1ms/(CMT1.CMCOR+1)=1000us/6250

void    TmC_St(ushort *ptmC)

{

    *ptmC = CMT1.CMCNT;             // タイマ開始時の CMT1.CMCNT値

}

// CMCNT利用:タイマ経過時間演算

ushort TmC_Ck(ushort tmC)

{

    ushort  tmCnt = CMT1.CMCNT;

    if(tmCnt < tmC)

        tmCnt += 6250;              // 6250=CMT1.CMCOR +1

    return((ushort)(tmCnt - tmC));  // 経過時間演算(160ns分解能)

}

-----------------------------------------------------------------------------------

<使い方>

#define TIM_1S      1000            // 1000ms(1sec)

#define TIMC_10US   (1000/16)       // 10us (10us/0.16us)

#define TIMC_160NS  (16/16)         // 0.16us (160ns/0.16us)

static  ushort      tm1;            //

static  ushort      tm1C;           //

例1:1ms ~ max約65secの監視。(実用上 max30sec程度がベター)

 <監視開始時>

    Tm1_Start(&tm1);                // 1秒監視開始

 <経過時間判定時>

    if(TIM_1S < Tm1_Check(tm1))     // 1秒経過?

        return;                     // yes

   // 未経過の処理。他タスク等実施可

    // 再度、経過時間判定へ

例2:0.16us ~ max1ms未満の監視。(実用上 max500us程度がベター)

 <監視開始時>

    TmC_St(&tm1C);                  // 10us監視開始

 <経過時間判定時>

    if(TIMC_10US < TmC_Ck(tm1C))    // 10us経過?

        return;                     // yes   少々誤差有り

   // 未経過の処理。他タスク等実施可

    // 再度、経過時間判定へ

<わがまま>:もっと長い時間を監視したい

 ・ushort → ulong   max49日余りの監視が可 (1ms周期タイマ時)

 ・1ms周期タイマ → 10ms周期タイマ  

Parents
  • あれ~! 改行が消えてるぅ....

  • 読める気がしません

  • ご迷惑おかけしました。改行の消えは修正しました。

    max±分解能の誤差は、許容範囲と割り切りる必要があるかも。

    ご意見聞かせてください。

  • LEON さん

    私も前には1mS割り込みやってた時があります、1mS割り込みやるとどうしてもCPU時間が気になっています1/10は消費しないとは思うが、1/100ぐらいにはなりはしないかと、気兼ねします、計算するとごくわずかとは思われますが、私の場合10mSであれば許せるが、「1mSはちょっと」、と思います、割り込みは全ての動作に影響しますので、ご注意を、その結果割り込みではなくフリーランのカウンタ値を任意に確認する方法で行えばCPU時間の消費は0ですので動作に影響を与えません。

  • IKUZOさん

    ありがとうございます。たしかに、使用するCPU、システムの用途によっては、1ms周期割込みの処理が重荷に感じるものもあるでしょうね。

    で、割込み軽減策としてカウンタの無限インクリメント(0~0xFFFF,0~ 繰り返し)のみとし、変数の管理、計算、判定等は、割込みの外でやらせています。

    IKUZOさんと同様、要求機能、特性とのバランスを考慮して、周期時間(~数十ms)を設定しています。たまたま早い周期タイマを使用することが多く、それを利用しているだけです。

    割込み処理は最小限に。フリーランカウンタの利用。は、まさにその通りで同意です。

    昔、割込み内処理に依存傾向のお客様に対し、割込み処理最小限による動作比較の検証結果を提示し、苦労してようやく納得してもらえたっけ。

Reply
  • IKUZOさん

    ありがとうございます。たしかに、使用するCPU、システムの用途によっては、1ms周期割込みの処理が重荷に感じるものもあるでしょうね。

    で、割込み軽減策としてカウンタの無限インクリメント(0~0xFFFF,0~ 繰り返し)のみとし、変数の管理、計算、判定等は、割込みの外でやらせています。

    IKUZOさんと同様、要求機能、特性とのバランスを考慮して、周期時間(~数十ms)を設定しています。たまたま早い周期タイマを使用することが多く、それを利用しているだけです。

    割込み処理は最小限に。フリーランカウンタの利用。は、まさにその通りで同意です。

    昔、割込み内処理に依存傾向のお客様に対し、割込み処理最小限による動作比較の検証結果を提示し、苦労してようやく納得してもらえたっけ。

Children
No Data