
简介这份华南理工大学信号与系统实验报告四面向电子信息、通信工程等专业学生及信号处理初学者聚焦时域抽样定理与频域抽样定理的验证与理解。报告围绕抽样频率对信号重构的影响、幅度调制信号频率特性、信号抽样与重建、频域抽样与时域混叠四个实验展开结合代码与波形图分析奈奎斯特采样定理的工程意义并附有实验思考题与感想可帮助读者掌握离散化过程的数学与物理概念。资源包共1个doc文件约276KB内容为完整实验报告文档便于直接查阅与参考。目前已有728人学习下载适合需要完成同类实验、复习抽样定理或准备信号处理课程考核的读者对照使用。1. 信号与系统实验四从“波形能画出来”到“参数能讲清楚”很多同学做信号与系统实验卡在实验四这一步前面几个实验还能照着步骤连一连、点一点到了实验四突然要求你对采样、卷积、频谱这些概念给出定量解释波形是画出来了但一问“为什么这个参数下波形长这样”就答不上来。这个实验的核心其实是把“信号与系统”从纸面公式拉到可运行的仿真环境里用离散采样去逼近连续信号再用卷积和频谱去验证系统特性。它适合正在上这门课、需要交实验报告但不想只抄步骤、想真正搞懂参数含义的本科生。我当年做这个实验时第一次跑出混叠波形还以为是代码写错了后来才发现是采样率设成了信号最高频率的两倍以下——这个坑后面会细说。2. 实验四到底在仿真什么采样、卷积与频谱的三条主线2.1 为什么实验四总绕不开“采样率”这个参数信号与系统实验四通常不会只让你画一个正弦波而是要求你观察连续信号经过采样后在离散域里发生了什么。这里最关键的参数就是采样频率 ( f_s )。常见做法是先定义一个连续时间信号比如 ( x(t)\sin(2\pi f_0 t) )然后以 ( f_s ) 对它采样得到离散序列 ( x[n]x(nT_s) )其中 ( T_s1/f_s )。如果你把 ( f_s ) 设得比 ( 2f_0 ) 小就会看到混叠原本高频的正弦在离散序列里看起来像低频。这不是代码 bug而是采样定理的直接结果。实验四往往要求你分别取 ( f_s 2f_0 )、( f_s 2f_0 )、( f_s 2f_0 ) 三组参数画出离散序列并比较。很多报告只贴三张图却不解释为什么 ( f_s 2f_0 ) 时波形也不理想——因为临界采样对相位和重建滤波器要求极高实际仿真里稍微偏移一点重建就会失真。我一般会建议在实验报告里加一张表把三组参数下的“观察到的频率”和“理论频率”列出来这样老师一眼就能看出你理解了混叠。表格比堆图更有说服力。2.2 离散卷积从公式到可运行代码的最小闭环实验四的另一条主线是卷积。连续卷积 ( y(t)x(t)*h(t) ) 在仿真里通常转成离散卷积 ( y[n]x[n]*h[n] )。这里最容易翻车的地方是很多同学直接调用conv函数但忘了卷积结果的长度是 ( NM-1 )画图时时间轴对不上导致波形“漂移”。一个可复现的最小闭环是这样的先定义输入序列 ( x[n] ) 和系统冲激响应 ( h[n] )用conv得到 ( y[n] )然后构造正确的离散时间轴。下面这段 Python 代码可以直接抄作业import numpy as np import matplotlib.pyplot as plt # 定义离散时间轴n 从 0 到 19 n np.arange(0, 20) # 输入信号指数衰减序列 x np.exp(-0.3 * n) # 系统冲激响应长度为 5 的矩形窗 h np.ones(5) # 离散卷积结果长度为 len(x)len(h)-1 y np.convolve(x, h, modefull) # 构造卷积结果对应的时间轴 n_y np.arange(0, len(y)) plt.figure(figsize(10, 6)) plt.subplot(3, 1, 1) plt.stem(n, x, basefmt ) plt.title(输入序列 x[n]) plt.subplot(3, 1, 2) plt.stem(np.arange(len(h)), h, basefmt ) plt.title(冲激响应 h[n]) plt.subplot(3, 1, 3) plt.stem(n_y, y, basefmt ) plt.title(卷积结果 y[n]) plt.tight_layout() plt.show()这段代码的逻辑说明np.convolve的modefull返回完整卷积长度是 ( NM-1 )。参数说明x的长度是 20h的长度是 5所以y的长度是 24。如果你用modesame长度会变成 20但那是为了对齐中心实验报告里通常要求完整卷积所以用full。时间轴n_y必须从 0 开始长度与y一致否则stem画出来会错位。2.3 频谱分析FFT 之后横轴到底怎么标实验四通常还会要求你对信号做频谱分析。很多同学用fft算完直接plot(abs(Y))结果横轴是 0 到 ( N-1 )完全看不出频率成分。正确的做法是构造频率轴( f_k k \cdot f_s / N )其中 ( k0,1,\dots,N-1 )。如果只看正频率就取前 ( N/2 ) 个点。这里有个血泪经验如果信号不是整周期采样频谱会泄漏原本一根谱线会散开。实验报告里如果要求“观察频谱”最好让信号长度是周期的整数倍或者加窗。但加窗会改变幅度所以要在报告里说明你用了什么窗、为什么用。常见做法是先算Y np.fft.fft(x)再算f np.fft.fftfreq(len(x), d1/fs)然后只画f[:len(x)//2]和abs(Y[:len(x)//2])。这样横轴就是真实的 Hz而不是样本序号。3. 用 Python 把实验四跑通从信号生成到频谱验证3.1 环境准备与最小依赖实验四不需要复杂的工具箱Python 里numpy和matplotlib就够了。如果你用的是某高校实验室的机房环境可能预装了 Anaconda直接开 Jupyter Notebook 就能跑。我一般会建议新建一个干净的虚拟环境避免版本冲突python -m venv sigsys_env source sigsys_env/bin/activate # Windows 下用 sigsys_env\Scripts\activate pip install numpy matplotlib这段命令的作用是创建独立环境并安装两个核心库。参数说明venv是 Python 标准库自带的虚拟环境模块source在 Windows 下换成对应激活脚本。如果你不想折腾环境直接用系统 Python 也行但要注意numpy版本最好在 1.20 以上避免fft接口差异。3.2 采样与混叠的完整仿真脚本下面这个脚本把采样、混叠、频谱放在一起你可以直接改参数观察变化import numpy as np import matplotlib.pyplot as plt # 连续信号频率 f0 5 # Hz # 三组采样频率 fs_list [50, 10, 8] # 分别对应过采样、临界、欠采样 t_continuous np.linspace(0, 1, 1000) plt.figure(figsize(12, 8)) for i, fs in enumerate(fs_list): # 离散采样 n np.arange(0, int(fs * 1)) # 1 秒内的样本 x_n np.sin(2 * np.pi * f0 * n / fs) # 连续信号用于对比 x_c np.sin(2 * np.pi * f0 * t_continuous) plt.subplot(3, 2, 2*i1) plt.plot(t_continuous, x_c, b, label连续信号) plt.stem(n/fs, x_n, r, basefmt , label采样点) plt.title(ffs{fs} Hz, f0{f0} Hz) plt.legend() # 频谱 X np.fft.fft(x_n) f np.fft.fftfreq(len(x_n), d1/fs) plt.subplot(3, 2, 2*i2) plt.stem(f[:len(f)//2], np.abs(X[:len(f)//2]), basefmt ) plt.title(f幅度谱 fs{fs} Hz) plt.xlabel(频率 (Hz)) plt.tight_layout() plt.show()逻辑说明第一组fs50远大于2*f010采样点能还原正弦第二组fs10刚好等于 ( 2f_0 )采样点落在零点附近重建困难第三组fs8小于 ( 2f_0 )频谱里会出现一个虚假的低频峰这就是混叠。参数说明f0是信号频率fs_list是三组采样率n是样本索引n/fs把样本索引转成时间。频谱只画了前半段因为实信号的频谱对称。3.3 卷积验证系统冲激响应与输出波形实验四经常要求你验证“系统对输入信号的响应等于卷积”。你可以构造一个简单的低通滤波器作为系统比如滑动平均import numpy as np import matplotlib.pyplot as plt # 输入信号两个不同频率正弦叠加 n np.arange(0, 100) x np.sin(0.1 * n) 0.5 * np.sin(0.8 * n) # 系统长度为 10 的滑动平均 h np.ones(10) / 10 # 卷积 y np.convolve(x, h, modefull) n_y np.arange(0, len(y)) plt.figure(figsize(10, 6)) plt.subplot(3, 1, 1) plt.stem(n, x, basefmt ) plt.title(输入信号 x[n]) plt.subplot(3, 1, 2) plt.stem(np.arange(len(h)), h, basefmt ) plt.title(系统冲激响应 h[n]) plt.subplot(3, 1, 3) plt.stem(n_y, y, basefmt ) plt.title(输出 y[n] x[n] * h[n]) plt.tight_layout() plt.show()逻辑说明滑动平均是一个低通系统高频成分会被削弱。你可以对比输入和输出的频谱会发现0.8那个频率的幅度明显下降。参数说明h的长度决定了平滑程度长度越大截止频率越低。注意modefull导致输出比输入长这是离散卷积的固有特性。4. 实验四避坑指南五个让报告被退回的细节4.1 现象采样率设成信号频率的两倍波形还是不对原因临界采样在理论上要求重建滤波器是理想低通实际仿真里用stem画点相位稍微偏移就会让样本落在零点附近。解决实验报告里不要只写“满足采样定理”要说明临界采样在实际离散仿真中的局限性建议取 ( f_s \geq 5f_0 ) 作为过采样观察。4.2 现象卷积结果长度和输入对不上画图错位原因np.convolve默认modefull输出长度是 ( NM-1 )但很多同学直接用输入的时间轴去画输出。解决单独构造输出时间轴n_y np.arange(0, len(y))或者用modesame并明确说明你做了截断。4.3 现象FFT 频谱横轴是样本序号不是频率原因直接plot(abs(fft(x)))没有构造频率轴。解决用np.fft.fftfreq(N, d1/fs)生成频率轴只取前半段画正频率。注意d是采样间隔不是采样率。4.4 现象频谱泄漏导致谱线散开被误认为噪声原因信号长度不是周期的整数倍FFT 默认认为信号是周期的边界不连续就会泄漏。解决调整信号长度使其包含整数个周期或者加汉宁窗并说明窗函数对幅度的影响。4.5 现象实验报告里参数写了一大堆但没说为什么选这些值原因只抄了代码里的数字没有解释物理意义。解决每个参数后面加一句“因为……所以取……”比如“因为信号最高频率是 5 Hz为了满足采样定理并留有余量取 ( f_s50 ) Hz”。5. 让实验四从“能跑”到“能讲”一个验证习惯和一条进阶技巧做完实验四最怕的是老师问“你这个频谱里为什么有个小峰”。我自己的习惯是每画一张图先自己问三个问题——横轴物理量是什么、纵轴物理量是什么、这个形状对应什么数学性质。比如频谱里出现一个小峰先检查是不是混叠再检查是不是泄漏最后检查是不是窗函数旁瓣。这个习惯让我在实验报告里少写了很多“玄学”解释。进阶技巧是用scipy.signal里的freqz直接画系统频率响应和 FFT 结果对照。比如滑动平均系统的频率响应可以用freqz(h)得到横轴是归一化频率。你可以把freqz的曲线和输入输出频谱叠在一起验证低通特性。这样报告里就不只是“我算了卷积”而是“我验证了系统在频域的行为”。from scipy import signal import matplotlib.pyplot as plt h [1/10] * 10 w, H signal.freqz(h) plt.plot(w / np.pi, 20 * np.log10(np.abs(H))) plt.title(滑动平均系统频率响应) plt.xlabel(归一化频率 (×π rad/sample)) plt.ylabel(幅度 (dB)) plt.grid() plt.show()这段代码用freqz计算系统频率响应w是归一化角频率H是复频响。参数说明h是系统系数w/np.pi把横轴转成以 π 为单位。你可以看到滑动平均在低频增益接近 0 dB高频衰减这就是它作为低通滤波器的证据。最后说一句实验四的代码可以复制但参数背后的“为什么”复制不了。我当年就是靠把每个参数都问一遍“如果改成别的会怎样”才真正把采样、卷积、频谱串起来。希望帮到你。本文还有配套的精品资源点击获取