DSP FIR-Filter Improvements and Comments
Page last updated 01 Jul 2013, by .
0
replies
FIR Filter Improvements
/*
dsp_fir
This software uses the algorithm and code found on the mbed.org Web site at
http://mbed.org/handbook/Matlab-FIR-Filter.
I removed the code used to compare the filtered output with a calculated
1000-Hz sine wave. Someone might use this code for a demonstration, but I wanted
to examine FIR outputs for different test signals added to the 1000-Hz signal.
I place no restrictions on the use of this code.
To calculate FIR-filter coefficients, see the ScopeFIR software from Iowegian International
http://www.iowegian.com/.
Cypress Semiconductor has filter blocks for the PSoC programmable system-on-a-chip
devices. The design software--PSoC Creator--might provide FIR coefficients
http://www.cypress.com/?id=2494
Microchip Technology provides filter-design software for the dsPIC family of
microcontrollers. For more information:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en023602
You also can find FIR-filter coefficient-calculator progrograms on the Internet.
Code modifoed and commented by Jon Titus, 01 July 2013.
*/
#include "mbed.h"
#include "dsp.h"
// dsp.h links to math_helper.h, arm_math.h, FIR_f32.h, and Sine_f32.h.
// This software uses 10 blocks of 32 to simplify the floating-point-math
// operations. It uses 320 samples overall. You can "pad" the results
// with 192 0's in Excel to run a 512-point DFT in Excel.
#define BLOCK_SIZE (32)
#define NUM_BLOCKS (10)
#define TEST_LENGTH_SAMPLES (BLOCK_SIZE * NUM_BLOCKS)
// the calculation above gives you 320 samples, total
//Rate set at 48,000 samples/second
#define SAMPLE_RATE (48000)
// set up serial connection with PC so you can see filtered data values.
Serial pc(USBTX, USBRX); // tx, rx
// set up an array for the output of the filter
float32_t output[TEST_LENGTH_SAMPLES];
// set up an array for floating-point values produced by the FIR filter
unsigned short loop_count;
// FIR coefficients buffer generated using fir1() MATLAB function; 29 filter "taps"
#define NUM_TAPS 29
// These are the coefficients in floating-point format
const float32_t firCoeffs32[NUM_TAPS] = {
-0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f,
+0.0085302217f, -0.0000000000f, -0.0173976984f, -0.0341458607f, -0.0333591565f,
+0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f,
+0.2229246956f, +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f,
-0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f, +0.0080754303f,
+0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f
};
#define WARMUP (NUM_TAPS-1)
#define DELAY (WARMUP/2)
int main()
{
//Define two sine-wave characteristics for use later by Sine_f32.cpp routines
// parameters: frequency in Hz, sample rate, amplitude
Sine_f32 sine_1KHz( 1000, SAMPLE_RATE, 1.0);
Sine_f32 sine_15KHz(7500, SAMPLE_RATE, 1.0); //Note: changed to 7500 Hz!
FIR_f32<NUM_TAPS> fir(firCoeffs32);
// create buffer_a for 1000-Hz sine wave
float32_t buffer_a[BLOCK_SIZE];
// create buffer_b for second test signal. Note, set to 7500 Hz in this code.
float32_t buffer_b[BLOCK_SIZE];
// create signals one block at a time. The 1000-Hz signal gets added to second
// test signal, with summed results going into buffer_b
for (float32_t *sgn=output; sgn<(output+TEST_LENGTH_SAMPLES); sgn += BLOCK_SIZE)
{
sine_1KHz.generate(buffer_a); // Generate a 1KHz sine wave
sine_15KHz.process(buffer_a, buffer_b); // Add a test sine wave
// FIR low pass filter function with 6-kHz cutoff using coefficients above.
//Note: Measured cut-off frequency closer to 5500 Hz.
fir.process(buffer_b, sgn);
}
// Transmit filter-output data to PC, default 9600 bits/sec., 8 bits, 1 stop bit
// no parity. Use Tera Term VT emulation mode as terminal software on a PC.
for (loop_count = 0; loop_count < 319; loop_count++)
{
pc.printf("%f\n\r", output[loop_count]);
}
}
Please log in to post comments.
