java实现irr滤波器,C语言中的IIR滤波器实现

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

for(;;){

for(j=0;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:

I'm using Processor Expert (PE) from freescale to program the embedded board;

IIR filters coefficient generated using MATLAB;

As the device needs to filter data in real time I take the minimum required data from the

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

you need to also keep track of previous outputs

maybe you were trying to, but the funny nested loop wasn't working

The denominator is applied to the outputs, not the inputs

The denominator is not really the denominator when you apply the coefficients; it's only called that because the frequency response works like a denominator. The denominator coefficients are multiplied to the history of outputs and their sum is subtracted from the output. (think of moving all the y(n-1)... y(n-k) terms to the other side of the equal sign, leaving only the filter output on one side)

The funny denominator coefficient is the that first one, it is multiplied by the new output you're actually trying to calculate! You will divide your whole result by that one to find out what the new output will be. (in most IIR filters this is 1.0, so you can skip this).

16 bit Integer divide by 65535 is zero!, and no need to convert to volts (as others have mentioned).

Only do engineering only at the end, and only if you need to; you don't

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

for(j=0; j

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 */

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值