在信号处理链中的哪个点使用 Hann Window?

信息处理 fft 窗函数
2022-02-10 16:36:05

我有一个关于信号处理的问题。具有嵌入式设计和代码经验,但 DSP 处于新领域。

到目前为止,我正在使用运行良好的 CMSIS DSP 库函数。我正在采样低频信号。使用定时器中断,采样率比我期望看到的最高信号高 40 倍。我处理的“缓冲区”大小为 2048。我首先应用低通 FIR ( arm_fir_f32),然后应用到arm_cfft_f32函数,这样我就可以计算频率信息。它可以很好地工作到频率为 +/- 1Hz 的点。但是,我希望能达到 +/-200mHz。

我知道我需要降低端点的功率(噪声),汉恩窗应该是最好的(更好的?)选择。因此我的问题:

在什么时候应用 Hann 算法?(如下)

w[n]=0.50.5cos(2πnN1)

应该是我的样本块的大小吗?N

编辑:

窗口函数代码:

(INPUT_SAMPLES=2048) 
for(uint16_t i = 0; i < INPUT_SAMPLES; i++) 
{ 
    ADC_Values[i] = 0.5 - (0.5 * cos ( (2.0 * PI * ADC_Values[i]) / (INPUT_SAMPLES - 1)));
} 

感谢您对此的任何帮助,罗杰

编辑2:

开玩笑,

创建窗口并按照建议更改计算已修复它。虽然窗口没有像我想要的那样提高分辨率,但它更好,并且足够接近以非常有用。太棒了...感谢大家的所有回复。

2个回答

您应该在时域中应用窗口目的是使您的信号在帧/样本块的边界处变为零。这是必要的,因为 DFT 假设信号是周期性的,并且在末端将其归零使其如此。显然,如果帧的长度是恒定的,则预先计算窗口值。

足够的话:

在此处输入图像描述

我突然想到您想要获得 0.2 Hz 的频率分辨率 - 对吗?您必须记住,频率分辨率由下式给出:因此,除非您的采样频率不低于大约。410 Hz(不太可能)您无法达到 200 mHz 的分辨率。你需要扩展你的观察窗口。用零填充你的信号也无济于事 - 这只是你的频谱点的插值。Δf=fsNfs

编辑:

如果您执行任何 FIR 过滤,则随后应用该窗口。应在 FFT 计算之前进行加窗,以使您的信号在末端“消失”(尤其是当滤波为第一个输出样本产生伪影时)。关于您的频率分辨率,为 2kHz ,等于 2048,您将获得大约 0.98 Hz 的分辨率。如果您想要更多,那么您可能会考虑扩展您的样本块或降低采样频率。请记住我上面提到的方程式。fsN

编辑2:

我认为您粘贴的功能(以及我移至您的原始问题的功能)仅用于计算窗口。我对你的理解正确吗?或者是执行信号窗口化的函数(ADC_Values[i]存在变量)。检查以下事项:

  1. 我更正了您的窗函数方程 - 请注意它仅取决于n- 没有信号样本。

  2. 如果你想在你的函数中执行窗口化,那么代码应该看起来更像:

    ADC_Values[i] = (0.5 - (0.5 * cos ( (2.0 * PI * i) / (INPUT_SAMPLES - 1)))*ADC_Values[i];

窗口计算本身由下式给出:

`win[i] = (0.5 - (0.5 * cos ( (2.0 * PI * i) / (INPUT_SAMPLES - 1)));`

win因此,我建议您一劳永逸地预先计算,稍后将其传递给您的函数并执行ADC_Values[i] *= win[i];. 这将节省一些时间。

我假设您正确地进行了类型转换。如果您有任何疑问,请提取滤波前后的信号块,以及窗口样本和窗口信号。这应该可以帮助您调试代码。

编辑 3:

恐怕你还是不明白原理。改变窗口只能消除泄漏效应——一种覆盖谐波的噪音。它不会增加您的频率分辨率事实上,它会使情况变得更糟——因为矩形窗口的主瓣最窄。让我再重复一遍 - 如果你想增加你的频率分辨率,那么你必须使用适当的缓冲区大小和采样频率,根据方程Δf=fsN

Hann 窗口大小的 N 参数应该是您的 FFT 的大小(或者,如果您计划对数据进行零填充以使用更长的 FFT,则应该是样本块的大小)。