1. 课程导入与MATLAB信号处理环境
信号处理系统设计并不是“打开MATLAB写几行滤波代码”这么简单。一个可交付的系统,通常要经历需求定义、算法建模、定点/浮点权衡、仿真验证、代码生成、硬件联调与测试验收等环节。MATLAB与Simulink的价值,正在于把这些环节串成一条可追溯、可复现的工程链路:用脚本和函数验证算法,用Simulink搭建数据流与信号链,用工具箱完成滤波器设计、频谱分析与统计评估,再通过自动代码生成把验证过的模型推向DSP、FPGA或嵌入式处理器。
本课程面向真实工程场景,后续章节会围绕“信号—系统—算法—实现—验证”逐步展开。作为导入,本章先建立三件事:一是信号处理系统设计流程的整体框架;二是MATLAB/Simulink工具链中各类工具的分工与衔接;三是通过一个工程案例概览,理解从需求到结果的完整闭环。
1.1 信号处理系统设计流程
工程中的信号处理系统,输入通常是传感器或前端采集设备输出的离散序列,输出可能是滤波后的波形、检测判决、参数估计值或控制指令。设计流程可以概括为六个相互反馈的阶段:
- 需求与指标定义:明确采样率、信号带宽、信噪比、实时性、资源约束(乘法器数量、内存、功耗)以及验收标准。例如“对1 kHz采样的心电信号抑制50 Hz工频干扰,通带0~40 Hz,阻带衰减≥40 dB”。
- 信号与系统建模:用数学描述输入信号特性(频率、幅度、噪声分布)和系统响应(差分方程、传递函数、状态空间)。
- 算法设计与浮点仿真:在MATLAB中设计滤波器、谱估计、检测器等算法,用理想浮点数据验证功能正确性。
- 定点化与资源评估:将浮点算法转换为定点,分析字长、舍入、溢出对性能的影响,评估运算量和存储需求。
- 模型实现与代码生成:用Simulink搭建可执行模型,配置目标硬件,生成C/C++或HDL代码。
- 测试验证与迭代:通过仿真、硬件在环或实测数据回放,对比指标是否达标,不达标则回到相应阶段修改。
这六个阶段不是单向流水线,而是带反馈的迭代过程。例如定点化后阻带衰减不足,可能需要回到算法阶段调整滤波器阶数或结构;代码生成后发现资源超限,可能需要重新选择实现架构。
1.2 MATLAB/Simulink工具链分工
MATLAB与Simulink不是两个孤立软件,而是一套协同环境。理解各工具的分工,能避免“用错工具做错事”。
MATLAB基础环境负责矩阵运算、脚本编程、数据可视化与算法原型。信号处理中常用的操作包括:用fft做频谱分析、用filter实现差分方程、用freqz查看频率响应、用pwelch做功率谱估计。这些函数适合快速验证算法思想,但不直接对应硬件实现。
Signal Processing Toolbox提供滤波器设计与分析的高级函数。例如用designfilt设计低通滤波器,用fvtool交互查看幅频响应、相位响应、群延迟和零极点分布。设计完成后可导出系数供Simulink或代码生成使用。
Simulink与DSP System Toolbox负责数据流建模。Simulink以模块和信号线描述系统,天然适合表达采样率变化、帧处理、多速率系统和控制逻辑。DSP System Toolbox提供滤波器、FFT、采样率转换等专用模块,支持浮点和定点运算。
Fixed-Point Designer用于定点化。它可以帮助分析数据范围、推荐字长、检测溢出和精度损失。定点化是连接“算法正确”与“硬件可实现”的关键桥梁。
Embedded Coder与HDL Coder负责从模型生成可部署代码。Embedded Coder面向C/C++处理器(如ARM Cortex-M、TI C6000 DSP),HDL Coder面向FPGA/ASIC。生成代码前需要配置目标硬件、接口和优化选项。
1.3 工程应用案例概览:工频干扰抑制
下面以一个教学示例说明完整闭环。假设从心电采集前端获得一段含50 Hz工频干扰的信号,采样率fs = 1000 Hz,目标是在0~40 Hz通带内保留心电成分,同时将50 Hz干扰衰减40 dB以上。
第一步,在MATLAB中构造示例信号并观察频谱。用正弦波模拟50 Hz干扰,叠加低频心电成分和少量白噪声,然后做FFT观察各频率分量。示例代码如下:
fs = 1000; % 采样率 1000 Hz
t = (0:1/fs:2-1/fs)'; % 2秒数据
ecg = 0.8*sin(2*pi*1.2*t) + 0.3*sin(2*pi*8*t); % 模拟心电成分
hum = 0.5*sin(2*pi*50*t); % 50 Hz工频干扰
noise = 0.05*randn(size(t)); % 白噪声
x = ecg + hum + noise;
X = fft(x);
f = (0:length(x)-1)*fs/length(x);
plot(f(1:length(x)/2), abs(X(1:length(x)/2)));
xlabel('频率 (Hz)'); ylabel('幅度'); grid on;
观察频谱时,应能看到1.2 Hz和8 Hz附近的心电成分,以及50 Hz处明显的干扰峰。这一步的目的是确认问题频率位置和相对幅度,而不是直接设计滤波器。
第二步,设计滤波器。由于50 Hz远离40 Hz通带,可以选择低通滤波器,也可以选择带阻滤波器。若心电成分最高约40 Hz,低通更简单。用designfilt设计一个巴特沃斯低通滤波器,通带截止40 Hz,阻带截止48 Hz,阻带衰减40 dB:
d = designfilt('lowpassiir', ...
'PassbandFrequency', 40, ...
'StopbandFrequency', 48, ...
'PassbandRipple', 1, ...
'StopbandAttenuation', 40, ...
'SampleRate', fs);
fvtool(d); % 查看幅频响应和相位响应
在fvtool中重点检查三项:40 Hz以内是否平坦、48 Hz以上是否达到40 dB衰减、通带内相位是否可接受。若阻带衰减不足,可增加滤波器阶数或调整过渡带宽度。
第三步,在Simulink中搭建数据流模型。用信号源模块产生同样的合成信号,经过Discrete FIR Filter或Biquad Filter模块,再用Spectrum Analyzer观察滤波前后频谱。Simulink的优势在于可以直观看到信号逐帧流动,并方便替换为定点数据类型。
第四步,定点化与代码生成。将滤波器系数和输入数据转换为定点格式,例如16位字长、12位小数位。用Fixed-Point Designer检查是否溢出,比较定点与浮点的频率响应差异。若差异在可接受范围内,用Embedded Coder生成C代码,部署到目标处理器。
第五步,验证。将实测心电数据回放到模型中,对比滤波前后波形和频谱。判断依据包括:50 Hz峰值是否下降40 dB以上、心电波形是否失真、通带内幅度波动是否在1 dB以内。若某项不达标,回到对应阶段修改。