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

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?

UserRevisionLine numberNew 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 }