简介:面向广东工业大学信息工程学院电子信息类学生的《信号与系统》实验报告文档,也可供学习信号处理与MATLAB仿真的读者参考。内容围绕连续时间信号在MATLAB中的表示、卷积运算、连续与离散LTI系统时域分析,以及傅里叶级数、傅里叶变换、拉普拉斯变换和Z变换等实验展开,并涉及采样、量化与离散信号运算。文档共92页,按实验目的、实验内容和结果分析组织,配有MATLAB代码与波形、响应曲线等结果图,便于对照理论验证计算过程。资源包仅含1个docx文件,大小约1.68MB,结构完整,便于检索和二次整理。已有1257人学习下载,适合需要完成课程实验、复盘MATLAB实现或查漏补缺的电子信息类学生使用。
1. 一次返工换来的教训:信号与系统实验报告到底要交付什么
交稿前一天晚上,A同学把四张图画在同一张纸上,实部和虚部叠成一条线,谁也说不清哪根是哪根,只能整段推倒重画。这份《信号与系统实验报告》的难点从来不在公式,而在于让每一条结论都能被一张图验证。某高校信息类专业的这门课,要求用 MATLAB 把连续时间信号、离散序列、卷积、傅里叶变换、拉普拉斯变换和 Z 变换一路跑通,十四个实验模块分四个实验单元,最后交出一份图、码、分析三者对得上的报告。很多人卡在同一处:代码能出图,但说不出参数为什么这么设,题目一换就崩。这里要交付的就是一套能照搬的流程——体系怎么拆、脚本怎么写、结果怎么分析、交稿前怎么自查,适合要交课程设计、实验报告或做毕设前期训练的人直接改。
2. 实验体系拆解:十四个模块归成四条主线与一份报告骨架
十四个实验模块看起来零散,实际上是一条完整的依赖链:先在 MATLAB 里把信号画出来,再对信号做运算,然后用卷积和变换去分析系统,最后把连续域的方法平移到离散域。拆不清这条链,写报告时就只能一章一章地抄代码,抄到第七章就不知道自己画的是什么了。
2.1 四条主线与它们之间的先修关系
我把整份报告压成四条主线,每条主线对应一组命令、一组必出的图,这样每个实验该产出什么,在动手之前就是确定的。
| 主线 | 覆盖的实验单元 | 核心命令 | 必须产出的图 |
|---|---|---|---|
| 连续信号的表示 | 实验一 | plot、axis、subplot、real/imag/abs/angle、square | 基本信号波形、复信号四分量 |
| 连续信号的运算与卷积 | 实验一后半、实验二 | 自定义分段函数、conv、fliplr | 时移反褶尺度变换后的波形、奇偶分量、卷积结果 |
| 连续 LTI 的频域分析 | 实验三 | fft/fftshift、傅里叶系数积分、tf/pzmap/bode | 频谱图、幅频相频特性、零极点图 |
| 离散信号与 Z 域 | 实验二后半、实验四 | stem、conv、filter、ztrans、zplane | 离散序列图、差分方程响应、Z 域零极点图 |
先修关系是硬的:第一条主线的t向量写不对,后面卷积的时间轴一定错位;阶跃函数没统一,(2-e^(-t))u(t)这类题在端点处就会和其他小问对不上。我一般建议按主线顺序写,别按实验编号顺序写,因为原文的章节编号本身就存在重复标题的情况——第二章和第三章同名,都是“连续时间信号在 MATLAB 中的表示”,这种结构在答辩时很容易被问住。
2.2 每个实验条目的五段式模板
报告里的每一个小问,我都固定成五段:实验目的、实验内容、实验代码、实验结果、结果分析。前三段是体力活,后两段才是分数所在。
结果分析不要写“如图所示,波形正确”,这种话等于没写。合格的写法是三句话:第一句把表达式和图上能读到的参数对上,比如振幅、角频率、初相、周期;第二句描述趋势,比如衰减包络、谱线间隔、极点位置;第三句做一次交叉验证,比如“图上量得周期约 2.09 s,与 2π/3 吻合,说明t向量的步长足够细”。
这三句话听着简单,但它逼着你回去看坐标轴刻度、看axis设的范围、看采样点数够不够,报告的严谨度就在这里被拉开。
2.3 报告骨架与脚本文件的组织方式
常见的翻车方式是所有小问塞进一个脚本,变量互相覆盖,回头找一个图要翻两百行。我的做法是一个实验单元一个脚本,公共函数单独成文件,报告里的图号与脚本里的注释一一对应。
signals_lab/ ├── uCT.m % 自定义单位阶跃,全篇统一调用 ├── functl.m % 分段函数,时移反褶尺度变换共用 ├── exp1_signal_basic.m % 实验一:基本信号与复信号 ├── exp1_signal_op.m % 实验一后半:变换、奇偶分解 ├── exp2_conv_lti.m % 实验二:卷积与连续 LTI 时域 ├── exp3_fourier.m % 实验三:傅里叶级数与频谱 ├── exp4_laplace_pz.m % 实验四:拉普拉斯与零极点 └── exp4_z_transform.m % 实验四:离散与 Z 域每个脚本开头写一行注释标明它对应报告的哪一节、出哪几张图,比如% 对应 2.3.2 复信号四分量,出图 2-5。这样中期检查时导师随手点开一个脚本,两秒钟就能定位到对应段落,省下的都是自己的时间。
3. 连续时间信号的 MATLAB 表示:采样向量、阶跃函数与波形变换
这一章是全篇的地基。后面所有卷积、频谱、零极点的图,本质上都是在一个t向量上算出来的值再画出来,地基歪了,后面全是玄学。
3.1 t 向量的三个参数怎么定
t = 起点 : 步长 : 终点这三个参数里,最容易被随手乱写的是步长。步长太大,正弦波被画成折线;步长太小,向量长度爆炸,跑起来卡。
% 画 x(t) = 2cos(3t + pi/4),观察区间 [-pi/12, 2pi] t = -pi/12 : 0.01 : 2*pi; % 步长取周期的 1/200 左右比较稳妥 x = 2*cos(3*t + pi/4); % 振幅 2,角频率 3 rad/s,初相 pi/4 plot(t, x, 'LineWidth', 1.2); grid on; axis([-pi/12, 2*pi, -2.2, 2.2]); % 手动定范围,避免自动缩放留出大片白边 xlabel('t / s'); ylabel('x(t)'); title('2.3.1(1) 2cos(3t+\pi/4)');这里信号的角频率是 3 rad/s,周期 2π/3 ≈ 2.09 s,步长 0.01 意味着一个周期里约 209 个采样点,曲线足够光滑。如果步长写成 0.5,一个周期只剩四个点,画出来是折线,答辩时被问一句“你这个正弦怎么不圆”就很难接。axis的纵向范围我给到 ±2.2,比振幅 2 略宽一点,波形不会贴着边框。
3.2 阶跃信号:三种写法与各自的坑
同一份报告里出现三种阶跃写法,是结果对不上的主要原因。MATLAB 自带的heaviside(0)返回 0.5,而教材定义的 u(0) 通常取 1 或不讨论,混用就会出现端点值差一截。
function y = uCT(t) % 自定义单位阶跃:t >= 0 取 1,其余取 0 % 用逻辑数组转换,避免 heaviside(0) = 0.5 带来的端点差异 y = double(t >= 0); end定义好之后,(2-e^(-t))u(t)这类题就写得很干净:y = (2 - exp(-t)) .* uCT(t);。这里的点乘不能省,exp(-t)是向量,uCT(t)也是向量,用*会触发矩阵乘法报错,这是初学者最常见的报错之一。
另外几个信号可以顺手一起写:t.*(uCT(t)-uCT(t-1))是宽度为 1 的斜坡窗,(1+cos(pi*t)).*(uCT(t)-uCT(t-2))是两秒的余弦窗。用两个阶跃相减构造矩形窗,比写t>=0 & t<=1更贴教材表达,分析段也好写。占空比 0.5、幅度 1、周期 1 的矩形脉冲,直接用square(2*pi*t, 50),第二个参数就是占空比百分数。
3.3 复信号的四个分量:subplot 索引别写重
复信号要画实部、虚部、模、辐角四张图,subplot(2,2,k)的顺序一旦写错,后画的会盖掉先画的。
t = -5 : 0.01 : 10; y = 2 + exp(1j*(pi/4)*t) + exp(1j*(pi/2)*t); % 两个旋转相量加一个直流 subplot(2,2,1); plot(t, real(y)); title('实部'); grid on; subplot(2,2,2); plot(t, imag(y)); title('虚部'); grid on; subplot(2,2,3); plot(t, abs(y)); title('模'); grid on; subplot(2,2,4); plot(t, angle(y)); title('相角'); grid on;angle的值域是 (-π, π],相量转一圈就会从 π 跳到 -π,画出来是锯齿状。这恰恰说明了辐角的周期性,不是错误,但分析里要主动点出来,否则看图的人会以为程序坏了。如果想让曲线连续,可以套一层unwrap,不过实验报告里我更倾向保留原始跳变,再配一句说明,这样更能体现对定义的理解。
3.4 时移、反褶、尺度变换:一个函数文件走完全部小问
这一组小问最容易写成五段互不相干的代码。正确姿势是先写一个分段函数文件,后面所有变换都只是改调用参数。
function y = functl(t) % 分段函数 f(t):[-2,-1] 上升,[-1,0] 平台 1,[0,1] 平台 2,[1,2] 下降 y = (t+1) .* ((t>=-2) - (t>=-1)) ... + 1 .* ((t>=-1) - (t>= 0)) ... + 2 .* ((t>= 0) - (t>= 1)) ... + (2-t) .* ((t>= 1) - (t>= 2)); end((t>=-2) - (t>=-1))这个写法是关键:两个逻辑数组相减,得到的是一个只在 [-2,-1) 区间取 1 的窗口,不用写循环也不用if,天然支持向量输入。
有了它,四个变换小问只是改参数:
| 小问 | 调用写法 | 变换解读 | 横轴建议范围 |
|---|---|---|---|
| f(t-1) | functl(t-1) | 右移 1 | [-3, 3] |
| f(2-t) | functl(2-t) | 反褶后右移 2 | [-2, 5] |
| f(2t+1) | functl(2*t+1) | 压缩到 1/2 再左移 0.5 | [-2, 1] |
| f(4-t/2) | functl(4-t/2) | 反褶展宽 2 倍再右移 8 | [3, 14] |
写之前先化成 f(a(t+b/a)) 的标准形式,尺度因子 a 决定横轴压缩倍数,位移量算错一个符号整张图就移到画面外,axis一裁就是一片空白。
奇偶分量分解则是另一个套路,靠向量反转实现:
t = -3 : 0.01 : 3; % 必须关于 0 对称,fliplr 才等价于 f(-t) f = (t>=0 & t<=2) .* (1-t); fm = fliplr(f); % 反转后第 k 点正好对应 -t(k) fe = (f + fm)/2; % 偶分量 fo = (f - fm)/2; % 奇分量fliplr成立的前提是采样点关于原点对称且等间隔,-3:0.01:3一共 601 个点,正好满足。有人把区间写成0:0.01:3,翻转后对应的是3:-0.01:0而不是负时间,画出来的偶分量自然不对。
4. 卷积与频域分析:从 conv 到 fft、拉普拉斯零极点的落地写法
时域看完波形,接下来要回答“系统对输入做了什么”。这一章的四类图——卷积结果、频谱、幅频相频、零极点——是整份报告的技术核心,也是答辩时提问密度最高的部分。
4.1 连续卷积的数值近似:步长就是精度
MATLAB 的conv算的是离散求和,要近似连续卷积的积分,必须乘采样间隔,时间轴也要跟着改。
dt = 0.01; t1 = 0 : dt : 2; x1 = double(t1>=0 & t1<=1); % 宽 1 的矩形脉冲 t2 = 0 : dt : 3; x2 = exp(-t2); % 单边指数 y = conv(x1, x2) * dt; % 乘 dt 才是积分近似 ty = (t1(1) + t2(1)) + (0:length(y)-1)*dt; % 卷积后时间轴起点为两者之和 plot(ty, y); grid on; xlabel('t / s'); title('矩形脉冲与指数信号卷积');三个容易漏的点:第一,conv输出长度是 N1+N2-1,不是任意取;第二,输出时间轴起点是两个输入起点之和,这里都是 0,所以从 0 开始;第三,不乘dt的话幅值会大两个数量级,和解析结果对不上,很多报告就在这里被扣分。
验证方式很简单:矩形宽度 1 与 e^(-t) 卷积,结果应该是 0 到 1 区间内按 1-e^(-t) 上升,1 之后按指数衰减。图上取两个点对一下数,分析段就有实打实的内容可写。
4.2 周期信号的傅里叶级数与频谱
周期矩形脉冲的频谱是最适合拿来做验证的例子,因为它的包络是 sinc,零点位置可以手算。
N = 1024; Ts = 0.001; t = (0:N-1)*Ts; x = square(2*pi*t/1, 50); % 周期 1 s,占空比 50% 的方波 X = fftshift(fft(x))/N; % 归一化并把零频移到中心 f = (-N/2 : N/2-1)/(N*Ts); % 频率轴,单位 Hz stem(f, abs(X), 'filled'); xlim([-5 5]); grid on; xlabel('f / Hz'); title('周期方波的双边幅度谱');周期 1 s 的方波,谱线只出现在整数赫兹上,间隔 1 Hz,包络零点在 2、4、6 Hz。fftshift不写,零频就跑到最左边,画出来的谱看着像只有正频率;除以 N 不写,幅度值会随采样点数变化,换个 N 幅值就变,结论没法写。
如果题目要求算的是理论傅里叶系数,也可以用符号计算求一个周期内的积分,再和数值谱对照。两条路走一遍,能确认自己的fft用法没跑偏。
4.3 拉普拉斯变换与零极点:稳定与否看左半平面
到这一章,图从时域波形换成了复平面上的叉和圈。用tf建模,roots求极点,pzmap出图,是最省事的组合。
num = [1 3]; den = [1 4 13]; sys = tf(num, den); p = roots(den); % 极点 -2 ± 3j,实部为负,冲激响应按指数衰减 z = roots(num); % 零点 -3 pzmap(sys); grid on; % 叉为极点,圈为零点,左侧半平面为收敛区den的系数按 s 的降幂排列,缺项要补 0,这一点写错整张零极点图就偏了。极点实部为负说明冲激响应随时间衰减、系统收敛;实部为零落在虚轴上,是等幅振荡的临界情况;实部为正则响应发散。这三句话几乎是必考题,报告的分析段要明确写出“极点位于 s 左半平面”这类判断,而不是只说“图上有两个叉”。
部分分式展开用residue,把num、den传进去,直接得到留数、极点和直接项,正好对应拉普拉斯逆变换的三类情形。
4.4 离散序列与 Z 域:stem 与 plot 不能混用
从连续域切到离散域,第一件事是把plot换成stem。离散序列用折线连起来,视觉上会被误读成连续信号,这是报告里最扎眼的低级错误。
n = -5 : 15; x = (0.8.^n) .* (n>=0); % 单边指数序列,底数 0.8 保证收敛 stem(n, x, 'filled'); grid on; xlabel('n'); title('0.8^n u[n]');底数绝对值小于 1 序列收敛,等于 1 是单位阶跃,大于 1 发散,写分析时把这三档说清楚,等于把整个 Z 域收敛条件讲明白了。
差分方程求响应可以手写递推,也可以直接filter(b, a, x),b是输入侧系数、a是输出侧系数,顺序别反。Z 变换用ztrans做符号计算,零极点用zplane(b, a)出图,单位圆内外的分布直接对应系统是否收敛。连续域那套“左半平面”的判断,在离散域就换成“单位圆内”,两章对照着写,逻辑会顺很多。
5. 常见问题排查:五个让实验报告返工的高频坑
改报告改到第三版的时候,问题往往已经不在理论上了,全在这些细节里。下面五条是我见过返工率最高的,每条都按现象、原因、解决的顺序排。
5.1 四张子图只显示一条曲线
现象:复信号的实部、虚部、模、相角四张子图,其中某一张里出现了两条叠在一起的线,或者干脆只剩最后画的那条。
原因:subplot(2,2,k)的索引写重了,先plot(t, real(y))再plot(t, imag(y)),第二个plot默认会在同一坐标系里追加,前一条曲线就被压在下面;另一种情况是subplot写成了subplot(2,2,1)两次,第四张图跑到了第一格。
解决:四个subplot索引严格写 1、2、3、4,每格只放一条曲线;确实需要对比两条时,用plot(t, a, t, b)并加legend明确标注。交稿前把脚本从头跑一遍,逐格看标题和曲线是否匹配。
5.2 Undefined function 'uCT' 或 'functl'
现象:主脚本单独运行没问题,一换电脑或者换个文件夹就报未定义函数,红色报错直接中断。
原因:自定义函数写在了脚本末尾,或者文件名和函数名不一致。MATLAB 要求函数文件名与函数名完全相同,functl.m里必须定义function y = functl(t),且文件要放在当前工作目录或搜索路径里。
解决:公共函数一律单独成.m文件,与调用脚本放在同一个文件夹;函数体内第一行写清输入输出含义,方便复用。换机器前把整个文件夹打包,别只拷主脚本。
5.3 波形是折线、锯齿或者整张图空白
现象:正弦波画出来棱角分明,或者坐标轴范围给错,曲线整个跑到画面外,只剩一片空白网格。
原因:三种可能——步长太大导致采样点不够;axis手动设的范围与信号实际幅值不匹配;矩阵乘法*误用在向量上,结果维度对不上直接报错或画出怪图。
解决:步长按“每周期至少 100 个点”来估,频率越高步长越小;axis的范围先看max(abs(y))再定,别凭感觉写;向量运算一律用.*、./、.^。图出来先看横纵刻度和标题,再决定要不要改。
5.4 卷积结果幅值差一个数量级
现象:卷积波形形状对得上解析解,但幅值明显偏大,取峰值一对比差了几十倍上百倍。
原因:conv求的是离散求和,近似连续卷积的积分时少了采样间隔dt;另一种是时间轴没重算,直接把t1拿来当输出横轴,长度对不上导致后半段错位。
解决:y = conv(x1, x2) * dt,输出时间轴用(t1(1)+t2(1)) + (0:length(y)-1)*dt。分析段里把峰值和解析值各写一遍,数字对上了再往下写。
5.5 结果分析写成“如图所示,波形正确”
现象:每张图下面一句话带过,通篇没有具体数字,导师批注“分析空洞”。
原因:写的时候只盯着图好不好看,没有回头读表达式,也没有量化意识。
解决:固定三句话结构——先报参数(振幅、周期、谱线间隔、极点坐标),再说趋势(衰减、压缩、收敛),最后做一次交叉验证(图上量到的值与理论值误差多少)。三句话不到一百字,但每一句都能被追问,也能被验证。
6. 验收与答辩:交稿前自己跑一遍的三张检查表
报告写到最后一页,最容易松懈,而返工往往就出在这一步。我现在交稿前固定走三张表,走完再合上电脑。
第一张是图码对应表。报告里每一张图,都能在脚本里找到唯一一段生成它的代码,图号、脚本名、变量名三者对得上。做法很简单:把脚本从头跑到尾,按出现顺序数图,和正文里的“图 3-2”逐个核对。原报告里那种两章同名、图号跳号的情况,基本都是没做这一步。
第二张是参数自洽表,重点核三类数:
| 检查项 | 判定标准 | 不合格怎么处理 |
|---|---|---|
| 采样步长 | 每周期采样点数不少于 100 | 减小步长重跑,图重新导出 |
| 坐标轴范围 | 波形完整落在框内且留 10% 余量 | 用 max(abs(y)) 定上下限 |
| 卷积幅值 | 与解析解峰值相对误差小于 5% | 检查是否漏乘 dt、时间轴是否错位 |
| 变换后的横轴 | 起点、终点与理论位移量一致 | 按 f(a(t+b/a)) 重算范围 |
| 极点位置 | 实部符号与响应收敛性一致 | 核对 den 系数是否有缺项未补 0 |
第三张是答辩问答表。把每张图可能被问的三个问题先写下来:这个参数为什么取这个值?换一个输入图会怎么变?这条曲线和上一章的哪条结论呼应?三张表走完,报告里基本没有答不上来的图。
血泪经验是:不要等到打印前才通读。我一般会在写完第四章的时候回头重跑一次第一章的脚本,因为那时候你对axis、步长、点乘的理解已经比第一天清楚,能一眼看出早期图的毛病。从那以后我每次交实验报告,都强制自己按“图码对应、参数自洽、答辩问答”走一遍,宁可少写半页分析,也不留一张说不清来路的图。这套报告的脚本、函数文件和章节骨架,按上面的结构整理好之后是可以直接改题目复用的,需要的话拿去对着改就行。希望帮到你。
本文还有配套的精品资源,点击获取