マイクロチップ社が提供しているディジタルフィルタ設計ツールである「Digital
Filter Design Tool」
で作成したフィルタパラメータを使って、C30コンパイラのDSPライブラリ関数でフィルタプログラム
を作成する方法を説明しています。
【dsPIC Language Tools Libraries】
マイクロチップ社のC30コンパイラには、無償提供のライブラリ群があります。
「dsPIC Language Tools Libraries」と呼ばれているもので、そのライブラリの中には
下記のような関数群が含まれています。
関数種類 機能内容 ライブラリ名 スタートアップコード 初期化のコードで2種類ある
crt0:変数を初期化する
crt1:変数の初期化しないcrt0.o
crt1.oDSPライブラリ DSP処理に関する関数群
49個の関数を含み、高速化のため
大部分アセンブラで記述されているdsp.h
libdsp.a周辺モジュール
ライブラリ内蔵周辺モジュール用の組み込み関数で
下記を含みます
CAN、ADC12、ADC10、Timer、Reset、
I/O pin、Input Capture、Output Compare
UART、DCI、SPI、QEI、PWM、I2Cデバイスごとに用意
libp30F6014.a
libp30F3013A2.a
libp30F4013.a
−−−−−−
(A、A2はSiliconのバージョン)標準Cライブラリ
算術関数ライブラリANSI-89に準拠した関数群と算術関数群
デバイス専用の支援関数群libc.a と libm.a
libpic30.a
【DSPライブラリ】
DSP処理に関する関数を集めたライブラリで、大別すると下表のように5種類の
関数に分けられます。これらを使ってフィルタのプログラムを作ります。
関数種別 関数名 機能 ベクタ演算 VectorAdd 2つのベクタの要素ごとの加算
dstV[n] = srcV1[n] + srcV2[n]VectorConvolve 2つのベクタの畳み込み演算
y[n] = Σx(k)h(n-k)VectorCopy ベクタのコピー
dstV[n] = srcV[n]VectorCorrelate 2つのベクタの相関演算
r[n] = Σx[k]y[k+n]VectorDotProduct 2つのベクタの積和演算
VectorMax ベクタの最大値の要素の
インデックスを求めるVectorMin ベクタの最小値の要素の
インデックスを求めるVectorMultiply 2つのベクタの積を求める VectorNegate ベクタの符号を反転する VectorPower ベクタの平方根演算 VectorScale ベクタを定数倍する VectorSubtract 2つのベクタの減算
dstV[n] = srcV1[n] − srcV2[n]VectorZeroPad ベクタのコピー、不足要素には0を代入 窓関数 BartlettInit 指定要素数のBartilett窓関数を生成する BlackmanInit 指定用素数のBlackman窓関数を生成する HammingInit 指定用素数のHamming窓関数を生成する HanningInit 指定要素数のHanning窓関数を生成する KaiserInit 指定要素数のKaiser窓関数を生成する VectorWindow 指定した窓関数行列を適用する マトリクス演算 MatrixAdd 2つのベクタ行列の要素ごとの加算
dstM[r][c] = srcM1[r][c] + srcM2[r][c]MatrixMultiply 2つのベクタ行列の積を求める
dstM[i][j] = Σ(srcM1[i][k])(srcM2[k][j])MatrixScale ベクタ行列を定数倍する MatrixSubtract 2つのベクタ行列の減算
dstM[r] [c]= srcM1[r][c] − srcM2[r][c]MatrixTranspose 行列の行と列を入れ替える
dstM[i][j] = srcM[j][i]MatrixInvert 行列の逆行列を求める フィルタ関数 FIRStruct FIRフィルタ用の構造体を生成する FIR サンプルの配列に対してFIR演算を実行する FIRDecimate サンプルの配列に対して指定比率のデシメートする FIRDelayInit サンプルの配列の遅延値を0に初期化する FIRInterpolate サンプルの配列に指定比率で要素を追加挿入する FIRInterDelayInit 挿入した要素を0にする FIRLattice 格子型FIRフィルタを適用する FIRLMS 適応型FIRフィルタを適用する FIRLMSNorm 最小自乗法による正規化で適応型フィルタを適応する FIRStructInit FIR構造体を初期化する IIRCanonic 縦続型(直接型T)IIRフィルタを適用する IIRCanonicInit 縦続型(直接型T)IIRフィルタの遅延値を初期化する IIRLattice 格子型IIRフィルタを適用する IIRLatticeInit 格子型IIRフィルタの遅延値を初期化する IIRTranspose 転置型縦続(直接型U)IIRフィルタを適用する IIRTransposeInit 転置型縦続(直接型U)IIRフィルタの遅延値を初期化 変換関数 BitReverseComplex 配列の要素をビット逆列順に並べ替える CosFactorInit COSの前半の値を求める TypeUDCTで使用する DCT DCT変換を適用し、結果を指定配列へ DCTIP DCT変換を適用し、結果を上書き FFTComplex FFT変換を適用し、結果を指定配列へ FFTComplexIP FFT変換を適用し、結果を上書き IFFTComplex 逆FFT変換し結果を指定配列へ IFFTComplexIP 逆FFT変換を適用、結果を上書き TwidFactorInit FFT用に半分の回転因子を求める
【FIRフィルタのプログラム例】
実際にDSPライブラリ関数を使ってプログラムを作成してみましょう。FIRフィルタを使います。
フィルタプログラムを作成するときの基本的なプログラム構成は下記のようになります。
(1) 配列データの準備
入力となる信号の配列と、フィルタ後の結果の配列を用意する
例では、入力データはSigIn、出力データはSigOutとしています。
フィルタの構造体の定義は上表のFIRStructを使ってバンドパスフィルタ用の
構造体を下記で定義しています。フィルタ設計ツールで作成される構造体なので
externで外部定義変数として宣言します。ここで「Bandpass」部分がフィルタ設計
ツールで作成したファイルの名称で、構造体自身は自動的に生成されています。
extern FIRStruct BandpassFilter;
(2) フィルタパラメータファイルをリンクする
Digital Filter Design Toolで作成したデータファイルをプロジェクトウインドウでリンクする
例題では、あらかじめ500Hzのバンドパスフィルタを設計してあり、Bandpass.hとBandpass.s
という2つのファイルが生成されているので両方ともリンクに加えます。
そのほかリンクが必要なファイルは下記のProject Windowのようにします。
(3) プログラムで入力データを取り込む
定周期のサンプリングで入力し、配列SigInに格納する。
ここでのサンプリング周期はフィルタ設計ツールで指定したサンプリング周期と同じに
する必要があります。例題はサンプリング周期が10kHzで、タイマ3でこの周期を生成し、
A/D変換を自動起動に設定している。
(4) フィルタの初期化
FIRDelayInit()関数で下記のように記述してフィルタ用変数を初期化する。
FIRDelayInit (&BandpassFilter);
(5) フィルタ関数実行
FIR()関数を実行して、入力データSiginをフィルタリングし、結果をSigOutに格納する。
このための記述は下記とします。MaxSizeはサンプリング数です。
FIR (MaxSize, &SigOut[0], &SigIn[0], &BandpassFilter);
これで実際に作成したFIRフィルタの例題は下記リストのようになります。
まずデータとパラメータ宣言部です。
次に、タイマ3の割り込み処理とメイン処理部です。A/Dコンバータはタイマ3の
一致で自動変換スタートにしていますので、タイマ3の割り込み処理内では
このA/D変換の終了を待ち、入力データはSigIn配列に順次格納します。
これをMaxSize回数だけ繰り返したら入力終了で、メインのflag待ちが解除
され、先に進んでフィルタ処理を開始します。
【フィルタ効果の確認方法】
上記プログラムでFIRフィルタが実行されますが、このフィルタの効果を実際に
確認する方法を説明します。
この確認には、MPLAB ICD2のデバッグ機能と、dsPICworksのグラフ表示機能を
活用します。
まず、上記プログラムのメイン内のキー入力直前の行で、ICD2のブレークポイントを
かけてからプログラムを実行します。
その前に適当なアナログ信号をAN0に入力するようにしておきます。今回の例では
500Hzの矩形波の連続パルス信号を入力としました。
さらにMPLABのWatch窓にSigInとSigOutを登録しておきます。プログラム実行後、
この配列データの内容をファイルとしてExportします。方法は下図のようにWatch窓
のデータを右クリックしてExportを選択し、適当なフォルダに適当なファイル名をつけて
格納するだけです。
次に保存したファイルをdsPICwroksでグラフ化します。ファイルの読み込み方は簡単で、
メインメニューから File → Inport とすると下記ダイアログが開きますので、ここで下記
のようにサンプリング周期とデータ形式を指定します。
これで入力のSigInと出力のSigOutを表示させると下図のようになります。この図を
みると、500Hzのバンドパスフィルタのフィルタ効果が歴然と現れていることがわかります。
このフィルタは64タップになっているので、過去の64個のデータが揃うまでは完全な
波形とはなりません。
下図は同じ500Hzのバンドパスフィルタに800Hzの矩形波を入力したときの、入力と
フィルタ後の波形です。 800Hzではかなり減衰することがわかります。