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

Dependencies:   UIT_IIR_Filter UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602

Committer:
MikamiUitOpen
Date:
Fri Sep 11 09:52:06 2015 +0000
Revision:
7:34eced3597bb
Parent:
5:b291c4653eb9
8

Who changed what in which revision?

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