一、在Matlab中求数据序列的FFT
FFT测试数据生成:包含实部与虚部(虚部为0);
参数设置:
参数 | 配置 |
---|---|
采样频率 | 50MHz |
信号长度 | 1024 点 |
测试信号 | 5MHz与8MHz正弦波的混合信号 |
量化方式 | 二进制数:16位有符号数、保留6位小数 |
生成FFT测试数据的Matlab代码:
2024.11.22更改,增加:保存Vivado缩放相对应的FFT的实部和虚部结果:
%% 求特定序列的FFT
% 定义参数
clear all;
clc;
Fs = 50e6; % 采样频率 (50MHz)
T = 1/Fs; % 采样周期 (s)
L = 1024; % 信号长度
t = (0:L-1)*T; % 时间向量
%% 生成信号 (5MHz 的正弦波和 8MHz 的正弦波的叠加)
f1 = 5e6; % 信号频率(5MHz)
f2 = 8e6; % 信号频率(8MHz)
S = round((0.5*sin(2*pi*f1*t) + sin(2*pi*f2*t))*(2^14-1)); % 取整数
%% 对信号进行 FFT
Y = fft(S);
% 计算双边频谱
P2 = abs(Y/L);
% 计算单边频谱
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
% 定义频率域
f = Fs*(0:(L/2))/L; % 单边谱频率坐标
f2 = Fs*(0:L-1)/L; % 双边谱频率坐标
% 绘制信号的单边幅度谱
figure;
plot(f2, P2);
title('双边振幅谱');
xlabel('f (Hz)');
ylabel('|P1(f)|');
%% 写入txt文件
% 打开文件
file1 = fopen('data.txt', 'w');
q = quantizer([16 0]); % 量化方式:16位有符号数,0位小数
% 写入数据
for i = 1:size(S,2)
S_bin = num2bin(q, S(i));
fprintf(file1, '%s\n', S_bin);
end
% 关闭文件
fclose(file1);
% 打开文件
file2 = fopen('fft_data_R.txt', 'w');
% 写入数据
for i = 1:size(Y,2)
fprintf(file2, '%d\n', round(real(Y(i))/2^8)); % FFT结果右移8位,与Vivado仿真缩放因子对应
end
% 关闭文件
fclose(file2);
% 打开文件
file3 = fopen('fft_data_I.txt', 'w');
% 写入数据
for i = 1:size(Y,2)
fprintf(file3, '%d\n', round(imag(Y(i))/2^8)); % FFT结果右移8位,与Vivado仿真缩放因子对应
end
% 关闭文件
fclose(file3);
%% 求特定序列的IFFT
S_reconstructed = ifft(Y);
% 对比原始信号与恢复信号
figure;
plot(t, S);
hold on;
plot(t, real(S_reconstructed), '--');
legend('原始信号', '恢复信号');
title('原始信号与恢复信号对比');
xlabel('时间 (s)');
ylabel('幅度');
经FFT后的测试信号的双边谱:
测试信号和经IFFT还原后的信号:
二、在Vivado中求数据序列的FFT和IFFT
2.1 FFT的IP核参数设置
重要参数说明:
参数 | 配置 |
---|---|
Transform Length(FFT变换长度) | 1024点 |
Target Clock Frequency(目标时钟频率) | 50MHz |
Target Data Throughput( |