STM32F446 内蔵の DAC から出力する際に,補間フィルタを利用し,標本化周波数を入力の際の4倍の標本化周波数で出力するためのライブラリ.このライブラリを登録した際のプログラム: Demo_DSP_ADDA_Multirate. Library for outputting from built-in DAC in STM32F446 using interpolation filter at sampling frequency of 4 times in case of input.
Dependencies: Array_Matrix DSP_ADDA
Dependents: Demo_DSP_ADDA_Multirate DSP_AD_DA_Multirate DSP_GraphicEqualizerB DSP_VariableLHpfB ... more
Revision 8:356d0c5f97c3, committed 2020-11-28
- Comitter:
- MikamiUitOpen
- Date:
- Sat Nov 28 02:27:00 2020 +0000
- Parent:
- 7:51726b376b75
- Child:
- 9:9f391b2d51be
- Commit message:
- 9
Changed in this revision
--- a/MultirateLiPh.cpp Sat Nov 07 02:17:52 2020 +0000 +++ b/MultirateLiPh.cpp Sat Nov 28 02:27:00 2020 +0000 @@ -1,8 +1,8 @@ //----------------------------------------------------------- // 出力を 4 倍にアップサンプリングするクラス -// 補間処理で使うフィルタとして,直線位相 FIR フィルタを使用 +// 補間処理で使うフィルタ:直線位相 FIR フィルタ // -// 2020/06/18, Copyright (c) 2020 MIKAMI, Naoki +// 2020/11/28, Copyright (c) 2020 MIKAMI, Naoki //----------------------------------------------------------- #include "MultirateLiPh.hpp" @@ -12,20 +12,26 @@ // コンストラクタ(デフォルトの補間フィルタの係数を使う場合) MultirateLiPh::MultirateLiPh(float fSampling, PinName pin, ADC_TypeDef* const adc) - : indexW_(0), FIR_LOOP_(ORDER_/4), CENTER_(ORDER_/(FACTOR_*2)), - un_(ORDER_/4, 0.0f), - h1_(ORDER_/4, HK1_), h2_(ORDER_/4, HK2_), h3_(ORDER_/4, HK3_) - { Init(fSampling, pin, adc); } + : indexW_(0), FIR_LOOP_((ORDER_+2)/UR_), CENTER_((ORDER_+2)/(UR_*2)), + vn_((ORDER_+2)/UR_, 0.0f), h1_((ORDER_+2)/UR_, HK1_), + h2_((ORDER_+2)/UR_, HK2_), h3_((ORDER_+2)/UR_, HK3_) + { + MBED_ASSERT((ORDER_ % UR_) == 2); + Init(fSampling, pin, adc); + } // コンストラクタ(デフォルト以外の補間フィルタの係数を使う場合) MultirateLiPh::MultirateLiPh(float fSampling, int order, const float hk1[], const float hk2[], const float hk3[], PinName pin, ADC_TypeDef* const adc) - : indexW_(0), FIR_LOOP_(order/4), CENTER_(order/(FACTOR_*2)), - un_(order/4, 0.0f), - h1_(order/4, hk1), h2_(order/4, hk2), h3_(order/4, hk3) - { Init(fSampling, pin, adc); } + : indexW_(0), FIR_LOOP_((order+2)/UR_), CENTER_((order+2)/(UR_*2)), + vn_((order+2)/UR_, 0.0f), h1_((order+2)/UR_, hk1), + h2_((order+2)/UR_, hk2), h3_((order+2)/UR_, hk3) + { + MBED_ASSERT((order % UR_) == 2); + Init(fSampling, pin, adc); + } // 標本化の実行開始 void MultirateLiPh::Start(void (*Func)()) @@ -42,14 +48,14 @@ // 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む void MultirateLiPh::Output(float yn) { - un_[0] = yn; // 補間フィルタ用バッファの先頭に書き込む + vn_[0] = yn; // 補間フィルタ用バッファの先頭に書き込む - buf_[ModIndex(indexW_)] = un_[CENTER_]; - buf_[ModIndex(indexW_)] = Interpolator(h1_); - buf_[ModIndex(indexW_)] = Interpolator(h2_); - buf_[ModIndex(indexW_)] = Interpolator(h3_); + buf_[ModIndex(indexW_)] = vn_[CENTER_]; + buf_[ModIndex(indexW_)] = Interpolate(h1_); + buf_[ModIndex(indexW_)] = Interpolate(h2_); + buf_[ModIndex(indexW_)] = Interpolate(h3_); - for (int k=FIR_LOOP_-1; k>0; k--) un_[k] = un_[k-1]; + for (int k=FIR_LOOP_-1; k>0; k--) vn_[k] = vn_[k-1]; } // ADC 変換終了割り込みに対する割り込みサービス・ルーチン @@ -62,14 +68,14 @@ if (count == 0) // AD変換器からの入力信号は4回に1回使う NVIC->STIR = CAN2_TX_IRQn; // ソフトウェア割込み発生,信号処理を起動 - count = ++count & MASK_FACTOR_; // 入力を4回に1回行うための処理 + count = ++count & MASK_UR_; // 入力を4回に1回行うための処理 } // 補間用 FIR フィルタ - float MultirateLiPh::Interpolator(const float hk[]) const + float MultirateLiPh::Interpolate(const float hk[]) const { float y = 0; - for (int n=0; n<FIR_LOOP_; n++) y += un_[n]*hk[n]; + for (int n=0; n<FIR_LOOP_; n++) y += vn_[n]*hk[n]; return y; } @@ -79,13 +85,13 @@ NVIC_SetPriority(ADC_IRQn, 0); // ADC 終了割り込み:最優先 NVIC_SetPriority(CAN2_TX_IRQn, 1); // ソフトウェア割り込みで使用:2番目に優先 - adc_ = new DspAdc_Intr(fSampling*FACTOR_, pin, adc); + adc_ = new DspAdc_Intr(fSampling*UR_, pin, adc); } // static メンバの実体の宣言/初期化 DspAdc_Intr *MultirateLiPh::adc_; // AD変換器のオブジェクトのポインタ DspDac MultirateLiPh::dac_; // DA変換器のオブジェクト - Array<float> MultirateLiPh::buf_(2*FACTOR_, 0.0f); - int MultirateLiPh::indexR_ = FACTOR_; + Array<float> MultirateLiPh::buf_(2*UR_, 0.0f); + int MultirateLiPh::indexR_ = UR_; float MultirateLiPh::xn_; } \ No newline at end of file
--- a/MultirateLiPh.hpp Sat Nov 07 02:17:52 2020 +0000 +++ b/MultirateLiPh.hpp Sat Nov 28 02:27:00 2020 +0000 @@ -1,10 +1,10 @@ //----------------------------------------------------------- // 出力を 4 倍にアップサンプリングするクラス(ヘッダ) -// 補間処理で使うフィルタとして,直線位相 FIR フィルタを使用 +// 補間処理で使うフィルタ:直線位相 FIR フィルタ // // 出力端子: A2 (PA_4) // -// 2020/09/13, Copyright (c) 2020 MIKAMI, Naoki +// 2020/11/28, Copyright (c) 2020 MIKAMI, Naoki //----------------------------------------------------------- #include "DSP_AdcIntr.hpp" @@ -45,10 +45,10 @@ void Output(float yn); private: - static const int FACTOR_ = 4; // アップサンプリング倍率:4 倍 - // この倍率は 2 のべき乗にすること - static const int MASK_FACTOR_ = FACTOR_ - 1; - static const int MASK_BUF_ = 2*FACTOR_ - 1; + static const int UR_ = 4; // アップサンプリング倍率:4 倍 + // この倍率は 2 のべき乗にすること + static const int MASK_UR_ = UR_ - 1; + static const int MASK_BUF_ = 2*UR_ - 1; static DspAdc_Intr *adc_; // AD変換器のオブジェクトのポインタ static DspDac dac_; // DA変換器のオブジェクト @@ -61,7 +61,7 @@ // 補間用フィルタ用 const int FIR_LOOP_; // FIR フィルタのループの数 const int CENTER_; // 補間処理をしない信号の位置 - Array<float> un_; // FIR フィルタの遅延器に対応するバッファ + Array<float> vn_; // FIR フィルタの遅延器に対応するバッファ Array<float> h1_, h2_, h3_; // FIR フィルタの係数 // 補間用フィルタ用の係数(デフォルト) @@ -76,7 +76,7 @@ static void AdcIsr(); // 補間用 FIR フィルタ - float Interpolator(const float hk[]) const; + float Interpolate(const float hk[]) const; // ADC の初期化と割込み優先順位の設定 void Init(float fSampling, PinName pin, ADC_TypeDef* const adc);
--- a/MultirateLiPhCoefs.cpp Sat Nov 07 02:17:52 2020 +0000 +++ b/MultirateLiPhCoefs.cpp Sat Nov 28 02:27:00 2020 +0000 @@ -1,9 +1,9 @@ //------------------------------------------------------------------- // デフォルトの補間用フィルタの係数 -// このの係数は,入力の標本化周波数を 10 kHz,出力の標本化周波数を -// 40 kHz として設計したもの +// この係数は,入力の標本化周波数を 10 kHz, +// 出力の標本化周波数を 40 kHz として設計した // -// 2020/09/12, Copyright (c) 2020 MIKAMI, Naoki +// 2020/11/28, Copyright (c) 2020 MIKAMI, Naoki //------------------------------------------------------------------- #include "MultirateLiPh.hpp" @@ -12,27 +12,27 @@ { // 使用窓関数 Kaiser 窓 // 標本化周波数 (kHz) 40.000000 - // 次数 72 + // 次数 70 // 種類 LPF // 遮断周波数 (kHz) 5.000000 - // 減衰量 (dB) 40.00 - const int MultirateLiPh::ORDER_ = 72; + // 減衰量 (dB) 40.00 + const int MultirateLiPh::ORDER_ = 70; const float MultirateLiPh::HK1_[] = { - 4.431256E-03f, -8.146596E-03f, 1.341366E-02f, -2.077330E-02f, - 3.116614E-02f, -4.650688E-02f, 7.151836E-02f, -1.218529E-01f, - 2.971602E-01f, 8.993316E-01f, -1.751857E-01f, 9.144896E-02f, - -5.727932E-02f, 3.802786E-02f, -2.550498E-02f, 1.678651E-02f, - -1.055827E-02f, 6.120216E-03f}; + 3.806160E-03f, -7.410556E-03f, 1.260559E-02f, -1.994242E-02f, + 3.036776E-02f, -4.579744E-02f, 7.095016E-02f, -1.214690E-01f, + 2.969901E-01f, 8.992744E-01f, -1.749060E-01f, 9.096828E-02f, + -5.663444E-02f, 3.726704E-02f, -2.468324E-02f, 1.596038E-02f, + -9.780624E-03f, 5.435560E-03f}; const float MultirateLiPh::HK2_[] = { - 7.405152E-03f, -1.315348E-02f, 2.125564E-02f, -3.257789E-02f, - 4.868468E-02f, -7.290120E-02f, 1.139337E-01f, -2.039652E-01f, - 6.338376E-01f, 6.338376E-01f, -2.039652E-01f, 1.139337E-01f, - -7.290120E-02f, 4.868468E-02f, -3.257789E-02f, 2.125564E-02f, - -1.315348E-02f, 7.405152E-03f}; + 6.477720E-03f, -1.208128E-02f, 2.009782E-02f, -3.140681E-02f, + 4.757964E-02f, -7.194132E-02f, 1.131902E-01f, -2.034948E-01f, + 6.336764E-01f, 6.336764E-01f, -2.034948E-01f, 1.131902E-01f, + -7.194132E-02f, 4.757964E-02f, -3.140681E-02f, 2.009782E-02f, + -1.208128E-02f, 6.477720E-03f}; const float MultirateLiPh::HK3_[] = { - 6.120216E-03f, -1.055827E-02f, 1.678651E-02f, -2.550498E-02f, - 3.802786E-02f, -5.727932E-02f, 9.144896E-02f, -1.751857E-01f, - 8.993316E-01f, 2.971602E-01f, -1.218529E-01f, 7.151836E-02f, - -4.650688E-02f, 3.116614E-02f, -2.077330E-02f, 1.341366E-02f, - -8.146596E-03f, 4.431256E-03f}; + 5.435560E-03f, -9.780624E-03f, 1.596038E-02f, -2.468324E-02f, + 3.726704E-02f, -5.663444E-02f, 9.096828E-02f, -1.749060E-01f, + 8.992744E-01f, 2.969901E-01f, -1.214690E-01f, 7.095016E-02f, + -4.579744E-02f, 3.036776E-02f, -1.994242E-02f, 1.260559E-02f, + -7.410556E-03f, 3.806160E-03f}; } \ No newline at end of file