9

PICアセンブリ言語を使用して、8ビットPICマイクロコントローラー(具体的には16F627Aですが、それは問題ではありません)の2つの値の間で時間の経過とともに線形補間を行う必要があります。私はここで実際のコードと同じくらいのアルゴリズムを探していますが。

8ビットの開始値、8ビットの終了値、および2つの間の位置を取得する必要があります(現在、8ビットの数値0〜255として表されます。ここで、0は出力が開始値であり、255は最終値であることを意味します。値ですが、これを表すより良い方法がある場合は変更される可能性があります)、補間された値を計算します。

現在、PICには除算命令がないため、汎用の除算ルーチンをコーディングして、各ステップで(BA)/(x / 255)+ Aを効果的に計算できますが、これを行うにはおそらくはるかに優れた方法があると思います。 c++のPCで行う方法よりもマイクロコントローラー

このハードウェアにこれを効率的に実装するための提案はありますか?

4

6 に答える 6

7

探している値はです(A*(255-x)+B*x)/255。必要なのは8x8の乗算と、255による最終除算だけです。これは、合計の上位バイトを取得するだけで概算できます。

範囲0..128でxを選択すると、近似は必要ありません。の上位バイトを取得します(A*(128-x)+B*x)<<1

于 2010-04-18T08:45:10.553 に答える
2

前のエンドポイントが新しい開始点である一連の値を補間すると仮定します。

(B-A)/(x/255)+A

悪い考えのように聞こえます。不動点表現として基数255を使用する場合、同じ内挿を2回取得します。x = 255の場合はBを取得し、x=0の場合は新しいAとしてBを取得します。

固定小数点システムとして256を使用します。除算はシフトになりますが、16ビットの算術演算と8x8の乗算と16ビットの結果が必要です。前の問題は、上位バイトのビットを0になるように無視するだけで修正できます。x mod 256この提案では、16ビットの乗算を使用しますが、オーバーフローすることはできません。同じxを2回補間することはありません。

interp = (a*(256 - x) + b*x) >> 8

256 - xを取得すると、借用による減算になります0 - x

PICには、命令セットに次の操作がありません。

  • 左右シフト。(論理と算術の両方)
  • あらゆる形式の乗算。

代わりにrotate-rightを使用して右シフトし、続いて左側の余分なビットをビット単位でマスクすることができます-and。16ビットの結果で8x8の乗算を行う簡単な方法:

void mul16(
    unsigned char* hi, /* in: operand1, out: the most significant byte */
    unsigned char* lo  /* in: operand2, out: the least significant byte */
)
{
    unsigned char a,b;

    /* loop over the smallest value */
    a = (*hi <= *lo) ? *hi : *lo;
    b = (*hi <= *lo) ? *lo : *hi;
    *hi = *lo = 0;
    while(a){
        *lo+=b;
        if(*lo < b) /* unsigned overflow. Use the carry flag instead.*/
            *hi++;
        --a;
    }
}
于 2010-04-18T11:03:05.917 に答える
2

EricBainvilleとMadsElvheimによって説明された手法は問題なく機能します。それぞれが補間ごとに2つの乗算を使用します。

ScottDattaloとTonyKubekは、「ツイスト」と呼ばれる超最適化されたPIC固有の補間手法をまとめました。これは、補間ごとに2回乗算するよりもわずかに高速です。

この理解しにくいテクニックを使用することは、もう少し速く実行する価値がありますか?

于 2010-05-22T23:37:25.257 に答える
1

8.8固定小数点演算を使用してそれを行うことができます。次に、範囲0..255の数値は、0.0 ... 0.996と解釈され、乗算して正規化することができます。

詳細が必要な場合、または開始するのに十分かどうかを教えてください。

于 2010-04-18T08:36:02.253 に答える
1

代わりに、これを次のように特徴付けることができます。

(B-A)*(256/(x+1))+A

x = 0..255の値の範囲を使用して、256 /(x + 1)の値をテーブルの固定小数点数として事前計算してから、汎用の乗算をコーディングし、バイナリポイントの位置を調整します。これはスペース的には小さくないかもしれません。16ビット値の256エントリテーブルと乗算コードが必要になると思います。(速度が必要ない場合は、除算方法が適切であることを示しています。)ただし、1回の乗算と1回の加算のみが必要です。

私の推測では、Xのすべての可能な値が必要なわけではありません。Xの値が少ない場合は、オフラインで計算し、Xの特定の値で大文字と小文字を選択してから、次の式で乗算を実装できます。 Xの特定の値に対するシフトと加算の固定シーケンス。これは、コードではかなり効率的であり、PICでは非常に高速である可能性があります。

于 2010-04-18T08:37:44.970 に答える
1

補間

XYの2つの値が与えられると、基本的に次のようになります。

(X + Y)/ 2

また

X / 2 + Y / 2(A + Bがレジスタのサイズをオーバーフローする可能性があるという奇妙なケースを防ぐため)

したがって、次のことを試してください。

(擬似コード)

Initially A=MAX, B=MIN

Loop {

    Right-Shift A by 1-bit.

    Right-Shift B by 1-bit.

    C = ADD the two results.

    Check MSB of 8-bit interpolation value

    if MSB=0, then B=C

    if MSB=1, then A=C

    Left-Shift 8-bit interpolation value

}Repeat until 8-bit interpolation value becomes zero.

実際のコードも同様に簡単です。私だけがレジスターと命令を手元に覚えていません。

于 2010-04-18T08:52:19.927 に答える