gpt4 book ai didi

CMSIS FIR 带通滤波器

转载 作者:太空宇宙 更新时间:2023-11-04 00:02:12 26 4
gpt4 key购买 nike

我正在尝试在 STM32F407 微 Controller 上实现 60kHz 带通滤波器,但遇到了一些问题。我在 MATLABs fdatool 的帮助下生成了过滤器,然后也在 MATLAB 中对其进行了模拟。以下 MATLAB 脚本对其进行了模拟。

% FIR Window Bandpass filter designed using the FIR1 function.
% All frequency values are in Hz.
Fs = 5250000; % Sampling Frequency

N = 1800; % Order
Fc1 = 59950; % First Cutoff Frequency
Fc2 = 60050; % Second Cutoff Frequency
flag = 'scale'; % Sampling Flag
% Create the window vector for the design algorithm.
win = hamming(N+1);

% Calculate the coefficients using the FIR1 function.
b = fir1(N, [Fc1 Fc2]/(Fs/2), 'bandpass', win, flag);
Hd = dfilt.dffir(b);
%----------------------------------------------------------
%----------------------------------------------------------
T = 1 / Fs; % sample time
L = 4500; % Length of signal
t = (0:L-1)*T; % Time vector

% Animate the passband frequency span
for f=55500:50:63500
signal = sin(2*pi*f*t);
plot(filter(Hd, signal));
axis([0 L -1 1]);

str=sprintf('Signal frequency (Hz) %d', f);
title(str);
drawnow;
end

pause;
close all;

signal = sin(2*pi*50000*t) + sin(2*pi*60000*t) + sin(2*pi*78000*t);
signal = signal / 3;
signal = signal(1:1:4500);

filterInput = signal;
filterOutput = filter(Hd,signal);

subplot(2,1,1);
plot(filterInput);
axis([0 4500 -1 1]);

subplot(2,1,2);
plot(filterOutput)
axis([0 4500 -1 1]);
pause;

close all;

我从 fdatool 中将滤波器系数提取为 q15 格式的 16 位无符号整数,这是因为我使用的是 12 位 ADC。由 MATLAB 生成的滤波器协效 header 是 here以及由此产生的系数图可以在下图中看到 Filter co-efficents

下面是过滤器实现的代码,它显然不起作用,我真的不知道我能做些什么不同的事情,我在网上看了一些例子 Example 1Example 2

#include "fdacoefs.h"

#define FILTER_SAMPLES 4500
#define BLOCK_SIZE 900

static uint16_t firInput[FILTER_SAMPLES];
static uint16_t firOutput[FILTER_SAMPLES];
static uint16_t firState[NUM_TAPS + BLOCK_SIZE - 1];

uint16_t util_calculate_filter(uint16_t *buffer, uint32_t len)
{
uint16_t i;
uint16_t max;
uint16_t min;
uint32_t index;

// Create filter instance
arm_fir_instance_q15 instance;

// Ensure that the buffer length isn't longer than the sample size
if (len > FILTER_SAMPLES)
len = FILTER_SAMPLES;

for (i = 0; i < len ; i++)
{
firInput[i] = buffer[i];
}

// Call Initialization function for the filter
arm_fir_init_q15(&instance, NUM_TAPS, &firCoeffs, &firState, BLOCK_SIZE);

// Call the FIR process function, num of blocks to process = (FILTER_SAMPLES / BLOCK_SIZE)
for (i = 0; i < (FILTER_SAMPLES / BLOCK_SIZE); i++) //
{
// BLOCK_SIZE = samples to process per call
arm_fir_q15(&instance, &firInput[i * BLOCK_SIZE], &firOutput[i * BLOCK_SIZE], BLOCK_SIZE);
}

arm_max_q15(&firOutput, len, &max, &index);
arm_min_q15(&firOutput, len, &min, &index);

// Convert output back to uint16 for plotting
for (i = 0; i < (len); i++)
{
buffer[i] = (uint16_t)(firOutput[i] - 30967);
}

return (uint16_t)((max+min));
}

ADC 以 5.25 MSPS 采样,对 60kHz 信号采样 4500 次,您可以在此处看到 Input到过滤器,然后是 Output非常奇怪的过滤器..

有什么明显的我错过了吗?因为我完全迷路了,任何指示和提示都有帮助!

最佳答案

正如 Lundin 指出的那样,我将其改为使用 32 位整数,这实际上解决了我的问题。当然,我使用 MATLABS fdatool 生成了新的滤波器系数作为带符号的 32 位整数。

static signed int firInput[FILTER_SAMPLES];
static signed int firOutput[FILTER_SAMPLES];
static signed int firState[NUM_TAPS + BLOCK_SIZE -1];

uint16_t util_calculate_filter(uint16_t *buffer, uint32_t len)
{
uint16_t i;
int power;
uint32_t index;

// Create filter instance
arm_fir_instance_q31 instance;

// Ensure that the buffer length isn't longer than the sample size
if (len > FILTER_SAMPLES)
len = FILTER_SAMPLES;

for (i = 0; i < len ; i++)
{
firInput[i] = (int)buffer[i];
}

// Call Initialization function for the filter
arm_fir_init_q31(&instance, NUM_TAPS, &firCoeffs, &firState, BLOCK_SIZE);

// Call the FIR process function, num of blocks to process = (FILTER_SAMPLES / BLOCK_SIZE)
for (i = 0; i < (FILTER_SAMPLES / BLOCK_SIZE); i++) //
{
// BLOCK_SIZE = samples to process per call
//arm_fir_q31(&instance, &firInput[i * BLOCK_SIZE], &firOutput[i * BLOCK_SIZE], BLOCK_SIZE);
arm_fir_q31(&instance, &firInput[i * BLOCK_SIZE], &firOutput[i * BLOCK_SIZE], BLOCK_SIZE);
}

arm_power_q31(&firOutput, len, &power);

// Convert output back to uint16 for plotting
for (i = 0; i < (len); i++)
{
buffer[i] = (uint16_t)(firOutput[i] - 63500);
}

return (uint16_t)((power/10));
}

关于CMSIS FIR 带通滤波器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38264429/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com