我正在设计一个IIR二阶低通滤波器,采样频率= 100Hz,截止频率= 10 Hz。滤波器系数是在Matlab中使用fdatool的Chebyshev Type I。 但是代码不能过滤信号(即,对于所有频率,它给出的输出具有与输入信号相同的幅度)。对于10KHz及以上的输入信号,仅观察到幅度的轻微下降。我保证ADC和DAC工作正常,因为我测试了FFT滤波器。
以下是代码:
/* Include core modules */
#include "stm32f4xx.h"
#include "stdint.h"
#include "stdlib.h"
#include "arm_math.h"
#include "my_files.h"
#define URS 2
#define numStages 1
#define NUM_TAPS 5*numStages
#define samples 3
////////ADC FUNCTION//////////////////
void ADC_configure(void)
{
RCC->APB2ENR|=1Ul<<8; // ADC1 clock enabled
ADC1->CR2|=0x00000001; // enable ADC
ADC1->CR1|=0; // single conversion ADC1 pin 0 has been selected
}
int32_t readADC(void)
{
ADC1->CR2|=(1UL<<30);
return(ADC1->DR);
}
////////DAC FUNCTION/////////////////
int32_t dv1,dv2,ds;
//---function declaration--//
// initilising DAC---------//
void DAC_init(void)
{
RCC->APB1ENR|=1UL<<29;
DAC->CR|=((1UL<<16)|(1UL<<0));
RCC->AHB1ENR|=0x00000001; // clock to gpio A
GPIOA->MODER|=0x00000F03; // pt0,4,5 in Analog mode
}
// Sending to DAC...........//
void Send_DAC(int32_t data_in1, int32_t data_in2)
{ dv1=data_in1;
dv2=data_in2<<16;
ds=dv2+dv1;
DAC->DHR12RD=ds;
}
/* IIR settings */
float32_t pState[2*numStages];
const float pCoeffs[NUM_TAPS] = {1,2,1,-1.1997,0.5157};//{b0,b1,b2,a1,a2}
/* Global variables */
float32_t Input[samples]; /* Data to be read from ADC */
float32_t InputData[samples]; /* Data to be processed */
float32_t Output[samples]; /* Output filtered Data */
arm_biquad_cascade_df2T_instance_f32 S; /* ARM IIR module */
uint16_t i;
void TIM3_Init (void) {
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; /* enable clock for TIM1 */
TIM3->PSC = 8600; /* set prescaler = 10KHz */
TIM3->ARR = 100; /* set auto-reload = 10ms */
TIM3->RCR = 0; /* set repetition counter */
TIM3->CR1 |= (1UL << URS);
TIM3->DIER = TIM_DIER_UIE; /* Update Interrupt enable */
NVIC_EnableIRQ(TIM3_IRQn); /* TIM1 Interrupt enable */
NVIC_SetPriority (TIM3_IRQn, 0);
TIM3->CR1 |= TIM_CR1_CEN; /* timer enable */
}
void TIM3_IRQHandler() {
/*Shift Operation*/
for(i=samples-1;i>0;i--){
Input[i]= Input[i-1];
InputData[i]= Input[i];
}
/* Input part from the ADC */
Input[0] = (float32_t)readADC();
InputData[0] = Input[0];
//////////IIR//////////////////////
/* Initialize the IIR module */
arm_biquad_cascade_df2T_init_f32(&S, numStages, pCoeffs, pState);
/* Process the data through the IIR module */
arm_biquad_cascade_df2T_f32(&S, InputData, Output, samples);
////////DAC Output/////////////////
Send_DAC(Input[0], Output[0]);
}
/////////main function///////////////
int main(void) {
/* Initialize system */
SystemInit();
DAC_init();
ADC_configure();
TIM3_Init();
while (1) {
}
}
任何建议或解决方案都会有很大的帮助。
答案 0 :(得分:1)
一些可能的问题:
好的,你不要使用stdlib进行更多的初始化,顺便说一句。但你真的应该使用符号常量进行寄存器初始化!这不需要额外费用。
不直接相关,但会(!)给出错误的结果:如果我做对了,你会在readADC中触发每次转换。这会导致抖动(导致数字化信号产生噪声);通过定时器触发对话(触发系统实际上是什么)并使用ADC中断读取数据或使用DMA(STM DMA提供双缓冲模式,这是完美的) 。在这个简单的例子中,如果使用DMA,你甚至可以完全没有中断地相处并在主程序中进行计算。
对于DAC你也应该这样。
不知道为什么还要使用计时器; ADC可以自触发。这还不够吗?
答案 1 :(得分:0)
每次都不需要初始化IIR过滤器。在init代码中只执行一次。 Init过程清除pState中的先前值,但它们是IIR正确执行所必需的。这就是你的过滤器不起作用的原因。 FPU的存在只会影响计算速度。