別スレッドで時間待ちについて盛り上がったので、私はこうしてます。のサンプルソースです。
コンペアマッチタイマを常時動作中を前提にしています。(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周期タイマ
あれ~! 改行が消えてるぅ....
読める気がしません
ご迷惑おかけしました。改行の消えは修正しました。
max±分解能の誤差は、許容範囲と割り切りる必要があるかも。
ご意見聞かせてください。
LEON さん
私も前には1mS割り込みやってた時があります、1mS割り込みやるとどうしてもCPU時間が気になっています1/10は消費しないとは思うが、1/100ぐらいにはなりはしないかと、気兼ねします、計算するとごくわずかとは思われますが、私の場合10mSであれば許せるが、「1mSはちょっと」、と思います、割り込みは全ての動作に影響しますので、ご注意を、その結果割り込みではなくフリーランのカウンタ値を任意に確認する方法で行えばCPU時間の消費は0ですので動作に影響を与えません。
IKUZOさん
ありがとうございます。たしかに、使用するCPU、システムの用途によっては、1ms周期割込みの処理が重荷に感じるものもあるでしょうね。
で、割込み軽減策としてカウンタの無限インクリメント(0~0xFFFF,0~ 繰り返し)のみとし、変数の管理、計算、判定等は、割込みの外でやらせています。
IKUZOさんと同様、要求機能、特性とのバランスを考慮して、周期時間(~数十ms)を設定しています。たまたま早い周期タイマを使用することが多く、それを利用しているだけです。
割込み処理は最小限に。フリーランカウンタの利用。は、まさにその通りで同意です。
昔、割込み内処理に依存傾向のお客様に対し、割込み処理最小限による動作比較の検証結果を提示し、苦労してようやく納得してもらえたっけ。