大晚上的写一个小玩意儿,就是昨天的副产物,如何在 FFT 算法里面精确的锁定一个频率。(以 1kHz 为例子)
要想“一个信号”的 FFT 峰值稳稳落在 1 kHz,核心就是做到相干采样(coherent sampling)并且频轴用对真正的采样率。
让采样窗口里包含整数个周期 ⟹ 选
其中
= 目标基频(你要 1 kHz),
= 实际采样率(20k/40k/…/100k),
= 采样点数,
= 窗口中包含的整数周期数(自己选整数:几百~几千都行)。
只要按上式选 ,即使用矩形窗,峰也不会“歪”;同时幅值也最准(无需窗补偿)。
举例:取 个周期(足够长、分辨率细), Hz,则
记录时长 | ||
|---|---|---|
20 kS/s | 81 920 | 4.096 s |
40 kS/s | 163 840 | 4.096 s |
60 kS/s | 245 760 | 4.096 s |
80 kS/s | 327 680 | 4.096 s |
88 kS/s | 360 448 | 4.096 s |
100 kS/s | 409 600 | 4.096 s |
这些 不一定是 2 的幂。倒是也没关系:先按相干的 采数,再在计算时零填充到最近的 2 的幂做 FFT(加速而已,不改变实际分辨率)。
如果想保持固定时长(比如都采 5 s),那就设 固定,令: ,再把 调到 (或微调 使 为整数),也能相干。
先修正频轴:分析程序要用真实 。
定时器驱动采样:用 TIM 触发 AD7606 的 CONVST,保证匀速。
按上面的表取 (点数):每个 对应一个 。使用 MCU 的DMA/Ping-Pong 连续收满 点就“封包”一次做频谱。
FFT 算法:
用矩形窗(相干采样下幅值最准),或 Hann/Blackman 也可;需要加速就零填充到 ;峰值在正好 1 kHz 的 bin,不会飘。
如果发生轻微漂移:可以校准信号源与采样时钟(最好共用 10 MHz 参考或用 EXT Trig/Sync),也可以让信号源频率设成 (把频率“对准 bin”)。
其中频率分辨率:。想要细到 0.1 Hz:20 kS/s 需 (约 10 s);100 kS/s 需 (约 10 s)。