Cutoff frequency variable LPF and HPF by IIR 6th-order Butterworth filter for ST Nucleo F401RE.

Dependencies:   UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 UIT_IIR_Filter mbed

Committer:
MikamiUitOpen
Date:
Fri Sep 11 09:54:45 2015 +0000
Revision:
0:33908268d9ea
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:33908268d9ea 1 //------------------------------------------------------------------------------
MikamiUitOpen 0:33908268d9ea 2 // Design of Butterworth LPF and HPF using bilinear transform
MikamiUitOpen 0:33908268d9ea 3 //
MikamiUitOpen 0:33908268d9ea 4 // 2014/06/29, Copyright (c) 2014 MIKAMI, Naoki
MikamiUitOpen 0:33908268d9ea 5 //------------------------------------------------------------------------------
MikamiUitOpen 0:33908268d9ea 6
MikamiUitOpen 0:33908268d9ea 7 #include "BilinearDesignLH.hpp"
MikamiUitOpen 0:33908268d9ea 8
MikamiUitOpen 0:33908268d9ea 9 namespace Mikami
MikamiUitOpen 0:33908268d9ea 10 {
MikamiUitOpen 0:33908268d9ea 11 // Execute design
MikamiUitOpen 0:33908268d9ea 12 // input
MikamiUitOpen 0:33908268d9ea 13 // fc: Cutoff frequency
MikamiUitOpen 0:33908268d9ea 14 // output
MikamiUitOpen 0:33908268d9ea 15 // c : Coefficients for cascade structure
MikamiUitOpen 0:33908268d9ea 16 // g : Gain factor for cascade structure
MikamiUitOpen 0:33908268d9ea 17 void BilinearDesign::Execute(float fc, Coefs c[], float& g)
MikamiUitOpen 0:33908268d9ea 18 {
MikamiUitOpen 0:33908268d9ea 19 Butterworth();
MikamiUitOpen 0:33908268d9ea 20 Bilinear(fc);
MikamiUitOpen 0:33908268d9ea 21 ToCascade();
MikamiUitOpen 0:33908268d9ea 22 GetGain();
MikamiUitOpen 0:33908268d9ea 23 GetCoefs(c, g);
MikamiUitOpen 0:33908268d9ea 24 }
MikamiUitOpen 0:33908268d9ea 25
MikamiUitOpen 0:33908268d9ea 26 // Get poles for Butterworth characteristics
MikamiUitOpen 0:33908268d9ea 27 void BilinearDesign::Butterworth()
MikamiUitOpen 0:33908268d9ea 28 {
MikamiUitOpen 0:33908268d9ea 29 float pi_2order = PI_/(2.0f*ORDER_);
MikamiUitOpen 0:33908268d9ea 30 for (int j=0; j<ORDER_/2; j++) // Pole with imaginary part >= 0
MikamiUitOpen 0:33908268d9ea 31 {
MikamiUitOpen 0:33908268d9ea 32 float theta = (2.0f*j + 1.0f)*pi_2order;
MikamiUitOpen 0:33908268d9ea 33 sP_[j] = Complex(-cosf(theta), sinf(theta));
MikamiUitOpen 0:33908268d9ea 34 }
MikamiUitOpen 0:33908268d9ea 35 }
MikamiUitOpen 0:33908268d9ea 36
MikamiUitOpen 0:33908268d9ea 37 // Bilinear transform
MikamiUitOpen 0:33908268d9ea 38 // fc: Cutoff frequency
MikamiUitOpen 0:33908268d9ea 39 void BilinearDesign::Bilinear(float fc)
MikamiUitOpen 0:33908268d9ea 40 {
MikamiUitOpen 0:33908268d9ea 41 float wc = tanf(fc*PI_FS_);
MikamiUitOpen 0:33908268d9ea 42 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 0:33908268d9ea 43 zP_[k] = (1.0f + wc*sP_[k])/(1.0f - wc*sP_[k]);
MikamiUitOpen 0:33908268d9ea 44 }
MikamiUitOpen 0:33908268d9ea 45
MikamiUitOpen 0:33908268d9ea 46 // Convert to coefficients for cascade structure
MikamiUitOpen 0:33908268d9ea 47 void BilinearDesign::ToCascade()
MikamiUitOpen 0:33908268d9ea 48 {
MikamiUitOpen 0:33908268d9ea 49 for (int j=0; j<ORDER_/2; j++)
MikamiUitOpen 0:33908268d9ea 50 {
MikamiUitOpen 0:33908268d9ea 51 ck_[j].a1 = 2.0f*real(zP_[j]); // a1m
MikamiUitOpen 0:33908268d9ea 52 ck_[j].a2 = -norm(zP_[j]); // a2m
MikamiUitOpen 0:33908268d9ea 53 ck_[j].b1 = (PB_ == LPF) ? 2.0f : -2.0f; // b1m
MikamiUitOpen 0:33908268d9ea 54 }
MikamiUitOpen 0:33908268d9ea 55 }
MikamiUitOpen 0:33908268d9ea 56
MikamiUitOpen 0:33908268d9ea 57 // Calculate gain factor
MikamiUitOpen 0:33908268d9ea 58 void BilinearDesign::GetGain(){
MikamiUitOpen 0:33908268d9ea 59 float u = (PB_ == LPF) ? 1.0f : -1.0f;
MikamiUitOpen 0:33908268d9ea 60 float g0 = 1.0f;
MikamiUitOpen 0:33908268d9ea 61 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 0:33908268d9ea 62 g0 = g0*(1.0f - (ck_[k].a1 + ck_[k].a2*u)*u)/
MikamiUitOpen 0:33908268d9ea 63 (1.0f + (ck_[k].b1 + u)*u);
MikamiUitOpen 0:33908268d9ea 64 gain_ = g0;
MikamiUitOpen 0:33908268d9ea 65 }
MikamiUitOpen 0:33908268d9ea 66
MikamiUitOpen 0:33908268d9ea 67 // Get coefficients
MikamiUitOpen 0:33908268d9ea 68 void BilinearDesign::GetCoefs(Coefs c[], float& gain)
MikamiUitOpen 0:33908268d9ea 69 {
MikamiUitOpen 0:33908268d9ea 70 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 0:33908268d9ea 71 {
MikamiUitOpen 0:33908268d9ea 72 c[k].a1 = ck_[k].a1;
MikamiUitOpen 0:33908268d9ea 73 c[k].a2 = ck_[k].a2;
MikamiUitOpen 0:33908268d9ea 74 c[k].b1 = ck_[k].b1;
MikamiUitOpen 0:33908268d9ea 75 }
MikamiUitOpen 0:33908268d9ea 76 gain = gain_;
MikamiUitOpen 0:33908268d9ea 77 }
MikamiUitOpen 0:33908268d9ea 78 }
MikamiUitOpen 0:33908268d9ea 79
MikamiUitOpen 0:33908268d9ea 80
MikamiUitOpen 0:33908268d9ea 81