matlab将示波器得到的信号进行FFT处理

1FFT

1.1什么是fft

FFT(Fast Fourier Transformation)就是快速傅里叶变换的意思。输入的是离散数据,输出的也是离散频率。

在matlab中具体常用的使用方法为X=fft(x)或X=fft(x,Ns)。

1.2fft信号长度Ns

计算信号的fft,长度取信号长度。

Ns=length(t)

信号分析长度:一般取信号长度,或者2的整数次方长度。如果大于信号长度,

matlab默认在信号后面补0。

1.3计算频率索引号

fft得到的数据具有左右对称的特点,通常只采用左半边的数据作为信号数据

同时提一句,fft得到的数据长度同Ns

1.4计算真实幅值

abs(X)*2/Ns这个是固定的,记住就行了,如果想知道为什么可以了解fft的具体算法。这里Ns取得是信号的有效长度,如果在信号末尾补0的话,不算做有效长度。

1.5设置频域刻度

freq = (0:Ns/2)*fs/Ns;这个也是固定的用法。唯一注意的就是要和频率索引对应上。

通过计算可以看到,频率的最大值为fs/2,频率的分辨率为fs/Ns=1/T

1.6信号采样频率,计算前两个时间点的差的倒数

fs=1/(t(2)-t(1));

信号采样频率:就是每秒钟信号的采样点,与信号采样间隔成倒数关系

所以为了提高频率的最大值,需要提高信号的采样频率,这个主要是针对信号采样仪器设备的要求。

所以为了提高频率的分辨率,需要增加测量时间T,把信号尽可能测量的更长

7 信号加窗避免信号频谱泄露

如果信号在没有能在时间窗口内出现整数个周期,就会出现信号的泄露。
下图是一个1hz的信号,没有在末尾处没有出现完整,得到的频谱图。

信号泄露会导致该频率峰值的减小,同时也会导致频率峰宽度的增加。如上图,频率峰值不是1,而是比1小,而且1hz在两侧很长一段距离衰减的都很慢。

由于实际测量中,很难测到正好整数个波长,所以我们可以考虑给信号做一定的处理来减小这个泄漏问题。

代码

写代码的逻辑

 假设 t 和 x 已经定义,其中 t 是时间向量,x 是对应的信号值

 将示波器的数据导出,只保存成t和x两列数据

matalb里包含了读取该.m文件下的表格的能力

接下来就是:

1.计算数据长度

2 对纵坐标加汉宁窗

3对横坐标进行采样频率的计算,(横坐标相邻两个点时间差的倒数)

4 生成频率轴

5 对横坐标进行FFT转换

计算幅度值,将幅度转换为功率谱密度,

然后再将功率谱密度转换为dBm

6 只取单边带频谱

7作图,sbu(2,1,1)和sbu(2,1,2),这样就可以将原始信号和FFT处理后的图放到一个表格里

代码1:

% 数据选择界面
[specname,pathname,filterindex] = uigetfile('*.*','选择参数文件','MultiSelect', 'on');
% vm=[];rsd=[];len =[];specnum=[];num=0;numt=0;yy=[];cc=[];list=[];FWHMh=[];vvm=[];
 
specname = fullfile(pathname,specname);
data = readtable(specname);
data = table2array(data);
database = data;
t=data(:,1); %示波器横坐标
x=data(:,2); %示波器纵坐标
 
%先把示波器的数据分两列导入工作区,横坐标命名为t,纵坐标命名为x
subplot(2,1,1);
plot(t,x); %画出原始信号
 
%求FFT
N=length(t); %计算信号长度
Fs=1/(t(2)-t(1));%信号采样频率,计算前两个时间点的差的倒数
 
% 生成频率轴(以Hz为单位),用于后续绘图展示
f = (0:N-1)*(Fs/N);
 
% 应用汉明窗
win = hamming(N);
x_win = x.*win';
 
% 进行FFT
X = fft(x_win);
 
% 计算幅度谱(取绝对值,并归一化,这里的归一化是常规的一种处理方式)
X_mag = abs(X)/N;
 
% 将幅度转换为功率谱密度(根据 Parseval 定理等相关原理)
Pxx = (X_mag.^2);
 
% 将功率谱密度转换为dBm形式(参考功率为1mW,这里假设信号是在50欧姆负载上,可根据实际调整)
R = 50; % 负载电阻(欧姆)
Pref = 1e-3; % 参考功率(W),1mW转换为W
dBm = 10*log10(Pxx*R/Pref);
 
% 只取单边频谱(因为实际信号的频谱是对称的,通常我们只看单边就够了)
f_single_side = f(1:N/2+1);
dBm_single_side = dBm(1:N/2+1);
 
% 绘制频谱图
subplot(2,1,2);
plot(f_single_side, dBm_single_side);
xlabel('Frequency (Hz)');
ylabel('Power (dBm)');
title('Frequency Spectrum');
grid on;

 

代码2:

% 数据选择界面
[specname,pathname,filterindex] = uigetfile('*.*','选择参数文件','MultiSelect', 'on');
% vm=[];rsd=[];len =[];specnum=[];num=0;numt=0;yy=[];cc=[];list=[];FWHMh=[];vvm=[];
 
specname = fullfile(pathname,specname);
data = readtable(specname);
data = table2array(data);
database = data;
t=data(:,1); %示波器横坐标
x=data(:,2); %示波器纵坐标
 
%先把示波器的数据分两列导入工作区,横坐标命名为t,纵坐标命名为x
subplot(2,1,1);
plot(t,x); %画出原始信号
 
% %求FFT
% N=length(t); %计算信号长度
% Fs=1/(t(2)-t(1));%信号采样频率,计算前两个时间点的差的倒数
% 
% % 生成频率轴(以Hz为单位),用于后续绘图展示
% f = (0:N-1)*(Fs/N);
 
% 假设 t 和 x 已经定义,其中 t 是时间向量,x 是对应的信号值
 
% 采样频率,假设我们知道这个值
Fs = 1 / (t(2) - t(1)); % 如果 t 是等间隔的,可以通过两个相邻的时间差来计算
 
% 汉明窗大小等于信号长度
window = hamming(length(x));
 
% 对信号应用汉明窗
x_windowed = x .* window;
 
% 执行FFT并取绝对值得到单边频谱
X_fft = fft(x_windowed);
 
% 计算功率谱密度(PSD)
Pxx = (abs(X_fft).^2) / length(x); % 功率谱
 
% 转换到单边频谱,并考虑能量归一化
n = length(x);
if mod(n, 2) == 0
    Pxx = Pxx(1:n/2+1);
    Pxx(2:end-1) = 2*Pxx(2:end-1);
else
    Pxx = Pxx(1:(n+1)/2);
    Pxx(2:end-1) = 2*Pxx(2:end-1);
end
 
% 将功率谱转换为 dBm 单位
% 注意:这里假设输入信号是以伏特为单位的电压信号,
% 并且负载电阻是50欧姆。如果情况不同,请调整公式。
R = 50; % 负载电阻,通常为50欧姆
Pxx_dBm = 10*log10(Pxx * (1e3 / R)); % 将瓦特转换为毫瓦再转为dBm
 
% 频率轴
f = linspace(0, Fs/2, length(Pxx));
 
% 绘制频谱图
subplot(2,1,2);
plot(f, Pxx_dBm);
xlabel('Frequency (Hz)');
ylabel('Power/Frequency (dBm/Hz)');
title('Single-Sided Amplitude Spectrum of x(t)');
grid on;

Q:为什么和示波器的值不一样?

A:纵坐标数值与示波器的不一致可能由多种因素引起,包括但不限于以下几点:

1. **不同的参考电平和单位**:示波器可能使用了不同的参考电平或单位。确保您在MATLAB中使用的转换公式正确反映了示波器所用的单位。

2. **窗口函数的影响**:应用汉明窗会改变信号的幅度。虽然我们在计算功率谱时考虑了这一点(通过乘以2来补偿单边频谱中的能量),但实际影响可能更复杂,特别是在信号边缘。

3. **频率分辨率**:MATLAB代码中的FFT点数决定了频率分辨率。如果FFT点数不同,得到的结果也会不同。

4. **功率谱密度的归一化**:在计算PSD时,我们进行了归一化处理。如果示波器使用了不同的归一化方式,这会导致结果差异。

5. **采样率和数据长度**:如果MATLAB中使用的采样率或数据长度与示波器的不同,那么得到的频域表示也会不同。

6. **示波器内部处理**:现代示波器可能会对采集的数据进行额外的处理,例如平均、滤波等,这些都可能导致结果上的差异。

为了使MATLAB的结果更接近于示波器的显示,您可以尝试以下方法:

- **检查示波器设置**:了解示波器的FFT设置,包括窗口类型、FFT大小、重叠百分比等,并尽可能地在MATLAB中模拟这些设置。

  - **调整功率谱的计算**:如果您知道示波器使用的具体公式,可以在MATLAB中实现相同的公式。

- **匹配参考电平**:确认MATLAB中计算dBm时的参考电平是否与示波器相同。比如,一些示波器可能会有一个固定的参考电平(如0 dBm = 1 mW)。

- **校准**:如果有可能,使用已知频率和幅度的信号源来进行校准,确保两者的一致性。

- **查阅文档**:查看示波器的手册,了解它是如何计算和显示FFT的。有些高端示波器允许导出FFT设置,这可以帮助您更好地理解其内部处理过程。

- **联系制造商支持**:如果您无法获得足够的信息来匹配两者的输出,可以考虑联系示波器的制造商获取更多帮助。

最后,要记住即使是经过仔细调整,由于硬件和软件之间的细微差别,完全一致可能是难以实现的。不过,通过上述步骤,应该可以显著减小两者之间的差异。

MATLAB是一种强大的数值计算和数据可视化工具,尤其适合处理信号处理任务,包括快速傅里叶变换(FFT)。FFT是将时间域信号转换到频率域的一种常见方法,用于分析信号的频域特性。 在MATLAB中进行信号FFT频谱分析,通常分为以下几个步骤: 1. **读取信号**:首先,你需要导入包含你想要分析的信号的数据文件,可以是向量、矩阵或者来自其他源的数据。 ```matlab signal = readmatrix('your_signal_file.csv'); ``` 2. **应用FFT**:`fft`函数是MATLAB内置的用于计算单个离散序列的快速傅立叶变换的函数。如果你想分析整个信号,需要先分段处理,比如窗口化。 ```matlab window_size = length(signal); % 窗口大小 n = window_size; % FFT点数等于信号长度 xfft = fft(signal, n); ``` 3. **绘制频谱**:获取了复数结果后,可以利用`abs(xfft)`得到幅度谱,`angle(xfft)`得到相位谱,然后通过`plot`函数显示出来。 ```matlab freq = (0:n-1)*(fs/window_size); % fs表示采样率 spectrogram = abs(xfft)/length(signal); spectrum_plot = plot(freq, spectrogram); xlabel('Frequency (Hz)'); ylabel('Magnitude'); title('Signal Frequency Spectrum'); ``` 4. **频率分辨率调整**:如果需要,你可以调整采样率 `fs` 或窗口大小来改变频率分辨率。 5. **处理复杂信号**:对于实值信号,一般只关心正频率部分,可通过 `xfft = xfft(1:n/2+1) + 1i*xfft(2:n/2)` 和 `xfft = xfft(1:n/2+1)` 来分别处理实部和虚部。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值