不韋 呂 / Mbed 2 deprecated UIT2_VariableFIR

Dependencies:   UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //------------------------------------------------------------------------------
00002 // Cutoff frequency variable LPF, HPF, BPF and BRF by FIR 160th-order filter
00003 //      A0: Signal to be filtered
00004 //      A2: Value which controls cutoff frequency
00005 //
00006 //      1: LPF, 3: HPF, 5: BPF, 7: BRF, even: through
00007 // 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
00008 //------------------------------------------------------------------------------
00009 
00010 #include "ADC_Interrupt.hpp"    // for ADC using interrupt
00011 #include "DAC_MCP4921.hpp"      // for DAC MCP4921, MCP4922
00012 using namespace Mikami;
00013 
00014 #include "WindowingDesign.hpp"  // for design of FIR filter
00015 
00016 // ACM1602Ni を使う場合は次の define 文をコメントにすること
00017 #define AQM1602
00018 
00019 #ifdef AQM1602
00020 #include "AQM1602.hpp"
00021 Aqm1602 Lcd_;
00022 #else
00023 #include "ACM1602NI.hpp"
00024 Acm1602Ni Lcd_;
00025 #endif
00026 
00027 const int FS_ = 16000;          // Sampling frequency: 16 kHz
00028 ADC_Intr myAdc_(A0, FS_, A1, A2);
00029 DAC_MCP4921 myDac_;
00030 
00031 const int ORDER_ = 160;
00032 float hm_[ORDER_/2+1];
00033 float xn_[ORDER_+1];
00034 
00035 BusIn sws_(D2, D3, D4, D5);
00036 int sw_;
00037 WindowingDesign design_(ORDER_, FS_);
00038 
00039 uint16_t a2_ = 0;   // Inputted data from A2 pin
00040 
00041 // Interrupt service routine for ADC
00042 void AdcIsr()
00043 {   
00044     xn_[0] = myAdc_.Read();     // Read from A0
00045 
00046     myAdc_.Select3rdChannel();  // Select A2   
00047     myAdc_.SoftStart();         // ADC start for A2 input
00048 
00049     //-----------------------------------------
00050     // Execute FIR filter
00051         float yn = hm_[ORDER_/2]*xn_[ORDER_/2];
00052         for (int k=0; k<ORDER_/2; k++)
00053             yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]);
00054 
00055         for (int k=ORDER_; k>0; k--)
00056             xn_[k] = xn_[k-1];  // move input signals
00057     //-----------------------------------------
00058 
00059     if ((sw_ & 0x01) == 0)
00060         myDac_.Write(xn_[0]);    // Using no filter
00061     else
00062         myDac_.Write(yn);        // Using filter
00063 
00064     // Read value which controls cutoff frequency
00065     a2_ = myAdc_.ReadWait_u16();
00066 
00067     myAdc_.Select1stChannel();      // Select A0
00068     myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
00069                                     // and enable ADC_IRQn
00070 }
00071 
00072 void printfLcdDesign(WindowingDesign::Type pb, char str[], int f1, int f2 = 0);
00073 
00074 int main()
00075 {
00076     myDac_.ScfClockTim3(670000);    // cutoff frequency: 6.7 kHz
00077     sws_.mode(PullDown);
00078 
00079     // Clear buffer in FIR filter
00080     for (int n=0; n<=ORDER_; n++)
00081         xn_[n] = 0;
00082     myAdc_.SetIntrVec(AdcIsr);  // Assign ISR for ADC interrupt
00083 
00084     float fc1 = 0;
00085     while (true)
00086     {
00087         sw_ = sws_.read();
00088         if ((sw_ & 0x01) == 0)
00089         {
00090             printf("Through\r\n");
00091             Lcd_.ClearLine(1);
00092             Lcd_.WriteStringXY("Through         ", 0, 0);
00093             wait(0.2f);
00094             Lcd_.ClearLine(0);           
00095             fc1 = 0;
00096         }
00097         else
00098         {
00099             // fc: cutoff or center frequency, 200 -- 2000 Hz
00100             float fc = 1800.0f*(a2_/4095.6f) + 200.0f;
00101 
00102             if (fabs(fc - fc1) > 10.0f)
00103             {
00104                 fc1 = fc;
00105 
00106                 switch (sw_)
00107                 {
00108                     case 1: printfLcdDesign(design_.LPF, "LPF", fc+0.5f);
00109                             break;
00110                     case 3: printfLcdDesign(design_.HPF, "HPF", fc+0.5f);
00111                             break;
00112                     case 5: printfLcdDesign(design_.BPF, "BPF", fc-100, fc+100);
00113                             break;
00114                     case 7: printfLcdDesign(design_.BRF, "BRF", fc-150, fc+150);
00115                             break;
00116                 }
00117             }
00118         }
00119         wait(0.1f);
00120     }
00121 }
00122 
00123 void printfLcdDesign(WindowingDesign::Type pb, char str[], int f1, int f2)
00124 {
00125     printf(((string)str+"\r\n").c_str());
00126     Lcd_.WriteStringXY(str, 0, 0);
00127     char strFc[17];
00128     if (f2 == 0)
00129     {
00130         printf("fc = %4d Hz\r\n", f1);
00131         sprintf(strFc, "fc: %4d Hz", f1);
00132     }
00133     else
00134     {
00135         printf("fc = %4d, %4d Hz\r\n", f1, f2);
00136         sprintf(strFc, "fc: %4d,%4d Hz", f1, f2);
00137     }
00138     Lcd_.WriteStringXY(strFc, 0, 1);
00139 
00140     design_.Design(ORDER_, pb, f1, f2, hm_);
00141 }