Nucleo-F446RE 内蔵の AD/DA を使うためのライブラリ.DA からの出力は,標本化周波数の4倍のレートで行う.AD の読み込みにはソフトウェア割り込みを使用. このライブラリを登録した際のプログラム: Demo_F446_AD_DA_MultirateSWI. Library for built-in ADC and DAC in Nucleo-F446RE using software interrupt for reading ADC. Sampling rate for DAC is four times of that for ADC.
Dependents: F446_UpSampling_LPF_HPF_Variable Demo_F446_AD_DA_MultirateSWI
F446_MultirateSWI.cpp@2:c8aa7ae0012c, 2020-02-09 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Sun Feb 09 02:18:32 2020 +0000
- Revision:
- 2:c8aa7ae0012c
- Parent:
- 0:3e5b7187753d
3
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:3e5b7187753d | 1 | //----------------------------------------------------------- |
MikamiUitOpen | 0:3e5b7187753d | 2 | // 出力を 4 倍にアップサンプリングするクラス:高域の補正を行う場合 |
MikamiUitOpen | 0:3e5b7187753d | 3 | // Nucleo-F446RE 専用 |
MikamiUitOpen | 0:3e5b7187753d | 4 | // 補間処理で使うフィルタとして,縦続形構成の IIR フィルタを使用 |
MikamiUitOpen | 0:3e5b7187753d | 5 | // |
MikamiUitOpen | 0:3e5b7187753d | 6 | // 2018/10/29, Copyright (c) 2018 MIKAMI, Naoki |
MikamiUitOpen | 0:3e5b7187753d | 7 | //----------------------------------------------------------- |
MikamiUitOpen | 0:3e5b7187753d | 8 | |
MikamiUitOpen | 0:3e5b7187753d | 9 | #include "F446_MultirateSWI.hpp" |
MikamiUitOpen | 0:3e5b7187753d | 10 | |
MikamiUitOpen | 0:3e5b7187753d | 11 | namespace Mikami |
MikamiUitOpen | 0:3e5b7187753d | 12 | { |
MikamiUitOpen | 0:3e5b7187753d | 13 | F446_MultirateSWI::F446_MultirateSWI(int order, const Biquad hk[], float g0) |
MikamiUitOpen | 0:3e5b7187753d | 14 | : indexW_(0) |
MikamiUitOpen | 0:3e5b7187753d | 15 | { |
MikamiUitOpen | 0:3e5b7187753d | 16 | // 補間用フィルタの初期化 |
MikamiUitOpen | 0:3e5b7187753d | 17 | if (order == -1) // デフォルトの補間用フィルタを使用 |
MikamiUitOpen | 0:3e5b7187753d | 18 | interpolator_ = new IirCascade(8, HK_, G0_); |
MikamiUitOpen | 0:3e5b7187753d | 19 | else // コンストラクタの引数で与えられた係数の補間用フィルタを使用 |
MikamiUitOpen | 0:3e5b7187753d | 20 | |
MikamiUitOpen | 0:3e5b7187753d | 21 | interpolator_ = new IirCascade(order, hk, g0); |
MikamiUitOpen | 0:3e5b7187753d | 22 | |
MikamiUitOpen | 0:3e5b7187753d | 23 | // 割り込み優先順位の設定 |
MikamiUitOpen | 0:3e5b7187753d | 24 | NVIC_SetPriority(ADC_IRQn, 0); // ADC 終了割り込み:最優先 |
MikamiUitOpen | 0:3e5b7187753d | 25 | NVIC_SetPriority(EXTI4_IRQn, 1); // ソフトウェア割り込みで使用:2番目に優先 |
MikamiUitOpen | 0:3e5b7187753d | 26 | } |
MikamiUitOpen | 0:3e5b7187753d | 27 | |
MikamiUitOpen | 0:3e5b7187753d | 28 | // 標本化の実行開始 |
MikamiUitOpen | 0:3e5b7187753d | 29 | void F446_MultirateSWI::Start(int frequency, void (*Func)(), PinName pin) |
MikamiUitOpen | 0:3e5b7187753d | 30 | { |
MikamiUitOpen | 0:3e5b7187753d | 31 | adc_ = new AdcF446(frequency*FACTOR_, pin); // AD変換器の初期化 |
MikamiUitOpen | 0:3e5b7187753d | 32 | wait_us(1000); // ある程度の待ち時間が必要 |
MikamiUitOpen | 0:3e5b7187753d | 33 | adc_->SetIntrVec(&F446_MultirateSWI::AdcIsr); // ISR の設定 |
MikamiUitOpen | 0:3e5b7187753d | 34 | |
MikamiUitOpen | 0:3e5b7187753d | 35 | // EXTI4 によるソフトウェア割り込みに対応する設定 |
MikamiUitOpen | 0:3e5b7187753d | 36 | NVIC_SetVector(EXTI4_IRQn, (uint32_t)Func); |
MikamiUitOpen | 0:3e5b7187753d | 37 | NVIC_EnableIRQ(EXTI4_IRQn); |
MikamiUitOpen | 0:3e5b7187753d | 38 | } |
MikamiUitOpen | 0:3e5b7187753d | 39 | |
MikamiUitOpen | 0:3e5b7187753d | 40 | // 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む |
MikamiUitOpen | 0:3e5b7187753d | 41 | void F446_MultirateSWI::Output(float yn) |
MikamiUitOpen | 0:3e5b7187753d | 42 | { |
MikamiUitOpen | 0:3e5b7187753d | 43 | for (int n=0; n<FACTOR_; n++) |
MikamiUitOpen | 0:3e5b7187753d | 44 | { |
MikamiUitOpen | 0:3e5b7187753d | 45 | buf_[ModCounter(indexW_)] = interpolator_->Execute(yn); |
MikamiUitOpen | 0:3e5b7187753d | 46 | yn = 0; // 2回目からは補間用フィルタの入力を 0 値とする |
MikamiUitOpen | 0:3e5b7187753d | 47 | } |
MikamiUitOpen | 0:3e5b7187753d | 48 | } |
MikamiUitOpen | 0:3e5b7187753d | 49 | |
MikamiUitOpen | 0:3e5b7187753d | 50 | // ADC 変換終了割り込みに対する割り込みサービス・ルーチン |
MikamiUitOpen | 0:3e5b7187753d | 51 | void F446_MultirateSWI::AdcIsr() |
MikamiUitOpen | 0:3e5b7187753d | 52 | { |
MikamiUitOpen | 0:3e5b7187753d | 53 | static int count = 0; |
MikamiUitOpen | 0:3e5b7187753d | 54 | |
MikamiUitOpen | 0:3e5b7187753d | 55 | xn_ = adc_->Read(); // AD変換器の値を読み込む |
MikamiUitOpen | 0:3e5b7187753d | 56 | dac_.Write(buf_[ModCounter(indexR_)]); // 出力バッファの内容を DAC へ書き込む |
MikamiUitOpen | 0:3e5b7187753d | 57 | |
MikamiUitOpen | 0:3e5b7187753d | 58 | if (count == 0) // AD変換器からの入力信号は4回に1回使う |
MikamiUitOpen | 0:3e5b7187753d | 59 | NVIC->STIR |= EXTI4_IRQn; // ソフトウェア割り込み発生 |
MikamiUitOpen | 0:3e5b7187753d | 60 | count = ++count & MASK_FACTOR_; // 出力時に4倍にアップサンプリングするので, |
MikamiUitOpen | 0:3e5b7187753d | 61 | // 入力を4回に1回行うための処理 |
MikamiUitOpen | 0:3e5b7187753d | 62 | } |
MikamiUitOpen | 0:3e5b7187753d | 63 | |
MikamiUitOpen | 0:3e5b7187753d | 64 | // static メンバの実体の宣言/初期化 |
MikamiUitOpen | 0:3e5b7187753d | 65 | AdcF446 *F446_MultirateSWI::adc_; |
MikamiUitOpen | 0:3e5b7187753d | 66 | DacF446 F446_MultirateSWI::dac_; |
MikamiUitOpen | 0:3e5b7187753d | 67 | Array<float> F446_MultirateSWI::buf_(2*FACTOR_, 0.0f); |
MikamiUitOpen | 0:3e5b7187753d | 68 | int F446_MultirateSWI::indexR_ = FACTOR_; |
MikamiUitOpen | 0:3e5b7187753d | 69 | float F446_MultirateSWI::xn_; |
MikamiUitOpen | 0:3e5b7187753d | 70 | |
MikamiUitOpen | 0:3e5b7187753d | 71 | // 補間用フィルタの係数(AD 変換器の標本化周波数は 10 kHz を想定している) |
MikamiUitOpen | 0:3e5b7187753d | 72 | // |
MikamiUitOpen | 0:3e5b7187753d | 73 | // 補間用フィルタ全体は biquad フィルタ4段とする. |
MikamiUitOpen | 0:3e5b7187753d | 74 | // 最初の3段は 6 次の LPF を使用し,最後の1段は,外付けの 1 次のアナログフィル |
MikamiUitOpen | 0:3e5b7187753d | 75 | // タによる,高域の低下分を補正するための 2 次の LPF を使用. |
MikamiUitOpen | 0:3e5b7187753d | 76 | // 利得定数は,両者の利得定数の積に sqrt(2) を乗算した.これは 2 次のフィルタの |
MikamiUitOpen | 0:3e5b7187753d | 77 | // 利得の最大値が 1 倍のため,この利得の最大値を sqrt(2) 倍にするため |
MikamiUitOpen | 0:3e5b7187753d | 78 | //-------------------------------- |
MikamiUitOpen | 0:3e5b7187753d | 79 | // 1 ~ 3 段目 |
MikamiUitOpen | 0:3e5b7187753d | 80 | // 低域通過フィルタ |
MikamiUitOpen | 0:3e5b7187753d | 81 | // 連立チェビシェフ特性 |
MikamiUitOpen | 0:3e5b7187753d | 82 | // 次数 : 6 次 |
MikamiUitOpen | 0:3e5b7187753d | 83 | // 標本化周波数: 40.00 kHz |
MikamiUitOpen | 0:3e5b7187753d | 84 | // 遮断周波数 : 4.80 kHz |
MikamiUitOpen | 0:3e5b7187753d | 85 | // 通過域のリップル: 0.50 dB |
MikamiUitOpen | 0:3e5b7187753d | 86 | // 阻止域の減衰量 :35.00 dB |
MikamiUitOpen | 0:3e5b7187753d | 87 | //-------------------------------- |
MikamiUitOpen | 0:3e5b7187753d | 88 | const Biquad F446_MultirateSWI::HK_[] = { |
MikamiUitOpen | 0:3e5b7187753d | 89 | Biquad(1.370091E+00f, -5.353523E-01f, 2.500437E-01f, 1.0f), // 1段目 |
MikamiUitOpen | 0:3e5b7187753d | 90 | Biquad(1.402004E+00f, -8.228448E-01f, -1.182903E+00f, 1.0f), // 2段目 |
MikamiUitOpen | 0:3e5b7187753d | 91 | Biquad(1.426447E+00f, -9.646314E-01f, -1.362836E+00f, 1.0f), // 3段目 |
MikamiUitOpen | 0:3e5b7187753d | 92 | //-------------------------------- |
MikamiUitOpen | 0:3e5b7187753d | 93 | // 4 段目:高域補正用フィルタ |
MikamiUitOpen | 0:3e5b7187753d | 94 | // 低域通過フィルタ |
MikamiUitOpen | 0:3e5b7187753d | 95 | // 連立チェビシェフ特性 |
MikamiUitOpen | 0:3e5b7187753d | 96 | // 次数 : 2 次 |
MikamiUitOpen | 0:3e5b7187753d | 97 | // 標本化周波数: 40.00 kHz |
MikamiUitOpen | 0:3e5b7187753d | 98 | // 遮断周波数 : 5.20 kHz |
MikamiUitOpen | 0:3e5b7187753d | 99 | // 通過域のリップル: 3.00 dB |
MikamiUitOpen | 0:3e5b7187753d | 100 | // 阻止域の減衰量 : 8.00 dB |
MikamiUitOpen | 0:3e5b7187753d | 101 | //-------------------------------- |
MikamiUitOpen | 0:3e5b7187753d | 102 | Biquad(1.240986E+00f, -7.647923E-01f, -1.053681E+00f, 1.0f)}; // 4段目 |
MikamiUitOpen | 0:3e5b7187753d | 103 | // 利得定数 |
MikamiUitOpen | 0:3e5b7187753d | 104 | const float F446_MultirateSWI::G0_ = FACTOR_*3.016500E-02f*3.918621E-01f*1.41421f; |
MikamiUitOpen | 0:3e5b7187753d | 105 | } |