2016年3月17日木曜日

リミット有りのエンコーダ入力

前回のエントリでは、エンコーダの位置を絶対位置で取り出しました。しかし、この方法では音量調整に使おうとすると、音量を下げて0を通過すると最大に戻るという問題点があります。ということで一定範囲に数値を収める方法について。

まずエンコーダの初期化(RCC,GPIO,TIM)は基本的に前回と同じです。ただし、TIM_SetAutoreloadの引数には0xFFFFを渡します。そうすることによりTIMの出力は0-65535の範囲を取ります。
次にカウント値を取り出すわけですが、TIMx->CNTはint_16でキャストして取り出します。そうすると正回転の時に正の値、逆回転の時に負の値を取り出すことができます。後はこの符号ありの数値を積算していけば、電源ONの時点からの絶対位置を取り出すことができます。
しかしそのままではせいぜい32bitや64bitの範囲でしか動作しません。なので積算後に範囲外に出た場合は範囲内に戻るようにします。
また、CNT値は取り出した後にちゃんと0に初期化してやります。そうすれば次回に取り出すときは、今回から次回の間に変更されたパルス数を読むことができます。

static int Value = 0;

if (TIM3->CNT) {
    Value += (int16_t)TIM3->CNT;
    TIM3->CNT = 0;

    if (Value > +100) { Value = +100; }
    if (Value < -100) { Value = -100; }

    printf("value:%4d\n", Value);
}

実際にはこのような処理になると思います。適当なタイマ割り込みやスレッドでこのような処理を行えば、上の例では+100から-100の間の数値として読み込むことができます。
他の使用方法として、タイマ割り込みなど正確な周期でTIMx->CNTの読み込みとリセットを行えば、周期とカウント値で速度を計測することも可能です。

0 件のコメント:

コメントを投稿