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:
Tue Jun 16 09:48:54 2020 +0000
Revision:
3:59af3dfa0595
Parent:
2:aa092bbc8877
Child:
4:c233f2db4652
4

Who changed what in which revision?

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