Nucleo-F446 による遮断周波数可変 LPF/HPF .DA変換器にデータを送る際は 4 倍にアップ・サンプリング.

Dependencies:   mbed SerialTxRxIntr F446_AD_DA_MultirateSWI

Committer:
MikamiUitOpen
Date:
Tue Jun 05 11:20:57 2018 +0000
Revision:
0:89d173001e82
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:89d173001e82 1 //------------------------------------------------------------------------
MikamiUitOpen 0:89d173001e82 2 // 双一次z変換によるバタワースフィルタの設計
MikamiUitOpen 0:89d173001e82 3 // LPF, HPF のみ
MikamiUitOpen 0:89d173001e82 4 //
MikamiUitOpen 0:89d173001e82 5 // 2018/05/14, Copyright (c) 2018 MIKAMI, Naoki
MikamiUitOpen 0:89d173001e82 6 //------------------------------------------------------------------------
MikamiUitOpen 0:89d173001e82 7
MikamiUitOpen 0:89d173001e82 8 #include "BilinearDesignLH.hpp"
MikamiUitOpen 0:89d173001e82 9
MikamiUitOpen 0:89d173001e82 10 namespace Mikami
MikamiUitOpen 0:89d173001e82 11 {
MikamiUitOpen 0:89d173001e82 12 // 設計の実行
MikamiUitOpen 0:89d173001e82 13 // 入力
MikamiUitOpen 0:89d173001e82 14 // fc: 遮断周波数
MikamiUitOpen 0:89d173001e82 15 // pb: 通過域 (LPF or HPF)
MikamiUitOpen 0:89d173001e82 16 // output
MikamiUitOpen 0:89d173001e82 17 // c : 縦続形の Biquad 構造の係数
MikamiUitOpen 0:89d173001e82 18 // g : 利得定数
MikamiUitOpen 0:89d173001e82 19 void BilinearDesign::Execute(float fc, Type pb, Biquad::Coefs c[], float& g)
MikamiUitOpen 0:89d173001e82 20 {
MikamiUitOpen 0:89d173001e82 21 Butterworth();
MikamiUitOpen 0:89d173001e82 22 Bilinear(fc);
MikamiUitOpen 0:89d173001e82 23 ToCascade(pb);
MikamiUitOpen 0:89d173001e82 24 GetGain(pb);
MikamiUitOpen 0:89d173001e82 25 GetCoefs(c, g);
MikamiUitOpen 0:89d173001e82 26 }
MikamiUitOpen 0:89d173001e82 27
MikamiUitOpen 0:89d173001e82 28 // バタワース特性の極を取得
MikamiUitOpen 0:89d173001e82 29 void BilinearDesign::Butterworth()
MikamiUitOpen 0:89d173001e82 30 {
MikamiUitOpen 0:89d173001e82 31 float pi_2order = PI_/(2.0f*ORDER_);
MikamiUitOpen 0:89d173001e82 32 for (int j=0; j<ORDER_/2; j++) // 虚部 >= 0 である極を求める
MikamiUitOpen 0:89d173001e82 33 {
MikamiUitOpen 0:89d173001e82 34 float theta = (2.0f*j + 1.0f)*pi_2order;
MikamiUitOpen 0:89d173001e82 35 sP_[j] = Complex(-cosf(theta), sinf(theta));
MikamiUitOpen 0:89d173001e82 36 }
MikamiUitOpen 0:89d173001e82 37 }
MikamiUitOpen 0:89d173001e82 38
MikamiUitOpen 0:89d173001e82 39 // 双一次z変換
MikamiUitOpen 0:89d173001e82 40 // fc: 遮断周波数
MikamiUitOpen 0:89d173001e82 41 void BilinearDesign::Bilinear(float fc)
MikamiUitOpen 0:89d173001e82 42 {
MikamiUitOpen 0:89d173001e82 43 float wc = tanf(fc*PI_FS_);
MikamiUitOpen 0:89d173001e82 44 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 0:89d173001e82 45 zP_[k] = (1.0f + wc*sP_[k])/(1.0f - wc*sP_[k]);
MikamiUitOpen 0:89d173001e82 46 }
MikamiUitOpen 0:89d173001e82 47
MikamiUitOpen 0:89d173001e82 48 // 縦続形の Biquad 構造の係数に変換
MikamiUitOpen 0:89d173001e82 49 void BilinearDesign::ToCascade(Type pb)
MikamiUitOpen 0:89d173001e82 50 {
MikamiUitOpen 0:89d173001e82 51 for (int j=0; j<ORDER_/2; j++)
MikamiUitOpen 0:89d173001e82 52 {
MikamiUitOpen 0:89d173001e82 53 ck_[j].a1 = 2.0f*real(zP_[j]); // a1m
MikamiUitOpen 0:89d173001e82 54 ck_[j].a2 = -norm(zP_[j]); // a2m
MikamiUitOpen 0:89d173001e82 55 ck_[j].b1 = (pb == LPF) ? 2.0f : -2.0f; // b1m
MikamiUitOpen 0:89d173001e82 56 ck_[j].b2 = 1.0f; // b2m
MikamiUitOpen 0:89d173001e82 57 }
MikamiUitOpen 0:89d173001e82 58 }
MikamiUitOpen 0:89d173001e82 59
MikamiUitOpen 0:89d173001e82 60 // 利得定数の計算
MikamiUitOpen 0:89d173001e82 61 void BilinearDesign::GetGain(Type pb)
MikamiUitOpen 0:89d173001e82 62 {
MikamiUitOpen 0:89d173001e82 63 float u = (pb == LPF) ? 1.0f : -1.0f; // u: inverse of z
MikamiUitOpen 0:89d173001e82 64 gain_ = 1.0f;
MikamiUitOpen 0:89d173001e82 65 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 0:89d173001e82 66 gain_ = gain_*(1.0f - (ck_[k].a1 + ck_[k].a2*u)*u)/
MikamiUitOpen 0:89d173001e82 67 (1.0f + (ck_[k].b1 + ck_[k].b2*u)*u);
MikamiUitOpen 0:89d173001e82 68 }
MikamiUitOpen 0:89d173001e82 69
MikamiUitOpen 0:89d173001e82 70 // 係数の取得
MikamiUitOpen 0:89d173001e82 71 void BilinearDesign::GetCoefs(Biquad::Coefs c[], float& gain)
MikamiUitOpen 0:89d173001e82 72 {
MikamiUitOpen 0:89d173001e82 73 for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k];
MikamiUitOpen 0:89d173001e82 74 gain = gain_;
MikamiUitOpen 0:89d173001e82 75 }
MikamiUitOpen 0:89d173001e82 76 }