プログラムは、ここですが、
理由が解らないまま、全く、動作いたしませんでした...(T_T)
int macw(short *ptr1, short *ptr2,unsigned int count)は、
<machine.h>で、既に定義されている組み込み関数です。
[積和演算組み込み関数は、二つのデータテーブルの内容の積和を求める。
例
short tbl1[ ] = {a1,a2,a3,a4};
short tbl2[ ] = {b1,b2,b3,b4};
この時
macw(tbl1, tbl2, 3)
は
a1*b1 + a2*b2 + a3*b3
を求める。]
(ルネサス社 SuperH RISC engine C/C++コンパイラユーザーズマニュアルから、抜粋。)
あっさり、動作いたしました...訳解らん???
プログラムは、ここです。
HEW3で作ったものと、殆ど変わりません。
組み込み関数の
int macw(short *ptr1, short *ptr2,unsigned int count)
は、GCCには、ありませんので、
同様の動作をするものをつくりました。
int macw( short *a,short *b )
{
int c;
asm("mov.l %0,r2\n"
"mov.l %1,r3"::"m" (a),"m" (b) );
asm(".rept 81\n" //ここのNだけは、手動で変える事
"mac.w @r2+,@r3+\n"
".endr");
asm("sts MACL,r4\n" //積和MACの下位だけr4に移す。MACHに溢れたら、どうするんや?
"mov.l r4,%0":"=m" (c)); (飽和に関しては、もっと、よく調べてみなくては...)
return c; //int Cを返す
}
ルネサス社のsh用コンパイラの、繰り返し展開擬似命令 .AREPEAT .AENDR は
GCCのアセンブラasでは、.rept .endr に相当します。
[ Assembler Directives
7.63 .rept count
Repeat the sequence of lines between the .rept directive and the next .endr directive count times.
For example, assembling
.rept 3
.long 0
.endr
is equivalent to assembling
.long 0
.long 0
.long 0
] (Tools/KPIT% 20Cummins/GNUSH-ELF/v0304/Doc/as.htmから抜粋。)
何はともあれ、firフィルターの形状を、確認できました。
60dBの差は、どうでしょうか?
あるような、ないような気が...
サンプリング周波数は、81タップで37.28KHzでした。
しかし、AD変換器の前段の、増幅器が NJM4580Dと言うオーディオ用のオペアンプを使ってますので
周波数特性が、以下の様になります。
おかしいなあ、もうちょっと、いけるはずやねんけど...
このため、firの特性が、垂れ下がってしましました。(DA変換器の0次ホールドのせいも、あるけど...)
これは、オペアンプを換えてみないと、いけませんわ。
これの理由なんですが、
どうやら、オペアンプに与える電源電圧が低いと
周波数特性が落ちるようです。
[NJM4580] [TL062]
4580の場合のデータは、V+/V-=+-15V
ですので、解決策は、
4580の電源電圧を上げてやるか、TL062の場合は、低電源電圧で、まだ、特性がよさそうなので
TL062に換えてみるのも一手ですね。(やってみようっと)
まだ、解決策は、あります。
4580Dの電源電圧は、そのままで、
何と、贅沢にも、サンプリング周波数を下げてやることです。(そしたら、オペアンプの周波数特性が平坦な所が使える)
これは、遅延ループを作ってやれば、よいですね....超贅沢!!!
まだ、ありました!
オペアンプにくっ付けていた、位相補償のコンデンサ、102を、取っ払う事です。
結果は、以下の特性になります。
420KHz位まで、平坦や... 素晴らしい...何と、なあ...うーむ.唖然。..
これには、落ちが、ありまして...
実は、発振しておりました...なはは
結局、位相補償の値を調整することが大切ですね。
ああ、大恥を斯きましたわ...汗
遂に、60dBの差を確認できました。
81タップ fir Q14
オペアンプは、そのままなのですが、(画像で、上の折れ線は、オペアンプの振幅対周波数特性です。)
設計したフィルタは、オペアンプの直線の範囲に入っていますので、
firフィルタの右肩下がりは、DA変換器の0次ホールド効果の為と、思われます。
これは、DA変換器の出力を、Cで切って、DCを遮断していますが、
このCが、10μFのみだったので、そのCの特性が出てしまいました.
10μFと並列に104を入れて、解決。
いつも、こんなチョンボばっかりで、スミマセン.....
如何にして、60dBの差を作れたかと、言いますと
最初に測定した時は、firをQ10に採っていたのですが、今回はQ14に採りました。
この方が、有効数字が、多く取れますので、上記の結果を得る事ができました、やれやれ...(^_^;;
とりあえず、希望の結果を得る事ができました。
毎度お騒がせして、申し訳ありません、m(__)m
よい、お年を!
それから、firフィルタの元の設計は
です。
それから、GCCのプログラムの中で、
やはり、ダブルバッファを使っていますが
この2つのバッファは、2分割して
short data_up[N]={0};
short data_low[N]={0};
と、しましたが、
GCCのエミュレーションで確認した所
続けて、配列を宣言すれば
2つの配列は、繋がっている事を確認いたしました。
まだ、すっきりしないのですが、
何はともあれ、firフィルタの形状を確認いたしました。
本年の実験は、これにて、お終いにいたします。
来年も、どうか、よろしく、お願い申し上げます。
H.15.12.26
This document created by Scientific Notebook 4.1. この文書は次の製品で作成しました Scientific Notebook 4.1.