Nucleo-F446RE 内蔵の AD/DA を使うためのライブラリ.DA からの出力は,標本化周波数の4倍のレートで行う.出力の補間フィルタには直線位相の FIR フィルタを使用.  このライブラリを登録した際のプログラム: Demo_F446_AD_DA_MultirateLinearPhase. Library for built-in ADC and DAC in Nucleo-F446RE. Sampling rate for DAC is four times of that for ADC. Interpolation filter for output is linear-phase FIR filter.

Dependencies:   Array_Matrix

Dependents:   Demo_F446_AD_DA_MultirateLinearPhase

Revision:
0:ad30ac2b412b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/F446_LinearPhase.cpp	Tue Jul 03 01:29:13 2018 +0000
@@ -0,0 +1,114 @@
+//-----------------------------------------------------------
+//  出力を 4 倍にアップサンプリングするクラス
+//  Nucleo-F446RE 専用
+//  補間処理で使うフィルタとして,直線位相 FIR フィルタを使用
+//  
+//  2018/07/03, Copyright (c) 2018 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "F446_LinearPhase.hpp"
+using namespace Mikami;
+
+F446_LinearPhase::F446_LinearPhase(int order, const float hk1[],
+                                   const float hk2[], const float hk3[])
+    : indexW_(0), ORDER_(order), FIR_COUNT_(order/4),
+      CENTER_(order/(FACTOR_*2)), un_(order/4, 0.0f),
+      h1_(order/4), h2_(order/4), h3_(order/4)
+{
+    if (hk1 == NULL)
+    {
+        h1_.Assign(HK1_);
+        h2_.Assign(HK2_);
+        h3_.Assign(HK3_);
+    }
+    else    // デフォルト以外の補間用フィルタの係数を使用する
+    {
+        h1_.Assign(hk1);
+        h2_.Assign(hk2);
+        h3_.Assign(hk3);
+    }
+}
+
+// 標本化の実行開始
+void F446_LinearPhase::Start(int frequency, PinName pin)
+{
+    adc_ = new AdcF446(frequency*FACTOR_, pin); // AD変換器の初期化
+    wait_us(1000);    // ある程度の待ち時間が必要
+    adc_->SetIntrVec(&F446_LinearPhase::AdcIsr);  // ISR の設定
+}
+
+// AD変換の結果を取り出す
+float F446_LinearPhase::Input()
+{
+    while (!okIn_) {}   // AD変換の結果を取り出せるまで待つ
+    okIn_ = false;
+    return xn_;
+}
+
+// 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む
+void F446_LinearPhase::Output(float yn)
+{
+    un_[0] = yn;    // 補間フィルタ用バッファの先頭に書き込む
+
+    buf_[ModCounter(indexW_)] = un_[CENTER_];
+    buf_[ModCounter(indexW_)] = Interpolator(h1_);
+    buf_[ModCounter(indexW_)] = Interpolator(h2_);
+    buf_[ModCounter(indexW_)] = Interpolator(h3_);
+
+    for (int k=FIR_COUNT_-1; k>0; k--) un_[k] = un_[k-1];
+}
+
+// ADC 変換終了割り込みに対する割り込みサービス・ルーチン
+void F446_LinearPhase::AdcIsr()
+{
+    static int count = 0;
+
+    xn_ = adc_->Read();     // AD変換器の値を読み込む
+    dac_.Write(buf_[ModCounter(indexR_)]);  // 出力バッファの内容を DAC へ書き込む
+    
+    if (count == 0) okIn_ = true;   // AD変換器からの入力信号は4回に1回使う
+    count = ++count & MASK_FACTOR_; // 出力時に4倍にアップサンプリングするので,
+                                    // 入力を4回に1回行うための処理
+}
+
+// 補間用 FIR フィルタ
+float F446_LinearPhase::Interpolator(float hk[])
+{
+    float y = 0;
+    for (int n=0; n<FIR_COUNT_; n++) y = y + un_[n]*hk[n];
+    return y;
+}
+
+// static メンバの実体の宣言/初期化
+AdcF446 *F446_LinearPhase::adc_;
+DacF446 F446_LinearPhase::dac_;
+Array<float> F446_LinearPhase::buf_(2*FACTOR_, 0.0f);
+int F446_LinearPhase::indexR_ = FACTOR_;
+float F446_LinearPhase::xn_;
+__IO bool F446_LinearPhase::okIn_ = false;
+
+// デフォルトの補間用フィルタの係数(AD 変換器の標本化周波数は 10 kHz を想定している)
+// 使用窓関数   Kaiser 窓
+// 標本化周波数 (kHz)      40.000000
+// 次数                    72
+// 種類         LPF
+// 遮断周波数 (kHz)         5.000000
+// 減衰量 (dB)             40.00 
+const float F446_LinearPhase::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 F446_LinearPhase::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 F446_LinearPhase::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};