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の解説して下さる、ダブルバッファを用いました。
全く同じ構造をもったバッファを2つ用意するのです。
一番左が、x0と言う最初のデータが入ってきた時の図です。
バッファが2箇所ですので、同じ位置にデータを置いて行きます。
バッファの大きさは、フィルタの係数の数と同じです。
以降、ポインタをデクリメントして、上位のアドレスに、データを埋めていくのです。
2番目の図は、一巡した時のデータ構造です。
2順目の最初のデータ(x16)は、x0の位置に、再び入ります。
こう言う構造にすると、firフィルタの係数を掛けやすいのです、さすが!!
黄色の網掛け部分と、フィルタ係数を掛けていくのです。
H8(SH)には、C言語を意識したインクリメント、デクリメントのニーモニックがあります。
これを使います。
新しいサブルーティンは、3つです。
init_buffer , kakunou , fir_keisan
完成後は、ベタにする予定です。
こんな感じです。(しっかり、デバッグできては、いないです。)
尚、これらのサブルーティンは、別のファイルに書いて置きます。
そして、これを、部分的にデバッグします。
最後にメインルーティンと結合するために、 .exportして置きます。
それで、結合してみますと、プログラムの長さは
たったの、300バイト前後になります!
(条件 AD変換の割込みを使わない、ベタの方が速いから。
firの係数等は、適当に。ステップ数は変わらないですから
DSB化は、入れていないです。20ステートも変わらないと思います...)
H'FA27−H'900 +1=64039-63744+1=296バイト !!!
さて、実際に動かして見ました。
(firは、まだ設定していない。一定値=20、 firの係数の数は、今は、30個)
積和を行って、その結果を出力して見ました。
果たして、積和の結果は?
又、サンプリング周波数が、幾らになるか?
入力周波数が、高くなると、振幅は低下しています。
ですので、fir係数が一定の時、ローパスフィルタになっています。
(fir係数を20と言う、移動平均より、遥かに高い数値に設定しているのに??)
firの係数数を変化させて、且つ、
積の部分
mulxu.w (符号なし16ビットの積)
mulxu.b (符号なし8ビットの積)
で、サンプリング周波数が、どうなるか調べました。(オシロの観測だから、正確ではないです。)
でも、考えてみれば
出力は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.