/* Program IIR.C */ /* This is an all C implementation of a 6-th order bandpass IIR */ /* filter based on an elliptic prototype with a passband of 500 to */ /* 1250 Hz and stop bands of 0-200 and 1750-2000 Hz. The passband */ /* ripple was chosen to be 0.3 dB and stopband attenuation to be */ /* 40 dB. A 4 kHz sampling rate is used. C:\DIGFIL\IIR\IIR.EXE was */ /* used to generate the filter coefficients. The filter is */ /* implemented as the cascade of three biquad sections. */ /* Provided by Professor Gansman at the University of Maryland */ /*========================================================================*/ /* These header files can be found in C:\UTIL.DSP */ /*========================================================================*/ #include "bus.h" #include "serial.h" #include "timers.h" /*#include "aic.h" /* MACROS and STRUCTURES for AIC */ /*========================================================================*/ /*========================================================================*/ /* Standard header files used for various tasks in the program */ /*========================================================================*/ #include #include #include #include /*========================================================================*/ /* Defines to setup global constants */ /*========================================================================*/ #define PI 3.14159 #define SAMPLING_FREQUENCY 8000.0 #define SCALING_FACTOR 10.0 #define NFIR 10 /* FIR filter size */ /*========================================================================*/ /* Proto-types of Procedures */ /*========================================================================*/ void init_c30bus(void); void init_aic(void); /*========================================================================*/ /* This is the main function. */ /*========================================================================*/ void main(void) { /* State variables for the 3 biquad sections. s[k][0] used for */ /* intermediate calculations. */ float s[3][3] = { {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0} }; /* Denominator coefficients for the 3 biquad sections. The first */ /* column of 1.0's is included to make indexing correspond to block */ /* diagrams of type 1 direct form sections. */ float a[3][3] = { {1.0, -.312065, -1.298487}, {1.0, .730459, .706656}, {1.0, -1.298487, .770969} }; /* Numerator coefficients for the 3 biquad sections. The first column */ /* of 1.0's is included to make indexing easy. */ float b[3][3] = { {1.0, .000000, -1.000000}, {1.0, -1.923943, 1.000000}, {1.0, 1.807937, 1.000000} }; /* Overall scale factor for unity gain */ float scale = .10739946612456; float y; int iy = 0, k; gie_clear(); /* In C:\UTIL.DSP\BUS.LIB. Disable */ /* interrupts by clearing GIE bit. */ clear_ints(); /* In C:\UTIL.DSP\BUS.LIB. Clear all flags*/ /* in interrupt flag (IF) register. */ init_c30bus(); /* Set 0 bus wait states and enable cache. */ init_aic(); /* Set up Timer 0, initialize Serial Port */ /* 0, start AIC and set its parameters */ for(;;){ p0_xmit(iy); /* Send out filtered sample on XRDY true */ y = p0_receive()<<16>>18; /* Get input sample and adjust it */ /* Now do the three biquad filter sections. */ for(k=0; k<3; k++){ s[k][0] = y - a[k][1]*s[k][1] - a[k][2]*s[k][2]; /* Compute section output */ y = s[k][0] + b[k][1]*s[k][1] + b[k][2]*s[k][2]; /* Update section state variables */ s[k][2] = s[k][1]; s[k][1] = s[k][0]; } iy = y*scale; /* Scale output and convert to int */ iy <<=2; /* Shift up to make 2 lsb's zero for AIC */ } }