firフィルタの実装について

firフィルタの積和には、基本的にデータの移動を伴います。

これを回避する方法は

1.転置型firフィルタ (C言語によるディジタル信号処理 三上著 CQ出版 p.68)

とか、その他

直接形T

直接形U

縦続形

並列形

格子形

状態変数形

最小ノルム形

出典 http://www.signal.ics.tut.ac.jp/~dspcai/mtanaka/filter-plan.html

 

2.ダブルバッファによる方法 (DSP処理のノウハウ 西村OM DesignWave CQ出版 p.94)

とか、あります。

ここで、私は、西村OMの解説して下さる、ダブルバッファを用いました。

MATH

全く同じ構造をもったバッファを2つ用意するのです。

 

一番左が、x0と言う最初のデータが入ってきた時の図です。

バッファが2箇所ですので、同じ位置にデータを置いて行きます。

バッファの大きさは、フィルタの係数の数と同じです。

以降、ポインタをデクリメントして、上位のアドレスに、データを埋めていくのです。

 

2番目の図は、一巡した時のデータ構造です。

2順目の最初のデータ(x16)は、x0の位置に、再び入ります。

 

こう言う構造にすると、firフィルタの係数を掛けやすいのです、さすが!!

黄色の網掛け部分と、フィルタ係数を掛けていくのです。

H8(SH)には、C言語を意識したインクリメント、デクリメントのニーモニックがあります。

これを使います。

 

新しいサブルーティンは、3つです。

init_buffer  ,   kakunou ,    fir_keisan

 

完成後は、ベタにする予定です。

MATH

MATH

MATH

こんな感じです。(しっかり、デバッグできては、いないです。)

 

尚、これらのサブルーティンは、別のファイルに書いて置きます。

そして、これを、部分的にデバッグします。

最後にメインルーティンと結合するために、 .exportして置きます。

それで、結合してみますと、プログラムの長さは

たったの、300バイト前後になります!

 

(条件 AD変換の割込みを使わない、ベタの方が速いから。

firの係数等は、適当に。ステップ数は変わらないですから

DSB化は、入れていないです。20ステートも変わらないと思います...)

 

MATH

H'FA27−H'900 +1=64039-63744+1=296バイト !!!

 

さて、実際に動かして見ました。

(firは、まだ設定していない。一定値=20、 firの係数の数は、今は、30個)

積和を行って、その結果を出力して見ました。

果たして、積和の結果は?

又、サンプリング周波数が、幾らになるか?

MATH

入力周波数が、高くなると、振幅は低下しています。

ですので、fir係数が一定の時、ローパスフィルタになっています。

(fir係数を20と言う、移動平均より、遥かに高い数値に設定しているのに??)

 

firの係数数を変化させて、且つ、

積の部分

mulxu.w (符号なし16ビットの積)

mulxu.b (符号なし8ビットの積)

で、サンプリング周波数が、どうなるか調べました。(オシロの観測だから、正確ではないです。)

MATH

でも、考えてみれば

出力は8ビットですし、

8ビットの積で最大は、256*256=65536(H'FFFFより、1つだけ大きい)ですから

積の部分だけは、8ビットでOKだと、思います。

和は、32ビットに採りました。

以上、途中経過です。

例によって、訂正しまくるかも知れません...

H15.10.18

This document created by Scientific Notebook 4.1. この文書は次の製品で作成しました Scientific Notebook 4.1.