不韋 呂 / Mbed 2 deprecated UIT2_VariableFIR_LPF

Dependencies:   UIT_ACM1602NI UIT_ADDA mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //------------------------------------------------------------------
00002 // Cutoff frequency variable LPF by FIR 160th-order filter
00003 //      A0: Signal to be filtered
00004 //      A2: Value which controls cutoff frequency
00005 //
00006 // 2014/12/08, Copyright (c) 2014 MIKAMI, Naoki
00007 //------------------------------------------------------------------
00008 
00009 #include "mbed.h"
00010 
00011 #include "ADC_Interrupt.hpp"    // for ADC using interrupt
00012 #include "DAC_MCP4922.hpp"      // for DAC MCP4922
00013 #include "ACM1602NI.hpp"        // for LCD display
00014 
00015 #include "WindowingDesignLH.hpp"    // for design of FIR filter
00016 
00017 using namespace Mikami;
00018 
00019 const int FS_ = 16000;          // Sampling frequency: 16 kHz
00020 ADC_Intr myAdc_(A0, FS_, A1, A2);
00021 DAC_MCP4922 myDac_;
00022 
00023 const int ORDER_ = 160;
00024 float hm_[ORDER_/2+1];
00025 float xn_[ORDER_+1];
00026 
00027 DigitalIn sw1_(D2, PullDown);   // 0: disable filter
00028                                 // 1: enable filter
00029 WindowingDesign design_(ORDER_, FS_);
00030 DigitalOut dOut_(D7);
00031 
00032 uint16_t a2_ = 0;   // Inputted data from A2 pin
00033 
00034 // Interrupt service routine for ADC
00035 void AdcIsr()
00036 {   
00037     dOut_.write(1);
00038     xn_[0] = myAdc_.Read();   // Read from A0
00039 
00040     myAdc_.Select3rdChannel();  // Select A2   
00041     myAdc_.SoftStart();         // ADC start for A2 input
00042 
00043     //-----------------------------------------
00044     // Execute FIR filter
00045         float yn = hm_[ORDER_/2]*xn_[ORDER_/2];
00046         for (int k=0; k<ORDER_/2; k++)
00047             yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]);
00048 
00049         for (int k=ORDER_; k>0; k--)
00050             xn_[k] = xn_[k-1];  // move input signals
00051     //-----------------------------------------
00052 
00053     if (sw1_ == 0) myDac_.Write(xn_[0]);    // Using no filter
00054     else           myDac_.Write(yn);        // Using filter
00055 
00056     // Read value which controls cutoff frequency
00057     a2_ = myAdc_.ReadWait_u16();
00058 
00059     myAdc_.Select1stChannel();      // Select A0
00060     myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
00061                                     // and enable ADC_IRQn
00062     dOut_.write(0);
00063 }
00064 
00065 int main()
00066 {
00067     myDac_.ScfClockTim3(670000);    // cutoff frequency: 6.7 kHz
00068 
00069     WindowingDesign lpfDsgn(ORDER_, FS_);
00070     Acm1602Ni lcd;  // objetc for display using LCD
00071 
00072     // Clear buffer in FIR filter
00073     for (int n=0; n<=ORDER_; n++)
00074         xn_[n] = 0;
00075     myAdc_.SetIntrVec(AdcIsr);  // Assign ISR for ADC interrupt
00076 
00077     float fc1 = 0;
00078     while (true)
00079     {
00080         // fc: cutoff frequency, 100 -- 2000 Hz
00081         float fc = 1900.0f*(a2_/4095.6f) + 100.0f;
00082 
00083         if (sw1_ == 0)
00084         {
00085             printf("Through\r\n");
00086             lcd.WriteStringXY("Through         ", 0, 0);
00087             wait(0.2f);
00088             lcd.ClearLine(0);           
00089             fc1 = 0;
00090         }
00091         else
00092         {
00093             if (fabs(fc - fc1) > 10.0f)
00094             {
00095                 printf("fc = %4d\r\n", int(fc+0.5f));
00096                 char str[18];
00097                 sprintf(str, "fc = %4d Hz", int(fc+0.5f));
00098                 lcd.WriteStringXY(str, 0, 0);
00099                 fc1 = fc;
00100                 // Design new coefficients based on new fc
00101                 design_.Design(ORDER_, WindowingDesign::LPF, fc1, hm_);
00102             }
00103         }
00104         wait(0.1f);
00105     }
00106 }
00107