简介:这份资源是面向通信工程、电子信息工程等专业本科生与研究生的信号与系统综合实验报告,围绕连续时间LTI系统的时域与频域分析展开,帮助读者借助Matlab完成从理论到仿真的完整训练。内容涵盖稳定4~6阶系统的零极点设计、直接/级联/并联三种实现结构的信号流图与特性对比、参数微扰下的稳定性与频响敏感性分析,以及周期信号频谱分析和LTI滤波器设计,并延伸到音频信号的获取、输出与频谱分析。资源包为1个docx文档,约2.62MB,内含详细实验步骤、Matlab代码实现与结果分析,可直接用于课堂教学或自主学习。目前已有1303人学习下载,适合希望深入理解系统函数零极点分布、频率特性与稳定性关系,并提升仿真与工程分析能力的读者参考。
1. 从一份“A-”实验报告说起:这套 MATLAB 连续时间 LTI 系统实验到底能跑出什么
如果你正在学信号与系统,大概率会被“零极点分布决定频率特性”这句话折磨过——书上画得明明白白,一到自己动手就发现:极点靠近虚轴到底会翘多高?直接型、级联型、并联型换个结构,系数动万分之一,结果能差多少?这份基于 MATLAB 的连续时间 LTI 系统综合实验,就是冲着这些“纸上看懂、动手翻车”的环节来的。它把时域响应、频域分析、零极点图、滤波器设计、音频信号采集串成一条完整链路,从基础验证一路做到应用设计。适合通信、电子信息类本科生,也适合想用 MATLAB 把信号处理概念重新夯实一遍的从业者。下面我按自己复现的顺序,把关键步骤、参数和踩过的坑拆开讲。
2. 时域与频域分析:从系统函数到冲激响应和阶跃响应
2.1 为什么先看零极点,再看响应
连续 LTI 系统的全部特性都压在系统函数 H(s) 上。极点位置决定时域响应的衰减还是发散:左半平面衰减,右半平面增长,虚轴上等幅。如果虚轴上有二重及以上的极点,系统直接不稳定。这套实验要求设计一个 4~6 阶稳定系统,并且至少有一对靠近虚轴的共轭复数极点——目的就是让你亲眼看到那对极点如何在幅频响应上顶出一个尖峰。
我一般会先手算一遍零极点,再用 MATLAB 验证。实验里给的例子是:
syms s t w Hs = (2.8*s + 1.99) / ((s^2 + 0.2*s + 0.01) * (s + 1) * (s + 2));分母展开后是 4 阶,极点分别在 -0.1±0.1j 附近(靠近虚轴的一对)、-1、-2。那对靠近虚轴的共轭极点,实部只有 -0.1,距离虚轴很近,所以幅频响应会在 ω≈0.1 rad/s 附近出现明显峰值。零点在 -1.99/2.8≈-0.71,离虚轴不算近,主要影响高频段的衰减斜率。
2.2 冲激响应和阶跃响应的 MATLAB 实现
求冲激响应最直接的方式是用ilaplace做拉普拉斯逆变换,再乘heaviside(t)保证因果性:
syms s t w Hs = (2.8*s + 1.99) / ((s^2 + 0.2*s + 0.01) * (s + 1) * (s + 2)); h = ilaplace(Hs) * heaviside(t); subplot(2,2,1); ezplot(h); title('h(t)'); Hw = fourier(h); subplot(2,2,2); ezplot(abs(Hw)); title('|H(jw)|'); axis([-6,6,-1,5]); P = angle(Hw); subplot(2,2,3); ezplot(P); title('相位');这里有几个参数要留意。ezplot在较新版本 MATLAB 里已经不推荐,但实验环境通常还能跑;如果报错,换成fplot并指定区间即可。axis([-6,6,-1,5])是手动限定坐标范围,因为靠近虚轴的极点会让幅频峰值很高,不限制的话其他细节全被压扁。相位图用angle取弧度,如果要看角度制,乘180/pi。
阶跃响应可以用step函数直接求,也可以走频域:阶跃信号的傅里叶变换乘上 H(jw),再逆变换回去。实验里用的是后者:
ft = heaviside(t); F = fourier(ft); Y = F * Hw; y = ifourier(Y); ezplot(abs(Y));注意:
fourier(heaviside(t))在符号计算里会带上 πδ(ω) 项,直接做数值逆变换时容易出数值问题。如果只是看阶跃响应的波形,建议直接用step(b, a, t),把系数转成向量形式更稳。
2.3 频域卷积定理在截断信号频谱分析里的体现
拓展部分要求构建 f(t)=cos(t)+cos(2t),截取不同长度分析频谱。这里核心是频域卷积定理:时域乘积对应频域卷积除以 2π。截断相当于乘了一个矩形窗,矩形窗的频谱是 sinc 函数,所以截断后的频谱是原信号频谱与 sinc 的卷积——原本的两根谱线会被“抹开”成 sinc 形状。
r = 0.02; t = -10:r:0; % 截取 -10 到 0 N = 200; W = 2*pi; k = -N:N; w = k * W / N; f = cos(t) + cos(2*t); F = r * f * exp(-j*t'*w); % 数值积分近似傅里叶变换 F1 = abs(F); P1 = angle(F); subplot(3,1,1); plot(t,f); xlabel('t'); ylabel('f(t)'); title('f(t)'); subplot(3,1,2); plot(w,F1); xlabel('w'); ylabel('F(jw)'); grid; subplot(3,1,3); plot(w,P1*180/pi); xlabel('w'); ylabel('度'); grid;r是时间步长,决定数值积分精度;N决定频率分辨率,W是频率范围。截取长度从 -10 到 0、-5 到 0、-10 到 10 三种情况对比,截得越短,频谱展宽越严重,旁瓣越明显。这就是频域卷积定理在“截断效应”上的直接体现。
3. 三种实现结构的参数敏感性:直接型、级联型、并联型到底差在哪
3.1 结构差异为什么会影响稳定性
同一个系统函数,可以用直接型、级联型、并联型三种结构实现。数学上它们完全等价,但在有限精度下,系数的微小变化对零极点位置的影响完全不同。直接型把所有系数放在一个高阶多项式里,某个系数动一点,所有极点都可能跟着跑;级联型和并联型把系统拆成多个二阶节,每个二阶节只负责一对零极点,调整一个节的系数基本不影响其他节。
实验里用tf2sos做直接到级联的转换,用tf2zp和zp2tf做直接到并联的转换:
a = [1, 2.2, 3.41, 0.62, 0.035]; % 原分母系数 b = [0, 0, 0, 2.8, 1.99]; % 原分子系数 a1 = [1, 2.2, 3.41, 0.62, 0.01]; % 微量改变后的分母系数 [sos, G] = tf2sos(b, a); % 直接到级联 [b2, a2] = sos2tf(sos, G); % 级联回到传递函数 [z, p, k] = tf2zp(b, a); % 直接到零极点 [b3, a3] = zp2tf(z, p, k); % 零极点回到传递函数 subplot(2,2,1); pzmap(b, a); title('未改变的零极点图'); subplot(2,2,2); pzmap(b, a1); title('直接系数改变的零极点图'); subplot(2,2,3); pzmap(b2, a2); title('级联系数改变的零极点图'); subplot(2,2,4); pzmap(b3, a3); title('并联系数改变的零极点图');这里a1只把最后一个系数从 0.035 改成 0.01,变化量不到 0.03。直接型的零极点图会看到极点明显偏移,而级联型和并联型的零极点几乎不动。这就是结构敏感性的直观对比。
3.2 参数微调后时域和频域的对比方法
光看零极点图还不够,要同时对比幅频响应、相频响应和阶跃响应。实验里的做法是用freqs求频率响应,用step求阶跃响应:
w = -4:0.01:4; h = freqs(b, a, w); h1 = freqs(b, a1, w); h2 = freqs(b2, a2, w); h3 = freqs(b3, a3, w); figure(1); subplot(2,1,1); plot(w, abs(h)); title('系数未改变的幅频响应'); subplot(2,1,2); plot(w, angle(h)); title('系数未改变的相频响应'); figure(2); subplot(2,1,1); plot(w, abs(h1)); title('直接系数改变的幅频响应'); subplot(2,1,2); plot(w, angle(h1)); title('直接系数改变的相频响应'); figure(3); subplot(2,1,1); plot(w, abs(h2)); title('级联系数改变的幅频响应'); subplot(2,1,2); plot(w, angle(h2)); title('级联系数改变的相频响应'); figure(4); subplot(2,1,1); plot(w, abs(h3)); title('并联系数改变的幅频响应'); subplot(2,1,2); plot(w, angle(h3)); title('并联系数改变的相频响应');freqs的输入是分子系数向量b、分母系数向量a和频率向量w。注意b和a的系数顺序是从高阶到低阶,缺项要补零。比如b = [0, 0, 0, 2.8, 1.99]表示分子是 2.8s+1.99,前面三个零对应 s³、s²、s¹ 的系数为零。
阶跃响应的对比更直接:
t = 0:0.01:80; subplot(2,2,1); step(b, a, t); title('系数未改变的阶跃响应'); subplot(2,2,2); step(b, a1, t); title('直接系数改变的阶跃响应'); subplot(2,2,3); step(b2, a2, t); title('级联系数改变的阶跃响应'); subplot(2,2,4); step(b3, a3, t); title('并联系数改变的阶跃响应');时间向量t取到 80 秒,是因为靠近虚轴的极点衰减很慢,时间太短看不到稳态。如果只取到 10 秒,直接型改变后的响应可能还在振荡,误以为系统不稳定。
3.3 结构选择的工程判断
从实验结果看,直接型对系数变化最敏感,级联型次之,并联型最稳。但这不是说直接型不能用——如果系统阶数低、系数精度足够,直接型实现最简单。工程上常见的做法是:阶数超过 4 阶就用级联型或并联型,需要独立调整某个频段就用并联型,需要精确控制零点就用级联型。这个判断在实验报告里不一定写,但实际做滤波器设计时绕不开。
4. 滤波器设计与音频信号处理:从零极点配置到 wav 文件读写
4.1 用零极点配置设计一个带阻滤波器
拓展部分要求设计一个 LTI 连续系统作为滤波器,对 f(t)=cos(t)+cos(2t) 进行滤波。实验给的 H(s) 是:
syms s t Hs = (s^2 - 0.2*s + 1.97) / (s^2 + 0.2*s + 1.01);零点在 0.1±1.4j,极点在 -0.1±1.4j。零点靠近虚轴,会在 ω≈1.4 rad/s 附近产生谷值;极点也在附近但实部为负,产生峰值。两者相互抵消一部分,最终形成一个带阻特性。用freqs看频率响应:
b = [1, -0.2, 1.97]; a = [1, 0.2, 1.01]; w = -6:0.01:6; H = freqs(b, a, w); subplot(2,1,1); plot(w, abs(H)); title('|H(jw)|'); grid; subplot(2,1,2); plot(w, angle(H)*180/pi); title('相位'); grid;如果要滤除 cos(t) 保留 cos(2t),需要让阻带中心对准 ω=1 rad/s。调整零点位置到 ±j 附近,极点保持在左半平面稍远一点,就能实现。这里的关键是:零点决定谷值频率,极点决定峰值频率和带宽,零点越靠近虚轴,谷值越深。
4.2 音频信号的采集、读写与频谱分析
应用设计部分用audiorecorder录音,audiowrite存 wav,audioread读回,再做 FFT:
y = audiorecorder; disp('Start speaking.'); recordblocking(y, 3); % 录音 3 秒 disp('End of Recording.'); play(y); % 回放 myRecording = getaudiodata(y); % 获取录音数据 plot(myRecording); % 绘制波形 filename = 'luyin.wav'; audiowrite(filename, myRecording, 8000); % 采样率 8000 Hz [y, fs] = audioread(filename); sound(y, fs); Y = fft(y, 8000); % 8000 点 FFT subplot(2,1,1); plot(y); title('声音信号的波形'); subplot(2,1,2); plot(abs(Y)); title('声音信号的频谱');采样率 8000 Hz 对应奈奎斯特频率 4000 Hz,语音信号的主要能量在 300~3400 Hz,够用。fft(y, 8000)如果 y 长度不足 8000 会自动补零,超过则截断。补零能提高频率分辨率,但不会增加真实信息量——这是新手最容易误解的地方。
注意:
wavrecord在较新 MATLAB 版本已经移除,必须用audiorecorder。wavread和wavwrite也被audioread和audiowrite取代。如果实验指导书还是老版本命令,直接换新函数,参数含义基本一致。
5. 避坑与排查:复现这套实验时最容易翻车的五个地方
5.1 符号计算和数值计算混用导致结果对不上
现象:用ilaplace求出的 h(t) 和用impulse数值求出的波形形状对不上,或者fourier变换后画图报错。
原因:符号计算返回的是解析表达式,ezplot画图时默认区间可能和数值计算不一致;fourier对heaviside的处理会引入冲激项,数值绘图时无法显示。
解决:时域波形统一用数值函数impulse(b,a,t)和step(b,a,t),频域用freqs(b,a,w)。符号计算只用来推导表达式,不直接用于最终绘图。
5.2 系数向量缺项没补零导致系统阶数错误
现象:freqs或step画出来的波形和预期完全不符,或者报“向量长度不一致”。
原因:传递函数的分子或分母有缺项时,系数向量必须补零。比如 H(s)=(2.8s+1.99)/(s⁴+2.2s³+3.41s²+0.62s+0.035),分子向量应该是[0,0,0,2.8,1.99],不是[2.8,1.99]。
解决:写系数向量前先把分子分母按降幂排列,缺哪一项就补零。用tf2zp和zp2tf转换时也要注意这一点。
5.3 截断长度选得太短导致频谱展宽误判
现象:截取信号做 FFT 后,频谱里原本的两根谱线变成一片,以为信号本身有问题。
原因:截断相当于加矩形窗,窗长越短,频域卷积的 sinc 主瓣越宽,谱线展宽越严重。如果截取长度小于最低频率分量的一个周期,频谱完全失真。
解决:截取长度至少包含最低频率分量的一个完整周期。实验里 f(t)=cos(t)+cos(2t),最低频率是 1 rad/s,对应周期 2π≈6.28 秒,所以截取 -10 到 0 是合理的,-5 到 0 就偏短了。
5.4 参数微调幅度过大导致系统直接不稳定
现象:把某个系数改了 5% 以上,零极点图显示极点跑到右半平面,阶跃响应发散。
原因:靠近虚轴的极点对系数变化极其敏感,直接型结构下尤其明显。实验建议变化量在万分之一到 5% 之间,超过这个范围就不是“微量改变”了。
解决:从万分之一开始试,逐步增大到 1%、2%,观察零极点移动趋势。如果直接型在 1% 时就不稳定,说明系统本身裕度很小,换级联型或并联型再试。
5.5 音频采样率设置不当导致混叠
现象:录音回放时声音变调,或者频谱里出现明显的高频杂散。
原因:采样率低于信号最高频率的两倍,产生混叠。语音信号如果包含 4 kHz 以上分量,用 8000 Hz 采样就会混叠。
解决:录音前确认声卡支持的采样率,语音场景用 8000 Hz 或 11025 Hz,音乐场景用 44100 Hz。如果发现混叠,在录音后加一个抗混叠低通滤波器,截止频率设为采样率的一半。
6. 进阶技巧:用freqs和pzmap快速验证滤波器设计
设计完滤波器后,我习惯先用pzmap看零极点分布,再用freqs看频率响应,最后用lsim跑一遍实际信号。这三步走完,基本能判断滤波器是否达标。
% 设计一个带通滤波器:零点在 ±j2,极点在 -0.5±j2 b = [1, 0, 4]; % s^2 + 4,零点 ±j2 a = [1, 1, 4.25]; % s^2 + s + 4.25,极点 -0.5±j2 % 第一步:零极点图 figure(1); pzmap(b, a); title('零极点分布'); % 第二步:频率响应 w = 0:0.01:10; H = freqs(b, a, w); figure(2); subplot(2,1,1); plot(w, abs(H)); title('幅频响应'); grid; subplot(2,1,2); plot(w, angle(H)*180/pi); title('相频响应'); grid; % 第三步:实际信号滤波 t = 0:0.01:20; f = cos(t) + cos(2*t) + cos(5*t); % 三个频率分量 y = lsim(tf(b, a), f, t); % 用 lsim 求输出 figure(3); subplot(2,1,1); plot(t, f); title('输入信号'); grid; subplot(2,1,2); plot(t, y); title('输出信号'); grid;pzmap的输入是分子分母系数向量,画出的图里叉号是极点,圆圈是零点。freqs的w范围要覆盖你关心的频段,太窄看不到阻带衰减,太宽浪费计算。lsim的输入是系统对象、输入信号和时间向量,输出是时域响应。如果lsim报错说系统不是 proper 的(分子阶数高于分母),说明传递函数写反了。
从那以后我每次设计完滤波器,都强制走一遍“零极点图→频率响应→实际信号”这三步,不看到时域波形和频域响应同时符合预期,绝不往下做。希望帮到你。
本文还有配套的精品资源,点击获取