[H8-ML(4006)] Re:位相計数カウンタについて
From: Shigeru Makino <mac@xxxxxxxxxxxxxx>
Date: 2003年10月09日(木)13時28分28秒
macです。

土屋 さん<hideki-tsuchiya@xxxxxxxxxx> wrote:

> 上記のrefreshTCNT32()をTCNTが最大でも32767を超えない周期で呼ぶ。
> (ex.1mSインターバル割り込み等)
> 
> 普段の参照はTCNT32値を使用すれば、
> 
> >割り込みが起こり、この処理が行われる前に、
> >もう一度、オーバーフロー/アンダーフローが、
> >起きている可能性があるのです。
> 
> の問題にも引っかかりません。
> 
> ・・・と思うんですけどどうでしょう?

カウンタの場合、その瞬時の値がほしいことが多いので、
1msごとの値では、うまくない可能性がありますね。

1msの割り込み以外に、値が必要になったら、
このルーチンと等価の関数を、
臨時に実行すれば大丈夫かもしれません。

また、コメントアウトしているので問題ないですが、
割り込みルーチンの中で、割り込み許可/不許可をすると、
予期しない多重割り込みが起こり混乱したりします。

処理系依存ですが、割り込みルーチンは、
通常のサブルーチン同様に、
呼ぶことができないのが普通ですので、

volatile signed long TCNT32; //  32bits拡張カウンタ
volatile static unsigned short TCNTold; //  前回のTCNT値を記憶。

// 処理系依存の割り込み関数用の定義文
void refreshTCNT32(void)
{
    unsigned short TCNTnew;
	signed short diff;

    TCNTnew = TCNT;
    diff = TCNTnew - TCNTold; //  前回値と今回値の差を取得
    TCNTold = TCNTnew;
    TCNT32 += diff; // カウンタ値を更新

    return;
}

// 通常の読み出しルーチン
signed long readTCNT32(void)
{
    unsigned short TCNTnew;
	signed short diff

    disable_interrupt(); // 割り込み禁止
    TCNTnew = TCNT;
    diff = TCNTnew - TCNTold; //  前回値と今回値の差を取得
    TCNTold = TCNTnew;
    TCNT32 += diff; // カウンタ値を更新
    enable_interrupt(); // 割り込み許可

    return TCNT32;
}

というのが、この別解のまとめでしょうか。

他の方法としては、
GRA = 0x4000;
GRB = -0x4000;
のようにそれぞれ上限下限に設定し、
コンペアマッチが、交互に起これば一定方向に回り続けている。
片方だけが、連続して発生すれば、正転逆回転を繰り返している。
という判断を元に、オーバーフロー割り込みを使わず、
コンペアマッチを利用した方法も可能でしょう。

処理は多少複雑ですが、タイマーを使う方法に比べ、
Checkする周期を短くするとオーバーヘッドが増える。
周期を長くすると0x4000以上の変動を取りこぼす危険が出る。
という、問題を回避できる利点があります。

たまたま思いついた解法が、The Bestと思い込まずに、
時間が許すなら、考え付くもの全部をさらってやる、
という気構えでいくと、そのときには、使わなくても、
後で使えるネタが増え、効率的にスキルアップすると思います。

-- mac

スレッド概略
[3936(R)](起点)
 └[4004(U)]
   └[表示中]


投稿順に移動
[←前の記事へ(P)]
[→次の記事へ(N)]


リスト表示へ
[このスレッド(T)]
[本記事の前後(L)]