【发布时间】:2014-05-11 01:00:34
【问题描述】:
我正在尝试在 C 中为 FRDMKL25Z 板实现 IIR 滤波器。我当前的代码如下所示:
#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 */
}
}
部分代码细节:
- 我正在使用飞思卡尔的 Processor Expert (PE) 对嵌入式板进行编程;
- 使用 MATLAB 生成的 IIR 滤波器系数;
- 由于设备需要实时过滤数据,我从
ADC 过滤后直接输出到 DAC;
一旦闪存到板上,我就无法从 DAC 端口获得任何输出。
我对所有建议和调试方法持开放态度。
【问题讨论】:
-
(ADCvalue/65535)
-
实际上为什么要这样做呢?根本不需要在电压之间进行线性缩放,只需保持原样
-
它看起来你的过滤器也没有通过 DC(不仅仅是 DC 的 0dB,而是 -infinity [实际上就像 -40])。但是您输入了一个无符号值,这意味着您正在处理的信号可能具有您正在接收的大直流分量。更糟糕的是,即使过滤后的信号几乎肯定会具有负值,您也会输出另一个无符号信号。那里出了点问题,但我没有足够的信息来找出正确的做法是
-
你用整数除以 16 位值除以 65536。正如史蒂夫注意到的那样,结果为零。
-
在 48MHz Cortex-M0 上使用双精度浮点将是处理器密集型的。您应该使用定点算法,最好使用 16 位或 32 位。即使使用单精度也会让您获得更好的性能,而保真度可能不会有明显损失。您还可以通过使用 DMA 捕获样本块并处理整个块而不是按样本处理来提高性能。
标签: c embedded digital-filter