嵌入式学习交流Q群 679912988
前言
- 工具地址: 傅里叶变换
- 无需下载,多窗口,多频谱的快速傅里叶变换FFT,及逆变换IFFT。
- 多次谐波信号发生器。
- 有好的想法或遇到问题,请到留言板留言。
简介
快速傅里叶变换 (fast Fourier transform),即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。
快速傅里叶变换是1965年由J.W.库利和T.W.图基提出的。
采用这种算法能使计算机计算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数N越多,FFT算法计算量的节省就越显著。
FFT(Fast Fourier Transformation) 是离散傅氏变换(DFT)的快速算法。即为快速傅氏变换。
它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
——百度百科
使用说明
步骤:
- 加载本地JSON文件或CSV文件(也可用信号生成模拟一个多次谐波的信号)
- 选择合适的窗口及频率类型
- 点击傅里叶变换
- 选择合适的频率区间时域还原
应用举例
模拟生成两个谐波,幅值为2的20Hz正弦波,幅值为1的50Hz正弦波,再加上幅值为0.5的高斯白噪声,配置如下:
对应波形如下:
FFT计算对应时频域图如下:
指定频率 49Hz~50Hz IFFT逆变换对应的时域图如下:
JSON文件样例
{
"signal": [
0,
0.06279051952931337,
0.12533323356430426,
0.18738131458572463,
/* 省略若干 */
0.968583161128631,
0.9822872507286886,
0.9921147013144778,
0.9980267284282716,
1
]
}
CSV文件样例
0
0.06279051952931337
0.12533323356430426
0.18738131458572463
0.2486898871648548
0.3090169943749474
0.368124552684678
0.42577929156507266
/* 省略若干 */
0.968583161128631
0.9822872507286886
0.9921147013144778
0.9980267284282716
1
STM32示例
模拟了一个单次谐波的FFT转换, 未添加逆变换
#include "arm_math.h"
#include "arm_const_structs.h"
#include "arm_common_tables.h"
void testFFT(uint32_t hz)
{
LOG_INFO("输入 %dhz", hz);
const static uint32_t adc_size = 1024; //采样点数量
uint16_t adc_buf[adc_size]; //采样缓存
float32_t fft_input_buf[adc_size * 2]; //fft 输入输出
float32_t fft_output_buf[adc_size]; //fft 输出
float32_t freq_sample = 1000; //采样频率
// 模拟一个采样缓存 传入的hz正弦波
for (int32_t i = 0; i < adc_size; i++)
adc_buf[i] = (uint16_t)(arm_sin_f32(2 * 3.1415926f * hz * i / freq_sample) * 4096.0f + 4096.0f);
// 更新待计算的缓存
for (int32_t i = 0; i < adc_size; i++) {
//搬运数据到实部
fft_input_buf[i * 2] = (float32_t)(adc_buf[i]);
//虚部为0
fft_input_buf[i * 2 + 1] = 0;
}
// 调用复数傅里叶变换
arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_input_buf, 0, 1);
// 计算FFT幅度值
arm_cmplx_mag_f32(fft_input_buf, fft_output_buf, adc_size);
// 输出各次谐波幅值
for (int i = 0; i < adc_size; i++)
fft_output_buf[i] /= i? 512: 1024;
float32_t maxValue;
uint32_t maxIndex;
// 找到最大幅度值以及其对应的位置
arm_max_f32(fft_output_buf, adc_size/2, &maxValue, &maxIndex);
float32_t PeakFreq = maxIndex * freq_sample / adc_size;
LOG_INFO("max %d: %f", maxIndex, maxValue);
LOG_INFO("结果: %f hz done!", PeakFreq);
}
2695

被折叠的 条评论
为什么被折叠?



