Cutoff frequency variable LPF, HPF, BPF, and BRF by FIR 160th-order filter.
Dependencies: UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602
main.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2015-07-25
- Revision:
- 3:24b6aa1a19ba
- Parent:
- 1:58271fae2e01
File content as of revision 3:24b6aa1a19ba:
//------------------------------------------------------------------------------ // Cutoff frequency variable LPF, HPF, BPF and BRF by FIR 160th-order filter // A0: Signal to be filtered // A2: Value which controls cutoff frequency // // 1: LPF, 3: HPF, 5: BPF, 7: BRF, even: through // 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki //------------------------------------------------------------------------------ #include "ADC_Interrupt.hpp" // for ADC using interrupt #include "DAC_MCP4921.hpp" // for DAC MCP4921, MCP4922 using namespace Mikami; #include "WindowingDesign.hpp" // for design of FIR filter // ACM1602Ni を使う場合は次の define 文をコメントにすること #define AQM1602 #ifdef AQM1602 #include "AQM1602.hpp" Aqm1602 Lcd_; #else #include "ACM1602NI.hpp" Acm1602Ni Lcd_; #endif const int FS_ = 16000; // Sampling frequency: 16 kHz ADC_Intr myAdc_(A0, FS_, A1, A2); DAC_MCP4921 myDac_; const int ORDER_ = 160; float hm_[ORDER_/2+1]; float xn_[ORDER_+1]; BusIn sws_(D2, D3, D4, D5); int sw_; WindowingDesign design_(ORDER_, FS_); uint16_t a2_ = 0; // Inputted data from A2 pin // Interrupt service routine for ADC void AdcIsr() { xn_[0] = myAdc_.Read(); // Read from A0 myAdc_.Select3rdChannel(); // Select A2 myAdc_.SoftStart(); // ADC start for A2 input //----------------------------------------- // Execute FIR filter float yn = hm_[ORDER_/2]*xn_[ORDER_/2]; for (int k=0; k<ORDER_/2; k++) yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]); for (int k=ORDER_; k>0; k--) xn_[k] = xn_[k-1]; // move input signals //----------------------------------------- if ((sw_ & 0x01) == 0) myDac_.Write(xn_[0]); // Using no filter else myDac_.Write(yn); // Using filter // Read value which controls cutoff frequency a2_ = myAdc_.ReadWait_u16(); myAdc_.Select1stChannel(); // Select A0 myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt // and enable ADC_IRQn } void printfLcdDesign(WindowingDesign::Type pb, char str[], int f1, int f2 = 0); int main() { myDac_.ScfClockTim3(670000); // cutoff frequency: 6.7 kHz sws_.mode(PullDown); // Clear buffer in FIR filter for (int n=0; n<=ORDER_; n++) xn_[n] = 0; myAdc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt float fc1 = 0; while (true) { sw_ = sws_.read(); if ((sw_ & 0x01) == 0) { printf("Through\r\n"); Lcd_.ClearLine(1); Lcd_.WriteStringXY("Through ", 0, 0); wait(0.2f); Lcd_.ClearLine(0); fc1 = 0; } else { // fc: cutoff or center frequency, 200 -- 2000 Hz float fc = 1800.0f*(a2_/4095.6f) + 200.0f; if (fabs(fc - fc1) > 10.0f) { fc1 = fc; switch (sw_) { case 1: printfLcdDesign(design_.LPF, "LPF", fc+0.5f); break; case 3: printfLcdDesign(design_.HPF, "HPF", fc+0.5f); break; case 5: printfLcdDesign(design_.BPF, "BPF", fc-100, fc+100); break; case 7: printfLcdDesign(design_.BRF, "BRF", fc-150, fc+150); break; } } } wait(0.1f); } } void printfLcdDesign(WindowingDesign::Type pb, char str[], int f1, int f2) { printf(((string)str+"\r\n").c_str()); Lcd_.WriteStringXY(str, 0, 0); char strFc[17]; if (f2 == 0) { printf("fc = %4d Hz\r\n", f1); sprintf(strFc, "fc: %4d Hz", f1); } else { printf("fc = %4d, %4d Hz\r\n", f1, f2); sprintf(strFc, "fc: %4d,%4d Hz", f1, f2); } Lcd_.WriteStringXY(strFc, 0, 1); design_.Design(ORDER_, pb, f1, f2, hm_); }