I am trying to implement an IIR filter in C for the FRDMKL25Z board. My current code is shown below:
#include "Cpu.h"
#include "Events.h"
#include "ADC_1.h"
#include "AdcLdd1.h"
#include "DAC_1.h"
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#define NSP 16
static uint16_t DACvalue, ADCvalue;
static LDD_TError Error;
static LDD_TDeviceData *MyDacPtr;
int N=10; // Filter order
double NumCoeff[11]={0.8017, -8.0174, 36.0785, -96.2094, 168.3664, -202.0397,
168.3664, -96.2094, 36.0785, -8.0174, 0.8017};
double DenomCoeff[11]={1.0000, -9.5582, 41.1210, -104.8588, 175.5143, -201.4924,
160.6706 , -87.8720, 31.5447, -6.7119, 0.6428};
double Signal[NSP], FilteredSignal[NSP];
int main(void)
{
/* Write your local variable definition here */
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
int j, k;
double y, Reg[NSP];
PE_low_level_init();
MyDacPtr = DAC_1_Init(NULL);
for(j=0; j<NSP; j++) Reg[j] = 0.0; // Init the delay registers
for(;;){
for(j=0;j<NSP;j++)
{
for(k=N; k>0; k--) Reg[k] = Reg[k-1]; // Shift the delay register values.
(void)ADC_1_Measure(TRUE); /* do conversion and wait for the result */
(void)ADC_1_GetValue16(&ADCvalue); /* get the result into value variable */
Signal[j]=(ADCvalue/65535)*3.5; /*Convert to volts*/
Reg[0] = Signal[j]; // The denominator
for(k=1; k<=N; k++) Reg[0] -= DenomCoeff[k] * Reg[k];
y = 0; // The numerator
for(k=0; k<=N; k++)y += NumCoeff[k] * Reg[k];
FilteredSignal[j] = y;
DACvalue=(FilteredSignal[j]*65535)*3.5; //Convert back to 16 bit
Error = DAC_1_SetValue(MyDacPtr, DACvalue); /* Set DA converter output */
}
}
Some details of the code:
ADC and filter it through then outputting it to the DAC right after the process;
Once flashed to the board, I get no output from the DAC port whatsoever.
I am open to all suggestions and debugging methods.
Here's what you done wrong
y(n-1)... y(n-k)
terms to the other side of the equal sign, leaving only the filter output on one side)Here's my suggestion, while trying to keep the same code structure...
unsigned int ADCvalue,
int Reg[NSP]; // use signed values instead of unsigned, and no need for double for history of ADCvalue
for(j=0; j<NSP; j++) Reg[j] = 0; // Init the delayed input registers
for(j=0; j<NSP; j++) FilteredSignal[j] = 0.0; // Init the delayed output registers
for(;;)
{
for(k=N; k>0; k--) Reg[k] = Reg[k-1]; // Shift the delay register values.
for(k=N; k>0; k--) FilteredSignal[k] = FilteredSignal[k-1];
(void)ADC_1_Measure(TRUE); /* do conversion and wait for the result */
(void)ADC_1_GetValue16(&ADCvalue); /* get the result into value variable */
Reg[0] = ADCvalue - 0x8000; // Save the previous inputs samples (and shift the zero value to 0)
y = 0;
for(k=0; k<=N; k++) y += NumCoeff[k] * Reg[k]; // The numerator
for(k=1; k<=N; k++) y -= DenomCoeff[k] * FilteredSignal[k]; // The denominator
FilteredSignal[0] = y/DenomCoeff[0];
DACvalue= FilteredSignal[0] + 0x8000; // shift the zero value back to unsigned, centered at 0x8000
Error = DAC_1_SetValue(MyDacPtr, DACvalue); /* Set DA converter output */
}