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:
0:79c0b1e2fd10
Child:
2:aa092bbc8877
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MultirateLiPh.cpp	Mon May 25 06:13:53 2020 +0000
@@ -0,0 +1,74 @@
+//-----------------------------------------------------------
+//  出力を 4 倍にアップサンプリングするクラス
+//  補間処理で使うフィルタとして,直線位相 FIR フィルタを使用
+//  
+//  2020/05/25, Copyright (c) 2020 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "MultirateLiPh.hpp"
+using namespace Mikami;
+
+MultirateLiPh::MultirateLiPh()
+    : 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_)
+{
+    // 割り込み優先順位の設定
+    NVIC_SetPriority(ADC_IRQn, 0);      // ADC 終了割り込み:最優先
+    NVIC_SetPriority(CAN2_TX_IRQn, 1);  // ソフトウェア割り込みで使用:2番目に優先
+}
+
+// 標本化の実行開始
+void MultirateLiPh::Start(float fSampling, void (*Func)(),
+                          PinName pin, ADC_TypeDef* const adc)
+{
+    // CAN2_TX によるソフトウェア割り込みに対応する設定
+    NVIC_SetVector(CAN2_TX_IRQn, (uint32_t)Func);
+    NVIC_EnableIRQ(CAN2_TX_IRQn);       
+
+    // AD 変換器を使うための準備
+    adc_ = new DspAdc_Intr(fSampling*FACTOR_, pin, adc);
+    wait_us(1000);    // ある程度の待ち時間が必要
+    adc_->SetIntrVec(&MultirateLiPh::AdcIsr);  // AD 変換終了に対応する ISR の設定
+}
+
+// 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む
+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_);
+
+    for (int k=FIR_LOOP_-1; k>0; k--) un_[k] = un_[k-1];
+}
+
+// ADC 変換終了割り込みに対する割り込みサービス・ルーチン
+void MultirateLiPh::AdcIsr()
+{
+    static int count = 0;
+
+    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回行うための処理
+}
+
+// 補間用 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;
+}
+
+// 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