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.
Dependents: Demo_F446_AD_DA_MultirateLinearPhase
F446_LinearPhase.cpp@1:cd42ecc1e174, 2018-11-28 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Wed Nov 28 12:45:18 2018 +0000
- Revision:
- 1:cd42ecc1e174
- Parent:
- 0:ad30ac2b412b
2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:ad30ac2b412b | 1 | //----------------------------------------------------------- |
MikamiUitOpen | 0:ad30ac2b412b | 2 | // 出力を 4 倍にアップサンプリングするクラス |
MikamiUitOpen | 0:ad30ac2b412b | 3 | // Nucleo-F446RE 専用 |
MikamiUitOpen | 0:ad30ac2b412b | 4 | // 補間処理で使うフィルタとして,直線位相 FIR フィルタを使用 |
MikamiUitOpen | 0:ad30ac2b412b | 5 | // |
MikamiUitOpen | 0:ad30ac2b412b | 6 | // 2018/07/03, Copyright (c) 2018 MIKAMI, Naoki |
MikamiUitOpen | 0:ad30ac2b412b | 7 | //----------------------------------------------------------- |
MikamiUitOpen | 0:ad30ac2b412b | 8 | |
MikamiUitOpen | 0:ad30ac2b412b | 9 | #include "F446_LinearPhase.hpp" |
MikamiUitOpen | 0:ad30ac2b412b | 10 | using namespace Mikami; |
MikamiUitOpen | 0:ad30ac2b412b | 11 | |
MikamiUitOpen | 0:ad30ac2b412b | 12 | F446_LinearPhase::F446_LinearPhase(int order, const float hk1[], |
MikamiUitOpen | 0:ad30ac2b412b | 13 | const float hk2[], const float hk3[]) |
MikamiUitOpen | 0:ad30ac2b412b | 14 | : indexW_(0), ORDER_(order), FIR_COUNT_(order/4), |
MikamiUitOpen | 0:ad30ac2b412b | 15 | CENTER_(order/(FACTOR_*2)), un_(order/4, 0.0f), |
MikamiUitOpen | 0:ad30ac2b412b | 16 | h1_(order/4), h2_(order/4), h3_(order/4) |
MikamiUitOpen | 0:ad30ac2b412b | 17 | { |
MikamiUitOpen | 0:ad30ac2b412b | 18 | if (hk1 == NULL) |
MikamiUitOpen | 0:ad30ac2b412b | 19 | { |
MikamiUitOpen | 0:ad30ac2b412b | 20 | h1_.Assign(HK1_); |
MikamiUitOpen | 0:ad30ac2b412b | 21 | h2_.Assign(HK2_); |
MikamiUitOpen | 0:ad30ac2b412b | 22 | h3_.Assign(HK3_); |
MikamiUitOpen | 0:ad30ac2b412b | 23 | } |
MikamiUitOpen | 0:ad30ac2b412b | 24 | else // デフォルト以外の補間用フィルタの係数を使用する |
MikamiUitOpen | 0:ad30ac2b412b | 25 | { |
MikamiUitOpen | 0:ad30ac2b412b | 26 | h1_.Assign(hk1); |
MikamiUitOpen | 0:ad30ac2b412b | 27 | h2_.Assign(hk2); |
MikamiUitOpen | 0:ad30ac2b412b | 28 | h3_.Assign(hk3); |
MikamiUitOpen | 0:ad30ac2b412b | 29 | } |
MikamiUitOpen | 0:ad30ac2b412b | 30 | } |
MikamiUitOpen | 0:ad30ac2b412b | 31 | |
MikamiUitOpen | 0:ad30ac2b412b | 32 | // 標本化の実行開始 |
MikamiUitOpen | 0:ad30ac2b412b | 33 | void F446_LinearPhase::Start(int frequency, PinName pin) |
MikamiUitOpen | 0:ad30ac2b412b | 34 | { |
MikamiUitOpen | 0:ad30ac2b412b | 35 | adc_ = new AdcF446(frequency*FACTOR_, pin); // AD変換器の初期化 |
MikamiUitOpen | 0:ad30ac2b412b | 36 | wait_us(1000); // ある程度の待ち時間が必要 |
MikamiUitOpen | 0:ad30ac2b412b | 37 | adc_->SetIntrVec(&F446_LinearPhase::AdcIsr); // ISR の設定 |
MikamiUitOpen | 0:ad30ac2b412b | 38 | } |
MikamiUitOpen | 0:ad30ac2b412b | 39 | |
MikamiUitOpen | 0:ad30ac2b412b | 40 | // AD変換の結果を取り出す |
MikamiUitOpen | 0:ad30ac2b412b | 41 | float F446_LinearPhase::Input() |
MikamiUitOpen | 0:ad30ac2b412b | 42 | { |
MikamiUitOpen | 0:ad30ac2b412b | 43 | while (!okIn_) {} // AD変換の結果を取り出せるまで待つ |
MikamiUitOpen | 0:ad30ac2b412b | 44 | okIn_ = false; |
MikamiUitOpen | 0:ad30ac2b412b | 45 | return xn_; |
MikamiUitOpen | 0:ad30ac2b412b | 46 | } |
MikamiUitOpen | 0:ad30ac2b412b | 47 | |
MikamiUitOpen | 0:ad30ac2b412b | 48 | // 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む |
MikamiUitOpen | 0:ad30ac2b412b | 49 | void F446_LinearPhase::Output(float yn) |
MikamiUitOpen | 0:ad30ac2b412b | 50 | { |
MikamiUitOpen | 0:ad30ac2b412b | 51 | un_[0] = yn; // 補間フィルタ用バッファの先頭に書き込む |
MikamiUitOpen | 0:ad30ac2b412b | 52 | |
MikamiUitOpen | 0:ad30ac2b412b | 53 | buf_[ModCounter(indexW_)] = un_[CENTER_]; |
MikamiUitOpen | 0:ad30ac2b412b | 54 | buf_[ModCounter(indexW_)] = Interpolator(h1_); |
MikamiUitOpen | 0:ad30ac2b412b | 55 | buf_[ModCounter(indexW_)] = Interpolator(h2_); |
MikamiUitOpen | 0:ad30ac2b412b | 56 | buf_[ModCounter(indexW_)] = Interpolator(h3_); |
MikamiUitOpen | 0:ad30ac2b412b | 57 | |
MikamiUitOpen | 0:ad30ac2b412b | 58 | for (int k=FIR_COUNT_-1; k>0; k--) un_[k] = un_[k-1]; |
MikamiUitOpen | 0:ad30ac2b412b | 59 | } |
MikamiUitOpen | 0:ad30ac2b412b | 60 | |
MikamiUitOpen | 0:ad30ac2b412b | 61 | // ADC 変換終了割り込みに対する割り込みサービス・ルーチン |
MikamiUitOpen | 0:ad30ac2b412b | 62 | void F446_LinearPhase::AdcIsr() |
MikamiUitOpen | 0:ad30ac2b412b | 63 | { |
MikamiUitOpen | 0:ad30ac2b412b | 64 | static int count = 0; |
MikamiUitOpen | 0:ad30ac2b412b | 65 | |
MikamiUitOpen | 0:ad30ac2b412b | 66 | xn_ = adc_->Read(); // AD変換器の値を読み込む |
MikamiUitOpen | 0:ad30ac2b412b | 67 | dac_.Write(buf_[ModCounter(indexR_)]); // 出力バッファの内容を DAC へ書き込む |
MikamiUitOpen | 0:ad30ac2b412b | 68 | |
MikamiUitOpen | 0:ad30ac2b412b | 69 | if (count == 0) okIn_ = true; // AD変換器からの入力信号は4回に1回使う |
MikamiUitOpen | 0:ad30ac2b412b | 70 | count = ++count & MASK_FACTOR_; // 出力時に4倍にアップサンプリングするので, |
MikamiUitOpen | 0:ad30ac2b412b | 71 | // 入力を4回に1回行うための処理 |
MikamiUitOpen | 0:ad30ac2b412b | 72 | } |
MikamiUitOpen | 0:ad30ac2b412b | 73 | |
MikamiUitOpen | 0:ad30ac2b412b | 74 | // 補間用 FIR フィルタ |
MikamiUitOpen | 0:ad30ac2b412b | 75 | float F446_LinearPhase::Interpolator(float hk[]) |
MikamiUitOpen | 0:ad30ac2b412b | 76 | { |
MikamiUitOpen | 0:ad30ac2b412b | 77 | float y = 0; |
MikamiUitOpen | 0:ad30ac2b412b | 78 | for (int n=0; n<FIR_COUNT_; n++) y = y + un_[n]*hk[n]; |
MikamiUitOpen | 0:ad30ac2b412b | 79 | return y; |
MikamiUitOpen | 0:ad30ac2b412b | 80 | } |
MikamiUitOpen | 0:ad30ac2b412b | 81 | |
MikamiUitOpen | 0:ad30ac2b412b | 82 | // static メンバの実体の宣言/初期化 |
MikamiUitOpen | 0:ad30ac2b412b | 83 | AdcF446 *F446_LinearPhase::adc_; |
MikamiUitOpen | 0:ad30ac2b412b | 84 | DacF446 F446_LinearPhase::dac_; |
MikamiUitOpen | 0:ad30ac2b412b | 85 | Array<float> F446_LinearPhase::buf_(2*FACTOR_, 0.0f); |
MikamiUitOpen | 0:ad30ac2b412b | 86 | int F446_LinearPhase::indexR_ = FACTOR_; |
MikamiUitOpen | 0:ad30ac2b412b | 87 | float F446_LinearPhase::xn_; |
MikamiUitOpen | 0:ad30ac2b412b | 88 | __IO bool F446_LinearPhase::okIn_ = false; |
MikamiUitOpen | 0:ad30ac2b412b | 89 | |
MikamiUitOpen | 0:ad30ac2b412b | 90 | // デフォルトの補間用フィルタの係数(AD 変換器の標本化周波数は 10 kHz を想定している) |
MikamiUitOpen | 0:ad30ac2b412b | 91 | // 使用窓関数 Kaiser 窓 |
MikamiUitOpen | 0:ad30ac2b412b | 92 | // 標本化周波数 (kHz) 40.000000 |
MikamiUitOpen | 0:ad30ac2b412b | 93 | // 次数 72 |
MikamiUitOpen | 0:ad30ac2b412b | 94 | // 種類 LPF |
MikamiUitOpen | 0:ad30ac2b412b | 95 | // 遮断周波数 (kHz) 5.000000 |
MikamiUitOpen | 0:ad30ac2b412b | 96 | // 減衰量 (dB) 40.00 |
MikamiUitOpen | 0:ad30ac2b412b | 97 | const float F446_LinearPhase::HK1_[] = { |
MikamiUitOpen | 0:ad30ac2b412b | 98 | 4.431256E-03f, -8.146596E-03f, 1.341366E-02f, -2.077330E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 99 | 3.116614E-02f, -4.650688E-02f, 7.151836E-02f, -1.218529E-01f, |
MikamiUitOpen | 0:ad30ac2b412b | 100 | 2.971602E-01f, 8.993316E-01f, -1.751857E-01f, 9.144896E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 101 | -5.727932E-02f, 3.802786E-02f, -2.550498E-02f, 1.678651E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 102 | -1.055827E-02f, 6.120216E-03f}; |
MikamiUitOpen | 0:ad30ac2b412b | 103 | const float F446_LinearPhase::HK2_[] = { |
MikamiUitOpen | 0:ad30ac2b412b | 104 | 7.405152E-03f, -1.315348E-02f, 2.125564E-02f, -3.257789E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 105 | 4.868468E-02f, -7.290120E-02f, 1.139337E-01f, -2.039652E-01f, |
MikamiUitOpen | 0:ad30ac2b412b | 106 | 6.338376E-01f, 6.338376E-01f, -2.039652E-01f, 1.139337E-01f, |
MikamiUitOpen | 0:ad30ac2b412b | 107 | -7.290120E-02f, 4.868468E-02f, -3.257789E-02f, 2.125564E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 108 | -1.315348E-02f, 7.405152E-03f}; |
MikamiUitOpen | 0:ad30ac2b412b | 109 | const float F446_LinearPhase::HK3_[] = { |
MikamiUitOpen | 0:ad30ac2b412b | 110 | 6.120216E-03f, -1.055827E-02f, 1.678651E-02f, -2.550498E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 111 | 3.802786E-02f, -5.727932E-02f, 9.144896E-02f, -1.751857E-01f, |
MikamiUitOpen | 0:ad30ac2b412b | 112 | 8.993316E-01f, 2.971602E-01f, -1.218529E-01f, 7.151836E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 113 | -4.650688E-02f, 3.116614E-02f, -2.077330E-02f, 1.341366E-02f, |
MikamiUitOpen | 0:ad30ac2b412b | 114 | -8.146596E-03f, 4.431256E-03f}; |