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 4:c233f2db4652, committed 2020-06-18
- Comitter:
- MikamiUitOpen
- Date:
- Thu Jun 18 05:06:42 2020 +0000
- Parent:
- 3:59af3dfa0595
- Child:
- 5:e905fed6b994
- Commit message:
- 5
Changed in this revision
MultirateLiPh.cpp | Show annotated file Show diff for this revision Revisions of this file |
MultirateLiPhCoefs.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/MultirateLiPh.cpp Tue Jun 16 09:48:54 2020 +0000 +++ b/MultirateLiPh.cpp Thu Jun 18 05:06:42 2020 +0000 @@ -2,87 +2,90 @@ // 出力を 4 倍にアップサンプリングするクラス // 補間処理で使うフィルタとして,直線位相 FIR フィルタを使用 // -// 2020/06/16, Copyright (c) 2020 MIKAMI, Naoki +// 2020/06/18, Copyright (c) 2020 MIKAMI, Naoki //----------------------------------------------------------- #include "MultirateLiPh.hpp" -using namespace Mikami; -// コンストラクタ(デフォルトの補間フィルタの係数を使う場合) -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); } +namespace Mikami +{ + // コンストラクタ(デフォルトの補間フィルタの係数を使う場合) + 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); } -// コンストラクタ(デフォルト以外の補間フィルタの係数を使う場合) -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); } + // コンストラクタ(デフォルト以外の補間フィルタの係数を使う場合) + 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); } -// 標本化の実行開始 -void MultirateLiPh::Start(void (*Func)()) -{ - // CAN2_TX によるソフトウェア割り込みに対応する設定 - NVIC_SetVector(CAN2_TX_IRQn, (uint32_t)Func); - NVIC_EnableIRQ(CAN2_TX_IRQn); + // 標本化の実行開始 + void MultirateLiPh::Start(void (*Func)()) + { + // CAN2_TX によるソフトウェア割り込みに対応する設定 + NVIC_SetVector(CAN2_TX_IRQn, (uint32_t)Func); + NVIC_EnableIRQ(CAN2_TX_IRQn); - // AD 変換器を使うための準備 - wait_us(1000); // ある程度の待ち時間が必要 - adc_->SetIntrVec(&MultirateLiPh::AdcIsr); // AD 変換終了に対応する ISR の設定 -} + // AD 変換器を使うための準備 + wait_us(1000); // ある程度の待ち時間が必要 + adc_->SetIntrVec(&MultirateLiPh::AdcIsr); // AD 変換終了に対応する ISR の設定 + } -// 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む -void MultirateLiPh::Output(float yn) -{ - un_[0] = yn; // 補間フィルタ用バッファの先頭に書き込む + // 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む + void MultirateLiPh::Output(float yn) + { + un_[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_)] = un_[CENTER_]; + buf_[ModIndex(indexW_)] = Interpolator(h1_); + buf_[ModIndex(indexW_)] = Interpolator(h2_); + buf_[ModIndex(indexW_)] = Interpolator(h3_); - for (int k=FIR_LOOP_-1; k>0; k--) un_[k] = un_[k-1]; -} + for (int k=FIR_LOOP_-1; k>0; k--) un_[k] = un_[k-1]; + } -// ADC 変換終了割り込みに対する割り込みサービス・ルーチン -void MultirateLiPh::AdcIsr() -{ - static int count = 0; + // ADC 変換終了割り込みに対する割り込みサービス・ルーチン + void MultirateLiPh::AdcIsr() + { + static int count = 0; - xn_ = adc_->Read(); // AD変換器の値を読み込む - dac_.Write(buf_[ModIndex(indexR_)]); // 出力バッファの内容を DAC へ書き込む + xn_ = adc_->Read(); // AD変換器の値を読み込む + dac_.Write(buf_[ModIndex(indexR_)]); // 出力バッファの内容を DAC へ書き込む - if (count == 0) // AD変換器からの入力信号は4回に1回使う - NVIC->STIR = CAN2_TX_IRQn; // ソフトウェア割込み発生,信号処理を起動 - count = ++count & MASK_FACTOR_; // 入力を4回に1回行うための処理 -} + if (count == 0) // AD変換器からの入力信号は4回に1回使う + NVIC->STIR = CAN2_TX_IRQn; // ソフトウェア割込み発生,信号処理を起動 + count = ++count & MASK_FACTOR_; // 入力を4回に1回行うための処理 + } -// 補間用 FIR フィルタ -float MultirateLiPh::Interpolator(const float hk[]) const -{ - float y = 0; - for (int n=0; n<FIR_LOOP_; n++) y += un_[n]*hk[n]; - return y; -} + // 補間用 FIR フィルタ + float MultirateLiPh::Interpolator(const float hk[]) const + { + float y = 0; + for (int n=0; n<FIR_LOOP_; n++) y += un_[n]*hk[n]; + return y; + } -// ADC の初期化と割込み優先順位の設定 -void MultirateLiPh::Init(float fSampling, PinName pin, ADC_TypeDef* const adc) -{ - NVIC_SetPriority(ADC_IRQn, 0); // ADC 終了割り込み:最優先 - NVIC_SetPriority(CAN2_TX_IRQn, 1); // ソフトウェア割り込みで使用:2番目に優先 + // ADC の初期化と割込み優先順位の設定 + void MultirateLiPh::Init(float fSampling, PinName pin, ADC_TypeDef* const adc) + { + 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*FACTOR_, pin, adc); + } -// static メンバの実体の宣言/初期化 -DspAdc_Intr *MultirateLiPh::adc_; // AD変換器のオブジェクトのポインタ -DspDac MultirateLiPh::dac_; // DA変換器のオブジェクト -Array<float> MultirateLiPh::buf_(2*FACTOR_, 0.0f); -int MultirateLiPh::indexR_ = FACTOR_; -float MultirateLiPh::xn_; \ No newline at end of file + // static メンバの実体の宣言/初期化 + DspAdc_Intr *MultirateLiPh::adc_; // AD変換器のオブジェクトのポインタ + DspDac MultirateLiPh::dac_; // DA変換器のオブジェクト + Array<float> MultirateLiPh::buf_(2*FACTOR_, 0.0f); + int MultirateLiPh::indexR_ = FACTOR_; + float MultirateLiPh::xn_; +} \ No newline at end of file
--- a/MultirateLiPhCoefs.cpp Tue Jun 16 09:48:54 2020 +0000 +++ b/MultirateLiPhCoefs.cpp Thu Jun 18 05:06:42 2020 +0000 @@ -1,37 +1,38 @@ //------------------------------------------------------------------- // デフォルトの補間用フィルタの係数 +// このの係数は,入力の標本化周波数は 10 kHz,出力の標本化周波数を +// 40 kHz として設計したもの // -// 2020/06/16, Copyright (c) 2020 MIKAMI, Naoki +// 2020/06/18, Copyright (c) 2020 MIKAMI, Naoki //------------------------------------------------------------------- #include "MultirateLiPh.hpp" -using namespace Mikami; -// 以下の係数は,入力の標本化周波数は 10 kHz,出力の標本化周波数は 40 kHz -// として設計したもの -// -// 使用窓関数 Kaiser 窓 -// 標本化周波数 (kHz) 40.000000 -// 次数 72 -// 種類 LPF -// 遮断周波数 (kHz) 5.000000 -// 減衰量 (dB) 40.00 -const int MultirateLiPh::ORDER_ = 72; -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}; -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}; -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}; \ No newline at end of file +namespace Mikami +{ + // 使用窓関数 Kaiser 窓 + // 標本化周波数 (kHz) 40.000000 + // 次数 72 + // 種類 LPF + // 遮断周波数 (kHz) 5.000000 + // 減衰量 (dB) 40.00 + const int MultirateLiPh::ORDER_ = 72; + 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}; + 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}; + 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}; +} \ No newline at end of file