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.

Dependencies:   Array_Matrix

Dependents:   F446_UpSampling_LPF_HPF_Variable Demo_F446_AD_DA_MultirateSWI

Committer:
MikamiUitOpen
Date:
Sun Feb 09 02:18:32 2020 +0000
Revision:
2:c8aa7ae0012c
Parent:
0:3e5b7187753d
3

Who changed what in which revision?

UserRevisionLine numberNew 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 }