3. MATLAB信号处理核心操作

在通信与雷达算法原型开发中,MATLAB 的信号处理能力几乎全部建立在“向量化”这一基础之上。所谓向量化,是指用矩阵/向量整体运算代替逐元素 for 循环,让 MATLAB 调用底层优化过的 BLAS/LAPACK 或内置函数一次性完成计算。它不只是写法问题,更直接影响原型开发的速度与代码可读性。例如要生成 1 秒、采样率 1 kHz 的正弦信号,逐点循环需要 1000 次迭代,而向量化只需一行:

fs = 1000;              % 采样率 1 kHz
t  = (0:1/fs:1-1/fs).'; % 列向量时间轴,长度 1000
f0 = 50;                % 信号频率 50 Hz
x  = sin(2*pi*f0*t);    % 向量化生成正弦波

这里 t 采用列向量,是为了与后续矩阵运算、滤波器状态、多通道数据保持维度一致。向量化编程中要特别注意三类运算的区别:* 是矩阵乘法,.* 是逐元素乘法,' 是共轭转置而 .' 是普通转置。复数信号处理时若误用 ',会悄悄引入共轭,导致频谱镜像错误,这是原型阶段最常见的隐蔽 bug 之一。

信号生成:从确定信号到复指数

通信与雷达原型常用的信号包括单频正弦、线性调频(LFM)、伪随机序列和复指数。LFM 是雷达脉冲压缩的核心波形,其瞬时频率随时间线性变化。用向量化方式生成一个带宽 1 MHz、脉宽 100 μs 的 LFM:

fs = 5e6; T = 100e-6; B = 1e6;
t = (-T/2:1/fs:T/2-1/fs).';
K = B/T;                       % 调频斜率
s = exp(1j*pi*K*t.^2);         % 复 LFM 信号

复指数形式 exp(1j*...) 同时保留了幅度与相位信息,便于后续做匹配滤波和相干积累。生成信号后,通常先检查其长度、采样点数与理论值是否一致,再用 abs、angle 观察包络和相位是否为预期形状。

滤波函数:filter 与 filtfilt 的取舍

MATLAB 提供 filter、conv、filtfilt 等滤波入口。filter(b,a,x) 实现因果 IIR/FIR 差分方程,会引入相位延迟;filtfilt 做前向-反向两次滤波,相位为零但等效阶数翻倍,且不适用于实时流式处理。设计一个 4 阶巴特沃斯低通滤波器并观察其效果:

[b,a] = butter(4, 0.2);        % 归一化截止频率 0.2×Nyquist
y = filter(b,a,x);             % 因果滤波,有群延迟
y0 = filtfilt(b,a,x);          % 零相位滤波,用于离线分析

判断滤波是否合理,不能只看时域波形“变平滑了”,而应结合幅频响应 freqz(b,a) 确认通带纹波、阻带衰减和过渡带宽度,并检查滤波后信号在通带内的幅度是否被明显衰减。

频谱分析与窗函数

频谱分析的核心是 FFT。直接对有限长信号做 FFT 会产生频谱泄漏,因为截断相当于乘了矩形窗,其旁瓣衰减只有约 −13 dB。加窗可压低旁瓣,代价是主瓣变宽、频率分辨率下降。常用窗的取舍如下:矩形窗主瓣最窄、旁瓣最高,适合整周期采样;汉宁窗旁瓣约 −31 dB,适合连续信号谱估计;汉明窗旁瓣约 −43 dB;布莱克曼窗旁瓣约 −58 dB,但主瓣更宽。工程上常按“是否需要分辨邻近强/弱分量”来选择。

N = 1024;
w = hann(N);                   % 汉宁窗
X = fft(x.*w, N);              % 加窗后 FFT
f = (0:N-1).'*fs/N;            % 频率轴
P = abs(X).^2/N;               % 周期图(未归一化)

需要注意,加窗后信号能量被窗函数削弱,做幅度谱时应除以 sum(w) 做相干增益补偿;做功率谱时应除以 sum(w.^2) 做功率增益补偿,否则不同窗之间的谱幅度不可比。

功率谱估计与时频分析入门

单次 FFT 得到的周期图方差很大,谱线起伏剧烈。pwelch 通过分段、加窗、重叠平均来降低方差,是工程上最常用的功率谱估计方法。典型调用为 pwelch(x, hann(256), 128, 256, fs),其中 256 为段长、128 为重叠点数、256 为 FFT 点数。段长决定频率分辨率,重叠比例影响方差与数据利用率,二者需要权衡。

当信号频率随时间变化(如 LFM、跳频、多普勒回波)时,单一频谱无法描述其演化,需要时频分析。MATLAB 的 spectrogram 与信号处理工具箱中的 stft、cwt 可给出时间-频率二维分布。以 LFM 为例,spectrogram(s, hann(128), 96, 128, fs, 'yaxis') 应呈现一条随时间线性上升的斜线,斜率为 K。若图中斜线方向、斜率或起止频率与设计不符,说明调频斜率、采样率或时间轴定义存在错误。

MATLAB 信号处理核心操作链路 信号生成 t = (0:1/fs:...).' sin / exp(1j·πKt²) 列向量 · 复指数 向量化,避免 for 滤波 butter / fir1 设计 filter:因果,有延迟 filtfilt:零相位 freqz 验证响应 窗函数 hann / hamming blackman / rectwin 旁瓣↓ 主瓣↑ 抑制频谱泄漏 频谱分析 fft(x.*w, N) f = (0:N-1)·fs/N 幅度/功率归一化 相干/功率增益补偿 功率谱估计 pwelch 分段 · 加窗 · 重叠 · 平均 pwelch(x, hann(256), 128, 256, fs) 段长→分辨率,重叠→方差 时频分析 spectrogram / stft 时间-频率二维分布 spectrogram(s, hann(128), 96, 128, fs) LFM → 斜线,斜率 = K 结果判读要点 通带幅度是否保持 · 旁瓣是否被压低 · 谱峰位置与理论频率是否一致 时频图斜率/起止频率是否匹配设计参数

把上述环节串起来,一个典型的原型验证流程是:先生成已知参数的信号(如 50 Hz 正弦或 LFM),再按需滤波,然后加窗做 FFT 或 pwelch 估计功率谱,最后用 spectrogram 观察时频结构。每一步都应保留中间变量,便于对照理论值。例如对 50 Hz 正弦加汉宁窗做 1024 点 FFT,谱峰应出现在 f0/fs*N = 51.2 号频点附近,若明显偏移,应检查频率轴定义或窗函数是否误用。

向量化编程的实用习惯:预分配数组(zeros、ones)、用逻辑索引代替条件循环、用 bsxfun 或隐式扩展处理不同维度数组。这些习惯能让原型代码在数据量增大时仍保持可接受的运行速度。
常见陷阱:fft 输出未做 fftshift 时零频在首元素,画图时容易误判正负频率;filter 的群延迟未补偿会导致与原始信号对齐错误;pwelch 的段长若大于信号长度,会静默补零,使谱看起来“更平滑”但分辨率并未真正提高。

掌握这些核心操作后,后续的调制解调、匹配滤波、CFAR 检测、DOA 估计等算法都可以在此基础上快速搭建原型。关键不在于记住每个函数的全部参数,而在于理解每个环节对信号做了什么、会引入什么误差,以及如何用理论值去校验结果。