【FPGA-DSP】第五期:FFT调用流程

目录

1. matlab输入信号编写

2. Simulink开发

2.1 模块搭建

2.2 Simulink运行

2.3 matlab信号处理 

拓:输入信号位数改变


本章节主要说明如何在system generator中使用fft模块,话不多说,看操作:

参考教程第5期 - FFT调用流程 - 基于FPGA的数字信号处理系统开发笔记_哔哩哔哩_bilibili

1. matlab输入信号编写

clc;clear all;close all;
%--------------------------------------------------------------------------
%%  FFT 输入信号生成
%--------------------------------------------------------------------------

%% 系统参数
N = 1024;%采样点数
Fs = 10000;%采样率为10KHz
Ts = 1/Fs;

%% 输入信号生成,由100Hz和2000Hz正弦信号合成
A = 0.5;
t = (0:N-1)*Ts;
ft_0 = 100;
vi_0 = zeros(1,N);
ft_1 = 2000;
vi_1 = zeros(1,N);
vi = zeros(1,N);% simulink rom导入

for n = 1:N
    vi_0(n) = A*sin(2*pi*ft_0*t(n));
    vi_1(n) = A*sin(2*pi*ft_1*t(n));
    vi(n) = vi_0(n) + vi_1(n);%混频
end


%% 信号图像输出
figure(1)
subplot(3,1,1)
plot(t,vi_0,'k');
xlabel('time'); 
ylabel('Amplitude');
subplot(3,1,2)
plot(t,vi_1,'k');xlabel('time'); 
ylabel('Amplitude');
subplot(3,1,3)
plot(t,vi,'k');
xlabel('time'); 
ylabel('Amplitude');

[Fre0,Amp0] = fft_plot(vi_0,Fs,N);
[Fre1,Amp1] = fft_plot(vi_1,Fs,N);
[Fre,Amp] = fft_plot(vi,Fs,N);

figure(2)
subplot(3,1,1)
plot(Fre0,Amp0);
xlabel('Frequency'); 
ylabel('Amplitude'); 
subplot(3,1,2)
plot(Fre1,Amp1);
xlabel('Frequency'); 
ylabel('Amplitude'); 
subplot(3,1,3)
plot(Fre,Amp);
xlabel('Frequency'); 
ylabel('Amplitude'); 

2. Simulink开发

2.1 模块搭建

参考我之前的一个开发笔记【FPGA-DSP】第二期:DSP开发流程【全过程】_༜黎明之光༜的博客-CSDN博客本章节首先介绍FPGA进行DSP开发所需要的软件环境,及其安装方式。DSP学习教程参考。https://blog.csdn.net/weixin_44810982/article/details/129746580

构建好的Simuink如下图所示 

Xilinx提供的FFT模块的输入输出均为两路IQ信号,在输入侧由于我们的输入信号为时域信号vi(只有实部信号),因此需要输入一个常数的虚部信号给data_tdata_xn_im_0,图中输入的是常数0。输出侧也是两路IQ信号,我们需要调用Simulink-Math Operation中的Real-Imag to complex将两路IQ信号合并成一路复数信号。因为输出端的信号合并操作是在FPGA外部(Simulink中处理),因此需要相连接outgetway再与Real-Imag to complex相连。最后将合并好的信号导入到work space中(使用To workspace模块)。

注意:当我们输入为fix_32_16的时候,simulink会报错,报错信息如下:

意思是请将输入修改为fix_32_31,这也就意味着在除去一位符号位之后,剩下的31位均为小数位,因此输入信号的幅度必须小于1,为了优化这个问题,将在文章最末给出解决方式 

2.2 Simulink运行

注意:Simulink的运行时间我们需要设置为N*5,即1024*5=5120个总采样点数。因为FFT需要才采集到1024个数据点之后才会进行快速傅里叶计算,同时考虑到系统计算会有一定的时延,因此我们需要将运行时间设置为5倍采样时间

图中易知FFT有很大的延迟

2.3 matlab信号处理 

在Simulink中我们使用了To workspace模块将数据导入到了work space中,变量名为sysgen_fft_output

因为FFT需要在采样1024个点后才会开始计算,同时也会存在计算时延,因此采样点为2166的时候才有数据点。 

第一节中的matlab代码需要在末添加对sysgen_fft_output进行信号处理的部分,代码如下:

%% ---------------------------- 运行该节 -----------------------------------
% 在运行了system generator 中的FFT模块后,下面的代码才能够成功运行
start = 2166; %2166个采样点后才会有数据,因此从2166~2166+1024的范围内是我们数据经过FFT计算的有效值
FFTData1 = out.sysgen_fft_output.Data;% Symulink中使用的to workspace模块的输出
FFTData = abs(FFTData1(start:start+N-1))/N;

% From fft_plot function file
FFTAmplitude_FFTData1 = FFTData(1:N/2);
FFTAmplitude_FFTData1(2:end) = 2*FFTAmplitude_FFTData1(2:end);
Frequence_FFTData1 = Fs*((0:(N/2)-1))/N;

figure(3)
subplot(2,1,1)
plot(Fre,Amp,'k');
subplot(2,1,2)
plot(Frequence_FFTData1,FFTAmplitude_FFTData1,'k');

选择运行节

运行后得到的图像如下图所示:

可以发现,二者对比,纵轴是没有差别的,横轴差了10个采样点数,这是可以原谅的。因为matlab与sumulink中对于fft的计算并不相同,会有数据点位置的不一致,但这不影响最终结果呈现。 

拓:输入信号位数改变

通过使用下列模块来实现输入信号位数的改变:Reinterpret(截位用Convert)

通过使用该模块,我们能够将我们输入信号fix_32_16强制转化为fix_32_31

修改好的Simulink结果如下:

与此同时,我们将matlab中的幅值参数A改为3后运行simulink

结果如下:

运行matlab对应的节 

可以发现幅值变得非常小,是因为我们需要输出侧中将信号重新解释回来

一致! 

猜你喜欢

转载自blog.csdn.net/weixin_44810982/article/details/130077517
今日推荐