1

8 ビット MCU (8051 アーキテクチャ) を使用するデバイスのファームウェアに取り組んでいます。SDCC (Small Device C Compiler) を使用しています。私の回路が駆動しているステッピングモーターの速度を設定するために使用する関数があります。速度は、タイマーのリロード レジスタに目的の値をロードすることによって設定されます。モーターへの 1 秒あたりのパルス数を表す変数 MotorSpeed が 0 から 1200 の範囲にあります。MotorSpeed を正しい 16 ビット リロード値に変換する関数を以下に示します。浮動小数点演算がかなり遅いことは知っていますが、これを行うより高速な方法があるかどうか疑問に思っています...

void SetSpeed()
{
    float t = MotorSpeed;
    unsigned int j = 0;
    t = 1/t ;
    t = t / 0.000001;
    j = MaxInt - t;
    TMR3RL = j;      // Set reload register for desired freq
    return;
}
4

3 に答える 3

2

何が起こっているのか正しく理解できたら式を計算したい

MaxInt - 1000000/MotorSpeed

ここで、MotorSpeed は 0 ~ 1200 の数値で、1 秒あたりのパルス数を表します。

コンパイラが浮動小数点演算をサポートしている場合、整数除算をサポートしている必要があります。試してみませんか。速度が > 15 の場合 問題はありませんが、速度が 0 から 15 の範囲の場合、結果は負になります。これは、カウンターが 16 ビット幅で、1MHz のレートでインクリメントされる場合、16 Hz より低い周波数のパルスを生成することは単純に不可能であることを意味します。インクリメントの頻度を減らすことができる追加のプリスケーラはありますか? (私は8051を知りません)。

于 2010-04-30T20:44:09.010 に答える
1

古典的な方法は、除算する前にスケールアップし、すべて整数として行うことにより、固定小数点を使用することです。

j = (MotorSpeed * 65536) / 1200;

これにはまだ実際の除算 (1200 による) が必要ですが、少なくともすべて整数です。シフトを使用して実装できるため、スケーリングは非常に高速です。

于 2010-04-30T13:49:48.727 に答える
0

unwind は固定点について正しいです。

私は 8051 で 32 ビット数を使用する SDCC 用の固定ライブラリを作成しました。分数に必要な精度を決定し、値に適切なシフトを適用するだけです。

たとえば、私の固定小数点ライブラリは、小数スペースに 2 バイトを使用します。

したがって、各数値 x は として表されx * 65535ます。通常の符号付き long 加算と減算を使用できます。

乗算と除算では、オフセットを調整する必要があります。単純な乗算は になります(x * 65535) * (y * 65535)。数値の各部分のオフセットを分割して因数分解し、それらをすべて加算します。

固定小数点数をバイトまたは 16 ビット整数に分割し、それらを分割して作業するだけです。

embedded.comのこの記事をご覧ください。

于 2010-04-30T20:55:13.433 に答える