Cutoff frequency variable LPF by 160th-order FIR filter designed by window method usin Hamming window for ST Nucleo F401RE.

Dependencies:   UIT_ACM1602NI UIT_ADDA mbed

Committer:
MikamiUitOpen
Date:
Mon Nov 10 02:56:27 2014 +0000
Revision:
1:24c33c8719b2
Parent:
0:b8bffbcb85fd
Child:
3:54eac4891e35
2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:b8bffbcb85fd 1 //------------------------------------------------------------------
MikamiUitOpen 1:24c33c8719b2 2 // Cutoff frequency variable LPF by FIR 160th-order filter
MikamiUitOpen 0:b8bffbcb85fd 3 // A0: Signal to be filtered
MikamiUitOpen 0:b8bffbcb85fd 4 // A2: Value which controls cutoff frequency
MikamiUitOpen 0:b8bffbcb85fd 5 //
MikamiUitOpen 0:b8bffbcb85fd 6 // 2014/11/10, Copyright (c) 2014 MIKAMI, Naoki
MikamiUitOpen 0:b8bffbcb85fd 7 //------------------------------------------------------------------
MikamiUitOpen 0:b8bffbcb85fd 8
MikamiUitOpen 0:b8bffbcb85fd 9 #include "mbed.h"
MikamiUitOpen 0:b8bffbcb85fd 10
MikamiUitOpen 0:b8bffbcb85fd 11 #include "ADC_Interrupt.hpp" // for ADC using interrupt
MikamiUitOpen 0:b8bffbcb85fd 12 #include "DAC_MCP4922.hpp" // for DAC MCP4922
MikamiUitOpen 0:b8bffbcb85fd 13 #include "ScfClockTim3.hpp" // for clock supplied to SCF
MikamiUitOpen 0:b8bffbcb85fd 14 #include "ACM1602NI.hpp" // for LCD display
MikamiUitOpen 0:b8bffbcb85fd 15
MikamiUitOpen 0:b8bffbcb85fd 16 #include "WindowingDesignLH.hpp" // for design of IIR filter
MikamiUitOpen 0:b8bffbcb85fd 17
MikamiUitOpen 0:b8bffbcb85fd 18 using namespace Mikami;
MikamiUitOpen 0:b8bffbcb85fd 19
MikamiUitOpen 0:b8bffbcb85fd 20 const int FS_ = 16000; // Sampling frequency: 16 kHz
MikamiUitOpen 0:b8bffbcb85fd 21 ADC_Intr myAdc_(A0, FS_, A1, A2);
MikamiUitOpen 0:b8bffbcb85fd 22 DAC_MCP4922 myDac_;
MikamiUitOpen 0:b8bffbcb85fd 23
MikamiUitOpen 0:b8bffbcb85fd 24 const int ORDER_ = 160;
MikamiUitOpen 0:b8bffbcb85fd 25 float hm_[ORDER_/2+1];
MikamiUitOpen 0:b8bffbcb85fd 26 float xn_[ORDER_+1];
MikamiUitOpen 0:b8bffbcb85fd 27
MikamiUitOpen 0:b8bffbcb85fd 28 DigitalIn sw1_(D2, PullDown); // 0: disable filter
MikamiUitOpen 0:b8bffbcb85fd 29 // 1: enable filter
MikamiUitOpen 0:b8bffbcb85fd 30 WindowingDesign design_(ORDER_, FS_);
MikamiUitOpen 0:b8bffbcb85fd 31 DigitalOut dOut_(D7);
MikamiUitOpen 0:b8bffbcb85fd 32
MikamiUitOpen 0:b8bffbcb85fd 33 uint16_t a2_ = 0; // Inputted data from A2 pin
MikamiUitOpen 0:b8bffbcb85fd 34
MikamiUitOpen 0:b8bffbcb85fd 35 // Interrupt service routine for ADC
MikamiUitOpen 0:b8bffbcb85fd 36 void AdcIsr()
MikamiUitOpen 0:b8bffbcb85fd 37 {
MikamiUitOpen 0:b8bffbcb85fd 38 dOut_.write(1);
MikamiUitOpen 0:b8bffbcb85fd 39 xn_[0] = myAdc_.Read(); // Read from A0
MikamiUitOpen 0:b8bffbcb85fd 40
MikamiUitOpen 0:b8bffbcb85fd 41 myAdc_.Select3rdChannel(); // Select A2
MikamiUitOpen 0:b8bffbcb85fd 42 myAdc_.SoftStart(); // ADC start for A2 input
MikamiUitOpen 0:b8bffbcb85fd 43
MikamiUitOpen 0:b8bffbcb85fd 44 //-----------------------------------------
MikamiUitOpen 0:b8bffbcb85fd 45 // Execute FIR filter
MikamiUitOpen 0:b8bffbcb85fd 46 float yn = hm_[ORDER_/2]*xn_[ORDER_/2];
MikamiUitOpen 0:b8bffbcb85fd 47 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 0:b8bffbcb85fd 48 yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]);
MikamiUitOpen 0:b8bffbcb85fd 49
MikamiUitOpen 0:b8bffbcb85fd 50 for (int k=ORDER_; k>0; k--)
MikamiUitOpen 0:b8bffbcb85fd 51 xn_[k] = xn_[k-1]; // move input signals
MikamiUitOpen 0:b8bffbcb85fd 52 //-----------------------------------------
MikamiUitOpen 0:b8bffbcb85fd 53
MikamiUitOpen 0:b8bffbcb85fd 54 if (sw1_ == 0) myDac_.Write(xn_[0]); // Using no filter
MikamiUitOpen 0:b8bffbcb85fd 55 else myDac_.Write(yn); // Using filter
MikamiUitOpen 0:b8bffbcb85fd 56
MikamiUitOpen 0:b8bffbcb85fd 57 // Read value which controls cutoff frequency
MikamiUitOpen 0:b8bffbcb85fd 58 a2_ = myAdc_.ReadWait_u16();
MikamiUitOpen 0:b8bffbcb85fd 59
MikamiUitOpen 0:b8bffbcb85fd 60 myAdc_.Select1stChannel(); // Select A0
MikamiUitOpen 0:b8bffbcb85fd 61 myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
MikamiUitOpen 0:b8bffbcb85fd 62 // and enable ADC_IRQn
MikamiUitOpen 0:b8bffbcb85fd 63 dOut_.write(0);
MikamiUitOpen 0:b8bffbcb85fd 64 }
MikamiUitOpen 0:b8bffbcb85fd 65
MikamiUitOpen 0:b8bffbcb85fd 66 int main()
MikamiUitOpen 0:b8bffbcb85fd 67 {
MikamiUitOpen 0:b8bffbcb85fd 68 ScfClockTim3(670000); // cutoff frequency: 6.7 kHz
MikamiUitOpen 0:b8bffbcb85fd 69
MikamiUitOpen 0:b8bffbcb85fd 70 WindowingDesign lpfDsgn(ORDER_, FS_);
MikamiUitOpen 0:b8bffbcb85fd 71 Acm1602Ni lcd; // objetc for display using LCD
MikamiUitOpen 0:b8bffbcb85fd 72
MikamiUitOpen 0:b8bffbcb85fd 73 // Clear buffer in FIR filter
MikamiUitOpen 0:b8bffbcb85fd 74 for (int n=0; n<=ORDER_; n++)
MikamiUitOpen 0:b8bffbcb85fd 75 xn_[n] = 0;
MikamiUitOpen 0:b8bffbcb85fd 76 myAdc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt
MikamiUitOpen 0:b8bffbcb85fd 77
MikamiUitOpen 0:b8bffbcb85fd 78 float fc1 = 0;
MikamiUitOpen 0:b8bffbcb85fd 79 while (true)
MikamiUitOpen 0:b8bffbcb85fd 80 {
MikamiUitOpen 0:b8bffbcb85fd 81 // fc: cutoff frequency, 100 -- 2000 Hz
MikamiUitOpen 0:b8bffbcb85fd 82 float fc = 1900.0f*(a2_/4095.6f) + 100.0f;
MikamiUitOpen 0:b8bffbcb85fd 83
MikamiUitOpen 0:b8bffbcb85fd 84 if (sw1_ == 0)
MikamiUitOpen 0:b8bffbcb85fd 85 {
MikamiUitOpen 0:b8bffbcb85fd 86 printf("Through\r\n");
MikamiUitOpen 0:b8bffbcb85fd 87 lcd.WriteStringXY("Through ", 0, 0);
MikamiUitOpen 0:b8bffbcb85fd 88 wait(0.2f);
MikamiUitOpen 0:b8bffbcb85fd 89 lcd.ClearLine(0);
MikamiUitOpen 0:b8bffbcb85fd 90 fc1 = 0;
MikamiUitOpen 0:b8bffbcb85fd 91 }
MikamiUitOpen 0:b8bffbcb85fd 92 else
MikamiUitOpen 0:b8bffbcb85fd 93 {
MikamiUitOpen 0:b8bffbcb85fd 94 if (fabs(fc - fc1) > 10.0f)
MikamiUitOpen 0:b8bffbcb85fd 95 {
MikamiUitOpen 0:b8bffbcb85fd 96 printf("fc = %4d\r\n", int(fc+0.5f));
MikamiUitOpen 0:b8bffbcb85fd 97 char str[18];
MikamiUitOpen 0:b8bffbcb85fd 98 sprintf(str, "fc = %4d Hz", int(fc+0.5f));
MikamiUitOpen 0:b8bffbcb85fd 99 lcd.WriteStringXY(str, 0, 0);
MikamiUitOpen 0:b8bffbcb85fd 100 fc1 = fc;
MikamiUitOpen 0:b8bffbcb85fd 101 // Design new coefficients based on new fc
MikamiUitOpen 1:24c33c8719b2 102 design_.Design(ORDER_, WindowingDesign::LPF, fc1, hm_);
MikamiUitOpen 0:b8bffbcb85fd 103 }
MikamiUitOpen 0:b8bffbcb85fd 104 }
MikamiUitOpen 0:b8bffbcb85fd 105 wait(0.1f);
MikamiUitOpen 0:b8bffbcb85fd 106 }
MikamiUitOpen 0:b8bffbcb85fd 107 }
MikamiUitOpen 0:b8bffbcb85fd 108