资讯详情 信号分析与处理实验:Matlab波形到频域分析的完整实操记录
📅 2026/10/23 18:41:05
简介这份资源是南京邮电大学「信号分析与处理实验」课程的完整实验报告面向正在修读数字信号处理、信号与系统相关课程的高校学生以及需要借助 MATLAB 完成信号处理实验与课程设计的自学者。报告围绕信号的产生和运算、连续时间信号的频域分析、信号的时域采样和重建、离散傅里叶变换与应用等核心实验展开并延伸至连续时间系统的频域与复频域分析、数字滤波器设计及信号处理综合应用配有可运行的 MATLAB 程序示例与图形结果便于对照理解时域与频域特性。资源包共 1 个 docx 文件约 1.02MB内容涵盖实验目的、实验内容、程序代码与结果分析结构完整、条理清晰。目前已有 952 人学习下载适合作为实验预习、报告撰写参考与 DSP 入门练习的实用材料。1. 信号分析与处理实验从Matlab波形到频域分析的完整实操记录很多同学学完《信号与系统》理论课面对傅里叶级数、采样定理、DFT这些概念还是一头雾水公式推得再熟一到实际信号上就不知道从哪下手。这份实验报告记录的就是把抽象公式变成Matlab波形的过程——从最基础的阶跃序列、复指数序列生成到周期矩形脉冲的频谱分析再到时域采样与信号重建最后落到数字滤波器设计。四个实验层层递进每个都配有可直接运行的Matlab代码和结果分析。如果你正在学数字信号处理DSP这门课或者需要一份能照着跑通的实验参考这份材料能帮你把理论和代码之间的那层窗户纸捅破。2. 实验环境与项目结构先搞清楚手里有什么2.1 运行环境与依赖这套实验全部基于Matlab完成不依赖任何额外工具箱。我实测在Matlab R2018b及以上版本都能直接跑低版本理论上也没问题因为用到的都是基础函数stem、plot、subplot、conv、fft、sinc、filter这些。不需要Simulink不需要DSP System Toolbox纯脚本就能搞定。如果你用的是Octave大部分代码也能跑但freqz和butter这类滤波器设计函数可能需要安装signal包。我一般建议直接用Matlab省得折腾兼容性问题。2.2 实验模块划分整份报告按实验序号组织每个实验对应一个独立文件夹里面包含脚本文件和结果图。目录结构大致如下信号分析与处理实验/ ├── 实验一_信号的产生和运算/ │ ├── P1_1.m % 单位阶跃序列 │ ├── P1_2.m % 复指数序列 │ ├── P1_3.m % 实指数序列 │ ├── P1_4.m % 正弦序列 │ ├── P1_5.m % 序列加乘运算 │ ├── P1_6.m % 奇偶分量分解 │ └── P1_7.m % 线性卷积 ├── 实验二_连续时间信号频域分析/ │ ├── P2_1.m % 周期矩形脉冲傅里叶级数 │ ├── P2_2.m % 谐波叠加 │ └── P2_4.m % 吉布斯现象过冲计算 ├── 实验三_时域采样与重建/ │ ├── P3_1.m % 采样与频谱分析 │ └── P3_2.m % 信号重建 └── 实验四_离散傅里叶变换与应用/ ├── P4_1.m % DFT实现 └── P4_2.m % 滤波器设计每个脚本都是独立可运行的变量命名清晰没有跨文件依赖。这种组织方式对新手很友好——你不需要理解整个工程打开哪个文件就跑哪个。2.3 实验报告的核心产出每个实验最终要交付三样东西一是可运行的Matlab代码二是波形图或频谱图三是对结果的分析说明。报告里对每个问题的分析都写得比较具体比如采样定理那部分不仅画出了混叠前后的频谱对比还解释了为什么Ts2时会发生混叠而Tspi/2时不会。这种“代码图解释”的结构拿来当实验模板或者自学材料都合适。3. 核心实验拆解从信号生成到频域分析的代码实现3.1 离散序列的生成与基本运算实验一的核心是让你熟悉Matlab里怎么表示离散时间信号。离散序列和连续信号最大的区别在于你得同时定义时间轴向量和幅度向量。比如要画单位阶跃序列u[n]代码是这样的% 产生单位阶跃序列 u[n] 和 u[n7] clear; close all; n -10:20; % 时间轴范围 x [zeros(1,10) 1 ones(1,20)]; % u[n]: n0时为0, n0时为1 subplot(1,2,1); stem(n, x); xlabel(n); ylabel(u[n]); title(单位阶跃序列 u[n]); M 7; % 移位量 xd [zeros(1,10M) 1 ones(1,20-M)]; % u[n7]: 左移7位 subplot(1,2,2); stem(n, xd); xlabel(n); ylabel(u[n7]); title(移位后的阶跃序列 u[n7]);这里的关键点在于zeros和ones的拼接方式。n-10:20一共31个点zeros(1,10)对应n-10到n-11对应n0ones(1,20)对应n1到n20。移位操作u[n7]本质上是把序列左移7位所以前面补7个零后面少7个一。这个逻辑搞清楚了后面所有序列的移位操作都是一个套路。复指数序列稍微绕一点因为涉及复数运算% 复指数序列 x[n] 1.5 * exp((0.2 j3)n), 0 n 15 clear; close all; c 0.2 3*1i; % 复数指数系数 K 1.5; % 幅度系数 n 0:15; x K * exp(c * n); % 生成复指数序列 subplot(1,2,1); stem(n, real(x)); % 取实部 xlabel(n); ylabel(幅度); title(实部); subplot(1,2,2); stem(n, imag(x)); % 取虚部 xlabel(n); ylabel(幅度); title(虚部);real(x)和imag(x)分别提取实部和虚部。复指数序列在DSP里非常重要因为它是DFT的基函数。这里c 0.2 3i实部0.2控制包络的衰减或增长虚部3控制振荡频率。你可以试着改一下c的值观察波形怎么变——比如把虚部改成0.5振荡会明显变慢。3.2 序列的卷积与奇偶分解卷积是信号处理里最核心的运算之一。实验一里用conv函数计算了两个有限长序列的线性卷积% 计算 x[n] 和 h[n] 的线性卷积 clear; close all; nx 0:14; x (-1).^nx; % x[n] (-1)^n, 0n14 nh 0:7; w 0.25 * pi; h cos(w * nh); % h[n] cos(0.25*pi*n), 0n7 y conv(x, h); % 线性卷积 n 0:21; % 卷积结果长度 15 8 - 1 22 subplot(3,1,1); stem(nx, x); title(x[n]); subplot(3,1,2); stem(nh, h); title(h[n]); subplot(3,1,3); stem(n, y); title(y[n] x[n] * h[n]);conv函数的输出长度是length(x) length(h) - 1这里是158-122个点。注意时间轴n要重新定义不能直接用nx或nh。这个细节很容易翻车——我见过不少同学画卷积结果时时间轴对不上波形整体偏移了。奇偶分解的代码也值得看一下% 序列的奇偶分量分解 clear; close all; n -2:2; x [1 2 4 -5 -2]; y fliplr(x); % 时间反转 xe 0.5 * (x y); % 偶部 xo 0.5 * (x - y); % 奇部 subplot(3,1,1); stem(n, x); title(x[n]); subplot(3,1,2); stem(n, xe); title(偶部 x_e[n]); subplot(3,1,3); stem(n, xo); title(奇部 x_o[n]);fliplr是左右翻转对应时间反转x[-n]。偶部是(x[n]x[-n])/2奇部是(x[n]-x[-n])/2。这个分解在分析系统对称性时很有用比如实偶信号的傅里叶变换也是实偶函数。3.3 周期矩形脉冲的傅里叶级数与吉布斯现象实验二的重头戏是周期矩形脉冲的频谱分析。指数形式的傅里叶级数系数公式是$$c_k \frac{A\tau}{T} \cdot \text{sinc}\left(\frac{k\Omega_0\tau}{2\pi}\right)$$代码实现时用sinc函数直接算% 周期矩形脉冲的傅里叶级数系数 A 1; tau 0.1; T 0.5; Omega0 2*pi/T; k -20:20; ck A*tau/T * sinc(k*Omega0*tau/(2*pi)); subplot(2,1,1); stem(k, abs(ck)); title(双边幅度谱); subplot(2,1,2); stem(k, angle(ck)); title(相位谱);这里k取-20到20覆盖了主要谐波分量。sinc函数在Matlab里定义为sin(pi*x)/(pi*x)和信号处理里的归一化sinc一致。如果你把T从0.5改成1或2会发现谱线间隔变密、幅度降低——这正是报告里问题2.2要你观察的现象。吉布斯现象的计算用了一个循环来累加谐波function p2_4(N) t -2:1e-4:2; A 1; tau 1; T 2; Omega0 2*pi/T; c0 A*tau/T; f_N c0 * ones(1, length(t)); for k 1:N f_N f_N 2*A*tau/T * sinc(k*Omega0*tau/(2*pi)) * cos(k*Omega0*t); end overshoot max(f_N); fprintf(The maximum overshoot is %.4f\n, overshoot); end当N增大时过冲峰值趋近于一个常数大约在跳变幅度的9%左右。这个函数直接返回过冲最大值方便你验证不同N下的收敛情况。3.4 采样定理验证与信号重建实验三用升余弦脉冲信号来验证采样定理。核心逻辑是先定义连续信号的频谱然后以不同采样间隔Ts采样观察频谱是否混叠。% 采样与频谱分析 Ts pi/2; % 采样间隔 t -10:Ts:10; % 升余弦脉冲信号生成 x ...; % 具体表达式见报告 % 计算并绘制频谱 X fftshift(fft(x)); f (-length(x)/2:length(x)/2-1) / (length(x)*Ts); plot(f, abs(X));当Ts pi/2时采样频率满足奈奎斯特条件频谱没有混叠当Ts 2时采样频率低于两倍截止频率频谱出现混叠。报告里对这两个情况的对比图和分析都很清楚。信号重建部分用低通滤波器从采样信号中恢复原信号% 信号重建 Wc 2; % 低通滤波器截止频率 % 设计理想低通滤波器 h Wc/pi * sinc(Wc/pi * (n - delay)); % 卷积实现重建 xr conv(xs, h);重建误差的大小直接反映了采样定理是否被满足。Ts2时误差明显增大因为混叠导致高频分量无法恢复。4. 避坑与常见问题跑代码时容易翻车的几个地方4.1 时间轴对不上导致波形偏移现象画卷积结果或移位序列时波形整体左移或右移和理论位置对不上。原因stem或plot的横轴向量和信号向量长度不一致或者移位操作后没有重新定义时间轴。解决每次生成新序列后先确认length(n) length(x)。卷积后用n 0:length(y)-1重新定义时间轴。移位操作时时间轴不变只改幅度向量的补零位置。4.2 复数序列取实部虚部时忘记用real/imag现象stem画复指数序列时报错或画出奇怪的结果。原因Matlab的stem不能直接画复数必须显式取实部或虚部。解决用real(x)和imag(x)分别提取。如果想画幅度和相位用abs(x)和angle(x)。4.3 采样频率设置不当导致频谱混叠现象频谱图上出现明显的频率折叠高频分量跑到低频区域。原因采样间隔Ts大于奈奎斯特间隔不满足采样定理。解决先计算信号的最高频率fm然后确保Ts 1/(2*fm)。报告里升余弦脉冲的截止频率是Wm2所以奈奎斯特间隔是pi/2。如果你不确定信号的带宽先把Ts设小一点逐步增大观察频谱变化。4.4 fft后的频率轴计算错误现象频谱图的横轴频率值不对峰值位置和理论值偏差很大。原因fft输出的频率分辨率是fs/N其中fs1/TsN是采样点数。频率轴应该从-fs/2到fs/2。解决用f (-N/2:N/2-1) * (fs/N)计算频率轴配合fftshift使用。如果只画正频率部分取前N/21个点频率轴从0到fs/2。4.5 滤波器设计时阶数选择不当现象重建信号要么过渡带太宽要么通带纹波太大。原因滤波器阶数太低导致过渡带不够陡峭阶数太高又可能引入数值不稳定。解决先用buttord或cheb1ord估算所需阶数再用butter或cheby1设计。对于理想低通重建直接用sinc函数生成冲激响应但要注意截断长度——截断太短会导致吉布斯现象太长会增加计算量。5. 二次开发与扩展把这套代码改成自己的工具5.1 封装成可复用的函数原始代码都是脚本形式变量直接暴露在工作区。如果你想反复使用某个功能比如生成任意参数的复指数序列可以把它封装成函数function [n, x] gen_complex_exp(K, sigma, omega, n_start, n_end) % 生成复指数序列 x[n] K * exp((sigma j*omega)n) % 输入 % K - 幅度系数 % sigma - 实部衰减/增长因子 % omega - 虚部角频率 % n_start - 起始索引 % n_end - 结束索引 % 输出 % n - 时间轴向量 % x - 复指数序列 n n_start:n_end; x K * exp((sigma 1i*omega) * n); end调用时只需要一行[n, x] gen_complex_exp(1.5, 0.2, 3, 0, 15);。这样你就不用每次改参数都去翻脚本了。5.2 用App Designer做个交互界面如果你想让不懂Matlab的人也能玩这些实验可以用App Designer搭个简单界面。拖几个滑块控制幅度、频率、采样间隔实时刷新波形图。核心逻辑还是调用上面那些函数只是把输入从命令行改成GUI控件。我一般会保留一个“导出数据”按钮把当前生成的信号和频谱存成.mat文件方便后续分析。这个功能在写论文或做项目时特别实用——你不需要重新跑一遍代码直接加载数据就行。5.3 扩展到实际信号处理这套实验用的是理想信号实际工程中你面对的是带噪声的音频、传感器数据或者通信信号。把实验里的采样、频谱分析、滤波这套流程套上去基本框架不用大改只需要注意几点实际信号的频率范围未知先做频谱预览再定采样率噪声会让频谱变得毛糙需要加窗函数如hamming、blackman抑制泄漏滤波器设计要考虑实时性IIR滤波器阶数低但相位非线性FIR滤波器线性相位但阶数高5.4 验证方法改完代码后怎么确认没跑偏我的习惯是拿一个已知答案的简单信号做回归测试。比如生成一个x[n] cos(0.1*pi*n)的序列理论上它的DFT应该在k0.1*N处有一个峰值。跑一遍代码看峰值位置对不对。如果对得上说明整个流程没问题如果对不上就从采样、加窗、FFT逐段排查。从那以后我每次改完信号处理代码都强制走一遍这个“已知信号验证”流程。看起来多花了几分钟但省下了后面调试玄学问题的大把时间。希望这份实验记录能帮你少走点弯路顺利把信号分析与处理的实验跑通。本文还有配套的精品资源点击获取