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
MultirateLiPh.cpp@8:356d0c5f97c3, 2020-11-28 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Sat Nov 28 02:27:00 2020 +0000
- Revision:
- 8:356d0c5f97c3
- Parent:
- 4:c233f2db4652
- Child:
- 9:9f391b2d51be
9
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:79c0b1e2fd10 | 1 | //----------------------------------------------------------- |
MikamiUitOpen | 0:79c0b1e2fd10 | 2 | // 出力を 4 倍にアップサンプリングするクラス |
MikamiUitOpen | 8:356d0c5f97c3 | 3 | // 補間処理で使うフィルタ:直線位相 FIR フィルタ |
MikamiUitOpen | 0:79c0b1e2fd10 | 4 | // |
MikamiUitOpen | 8:356d0c5f97c3 | 5 | // 2020/11/28, Copyright (c) 2020 MIKAMI, Naoki |
MikamiUitOpen | 0:79c0b1e2fd10 | 6 | //----------------------------------------------------------- |
MikamiUitOpen | 0:79c0b1e2fd10 | 7 | |
MikamiUitOpen | 0:79c0b1e2fd10 | 8 | #include "MultirateLiPh.hpp" |
MikamiUitOpen | 0:79c0b1e2fd10 | 9 | |
MikamiUitOpen | 4:c233f2db4652 | 10 | namespace Mikami |
MikamiUitOpen | 4:c233f2db4652 | 11 | { |
MikamiUitOpen | 4:c233f2db4652 | 12 | // コンストラクタ(デフォルトの補間フィルタの係数を使う場合) |
MikamiUitOpen | 4:c233f2db4652 | 13 | MultirateLiPh::MultirateLiPh(float fSampling, |
MikamiUitOpen | 4:c233f2db4652 | 14 | PinName pin, ADC_TypeDef* const adc) |
MikamiUitOpen | 8:356d0c5f97c3 | 15 | : indexW_(0), FIR_LOOP_((ORDER_+2)/UR_), CENTER_((ORDER_+2)/(UR_*2)), |
MikamiUitOpen | 8:356d0c5f97c3 | 16 | vn_((ORDER_+2)/UR_, 0.0f), h1_((ORDER_+2)/UR_, HK1_), |
MikamiUitOpen | 8:356d0c5f97c3 | 17 | h2_((ORDER_+2)/UR_, HK2_), h3_((ORDER_+2)/UR_, HK3_) |
MikamiUitOpen | 8:356d0c5f97c3 | 18 | { |
MikamiUitOpen | 8:356d0c5f97c3 | 19 | MBED_ASSERT((ORDER_ % UR_) == 2); |
MikamiUitOpen | 8:356d0c5f97c3 | 20 | Init(fSampling, pin, adc); |
MikamiUitOpen | 8:356d0c5f97c3 | 21 | } |
MikamiUitOpen | 3:59af3dfa0595 | 22 | |
MikamiUitOpen | 4:c233f2db4652 | 23 | // コンストラクタ(デフォルト以外の補間フィルタの係数を使う場合) |
MikamiUitOpen | 4:c233f2db4652 | 24 | MultirateLiPh::MultirateLiPh(float fSampling, int order, |
MikamiUitOpen | 4:c233f2db4652 | 25 | const float hk1[], const float hk2[], |
MikamiUitOpen | 4:c233f2db4652 | 26 | const float hk3[], |
MikamiUitOpen | 4:c233f2db4652 | 27 | PinName pin, ADC_TypeDef* const adc) |
MikamiUitOpen | 8:356d0c5f97c3 | 28 | : indexW_(0), FIR_LOOP_((order+2)/UR_), CENTER_((order+2)/(UR_*2)), |
MikamiUitOpen | 8:356d0c5f97c3 | 29 | vn_((order+2)/UR_, 0.0f), h1_((order+2)/UR_, hk1), |
MikamiUitOpen | 8:356d0c5f97c3 | 30 | h2_((order+2)/UR_, hk2), h3_((order+2)/UR_, hk3) |
MikamiUitOpen | 8:356d0c5f97c3 | 31 | { |
MikamiUitOpen | 8:356d0c5f97c3 | 32 | MBED_ASSERT((order % UR_) == 2); |
MikamiUitOpen | 8:356d0c5f97c3 | 33 | Init(fSampling, pin, adc); |
MikamiUitOpen | 8:356d0c5f97c3 | 34 | } |
MikamiUitOpen | 0:79c0b1e2fd10 | 35 | |
MikamiUitOpen | 4:c233f2db4652 | 36 | // 標本化の実行開始 |
MikamiUitOpen | 4:c233f2db4652 | 37 | void MultirateLiPh::Start(void (*Func)()) |
MikamiUitOpen | 4:c233f2db4652 | 38 | { |
MikamiUitOpen | 4:c233f2db4652 | 39 | // CAN2_TX によるソフトウェア割り込みに対応する設定 |
MikamiUitOpen | 4:c233f2db4652 | 40 | NVIC_SetVector(CAN2_TX_IRQn, (uint32_t)Func); |
MikamiUitOpen | 4:c233f2db4652 | 41 | NVIC_EnableIRQ(CAN2_TX_IRQn); |
MikamiUitOpen | 0:79c0b1e2fd10 | 42 | |
MikamiUitOpen | 4:c233f2db4652 | 43 | // AD 変換器を使うための準備 |
MikamiUitOpen | 4:c233f2db4652 | 44 | wait_us(1000); // ある程度の待ち時間が必要 |
MikamiUitOpen | 4:c233f2db4652 | 45 | adc_->SetIntrVec(&MultirateLiPh::AdcIsr); // AD 変換終了に対応する ISR の設定 |
MikamiUitOpen | 4:c233f2db4652 | 46 | } |
MikamiUitOpen | 0:79c0b1e2fd10 | 47 | |
MikamiUitOpen | 4:c233f2db4652 | 48 | // 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む |
MikamiUitOpen | 4:c233f2db4652 | 49 | void MultirateLiPh::Output(float yn) |
MikamiUitOpen | 4:c233f2db4652 | 50 | { |
MikamiUitOpen | 8:356d0c5f97c3 | 51 | vn_[0] = yn; // 補間フィルタ用バッファの先頭に書き込む |
MikamiUitOpen | 0:79c0b1e2fd10 | 52 | |
MikamiUitOpen | 8:356d0c5f97c3 | 53 | buf_[ModIndex(indexW_)] = vn_[CENTER_]; |
MikamiUitOpen | 8:356d0c5f97c3 | 54 | buf_[ModIndex(indexW_)] = Interpolate(h1_); |
MikamiUitOpen | 8:356d0c5f97c3 | 55 | buf_[ModIndex(indexW_)] = Interpolate(h2_); |
MikamiUitOpen | 8:356d0c5f97c3 | 56 | buf_[ModIndex(indexW_)] = Interpolate(h3_); |
MikamiUitOpen | 0:79c0b1e2fd10 | 57 | |
MikamiUitOpen | 8:356d0c5f97c3 | 58 | for (int k=FIR_LOOP_-1; k>0; k--) vn_[k] = vn_[k-1]; |
MikamiUitOpen | 4:c233f2db4652 | 59 | } |
MikamiUitOpen | 0:79c0b1e2fd10 | 60 | |
MikamiUitOpen | 4:c233f2db4652 | 61 | // ADC 変換終了割り込みに対する割り込みサービス・ルーチン |
MikamiUitOpen | 4:c233f2db4652 | 62 | void MultirateLiPh::AdcIsr() |
MikamiUitOpen | 4:c233f2db4652 | 63 | { |
MikamiUitOpen | 4:c233f2db4652 | 64 | static int count = 0; |
MikamiUitOpen | 0:79c0b1e2fd10 | 65 | |
MikamiUitOpen | 4:c233f2db4652 | 66 | xn_ = adc_->Read(); // AD変換器の値を読み込む |
MikamiUitOpen | 4:c233f2db4652 | 67 | dac_.Write(buf_[ModIndex(indexR_)]); // 出力バッファの内容を DAC へ書き込む |
MikamiUitOpen | 0:79c0b1e2fd10 | 68 | |
MikamiUitOpen | 4:c233f2db4652 | 69 | if (count == 0) // AD変換器からの入力信号は4回に1回使う |
MikamiUitOpen | 4:c233f2db4652 | 70 | NVIC->STIR = CAN2_TX_IRQn; // ソフトウェア割込み発生,信号処理を起動 |
MikamiUitOpen | 8:356d0c5f97c3 | 71 | count = ++count & MASK_UR_; // 入力を4回に1回行うための処理 |
MikamiUitOpen | 4:c233f2db4652 | 72 | } |
MikamiUitOpen | 0:79c0b1e2fd10 | 73 | |
MikamiUitOpen | 4:c233f2db4652 | 74 | // 補間用 FIR フィルタ |
MikamiUitOpen | 8:356d0c5f97c3 | 75 | float MultirateLiPh::Interpolate(const float hk[]) const |
MikamiUitOpen | 4:c233f2db4652 | 76 | { |
MikamiUitOpen | 4:c233f2db4652 | 77 | float y = 0; |
MikamiUitOpen | 8:356d0c5f97c3 | 78 | for (int n=0; n<FIR_LOOP_; n++) y += vn_[n]*hk[n]; |
MikamiUitOpen | 4:c233f2db4652 | 79 | return y; |
MikamiUitOpen | 4:c233f2db4652 | 80 | } |
MikamiUitOpen | 0:79c0b1e2fd10 | 81 | |
MikamiUitOpen | 4:c233f2db4652 | 82 | // ADC の初期化と割込み優先順位の設定 |
MikamiUitOpen | 4:c233f2db4652 | 83 | void MultirateLiPh::Init(float fSampling, PinName pin, ADC_TypeDef* const adc) |
MikamiUitOpen | 4:c233f2db4652 | 84 | { |
MikamiUitOpen | 4:c233f2db4652 | 85 | NVIC_SetPriority(ADC_IRQn, 0); // ADC 終了割り込み:最優先 |
MikamiUitOpen | 4:c233f2db4652 | 86 | NVIC_SetPriority(CAN2_TX_IRQn, 1); // ソフトウェア割り込みで使用:2番目に優先 |
MikamiUitOpen | 3:59af3dfa0595 | 87 | |
MikamiUitOpen | 8:356d0c5f97c3 | 88 | adc_ = new DspAdc_Intr(fSampling*UR_, pin, adc); |
MikamiUitOpen | 4:c233f2db4652 | 89 | } |
MikamiUitOpen | 3:59af3dfa0595 | 90 | |
MikamiUitOpen | 4:c233f2db4652 | 91 | // static メンバの実体の宣言/初期化 |
MikamiUitOpen | 4:c233f2db4652 | 92 | DspAdc_Intr *MultirateLiPh::adc_; // AD変換器のオブジェクトのポインタ |
MikamiUitOpen | 4:c233f2db4652 | 93 | DspDac MultirateLiPh::dac_; // DA変換器のオブジェクト |
MikamiUitOpen | 8:356d0c5f97c3 | 94 | Array<float> MultirateLiPh::buf_(2*UR_, 0.0f); |
MikamiUitOpen | 8:356d0c5f97c3 | 95 | int MultirateLiPh::indexR_ = UR_; |
MikamiUitOpen | 4:c233f2db4652 | 96 | float MultirateLiPh::xn_; |
MikamiUitOpen | 4:c233f2db4652 | 97 | } |