2. 信号与系统基础回顾
在 MATLAB 中做通信或雷达算法原型,几乎所有“看起来像算法”的问题,最后都会落到几个信号与系统的基本概念上:信号是连续的还是离散的、频谱长什么样、采样率够不够、系统对信号做了什么卷积、以及怎样用复基带和解析信号把高频载波问题化简。把这些概念在 MATLAB 里重新过一遍,比单纯背公式更有价值,因为后面 OFDM、匹配滤波、脉冲压缩、IQ 解调都会反复用到它们。
连续信号与离散信号:先分清“物理量”和“序列”
连续时间信号 x(t) 是定义在实数时间轴上的函数,例如单音余弦 x(t)=cos(2πf₀t);离散时间信号 x[n] 只在整数序号上有定义,通常来自对连续信号的采样:x[n]=x(nTₛ),其中 Tₛ=1/fₛ 是采样间隔。MATLAB 本身只能处理有限长离散序列,所以“连续信号”在原型里一般用两种方式近似:一是用足够高的采样率生成密集序列,二是用符号表达式或解析公式推导后再离散化。
例如要观察 1 kHz 单音在 8 kHz 采样率下的离散序列,可以这样生成并对比连续曲线:
fs = 8000; % 采样率 8 kHz
Ts = 1/fs;
f0 = 1000; % 单音频率 1 kHz
t = 0:1e-6:3e-3; % 连续时间轴,1 μs 步长
n = 0:round(3e-3*fs);
xn = cos(2*pi*f0*n*Ts);
plot(t, cos(2*pi*f0*t), 'LineWidth', 1.2); hold on;
stem(n*Ts, xn, 'filled'); grid on;
xlabel('t / s'); ylabel('幅度'); legend('连续','离散采样');
运行后应看到离散样点正好落在连续余弦曲线上。这里的关键判断是:离散序列的“频率”并不是物理频率本身,而是归一化频率 f/fₛ;同一个离散序列可以对应多个连续频率,这正是后面采样定理要处理的问题。
傅里叶变换:把时域问题换到频域看
连续时间傅里叶变换定义为 X(jΩ)=∫x(t)e^{-jΩt}dt,离散时间傅里叶变换(DTFT)为 X(e^{jω})=Σx[n]e^{-jωn},而实际计算用离散傅里叶变换(DFT):X[k]=Σ_{n=0}^{N-1}x[n]e^{-j2πkn/N}。MATLAB 的 fft 计算的就是 DFT,频率轴要自己构造:f = (0:N-1)*(fs/N),若用 fftshift 则中心为零频。
做频谱观察时,建议先加窗再 FFT,否则有限长截断会带来频谱泄漏。例如对上面的 1 kHz 单音取 1024 点做 FFT:
N = 1024;
xw = xn(1:N) .* hann(N)';
X = fftshift(fft(xw));
f = (-N/2:N/2-1)*(fs/N);
plot(f, 20*log10(abs(X)/max(abs(X)))); grid on;
xlabel('频率 / Hz'); ylabel('归一化幅度 / dB');
结果应在 ±1 kHz 附近出现主瓣,主瓣宽度由窗长和窗型决定。这里要建立的直觉是:时域越短,频域越宽;时域加窗会改变频谱形状,但不改变信号真实频率位置。
采样定理:不是“能采就行”,而是“不能混叠”
奈奎斯特采样定理指出:若连续信号最高频率为 f_max,则采样率必须满足 fₛ > 2f_max,否则高频分量会折叠到低频,形成混叠。工程上通常留 2.5~5 倍余量,并在 ADC 前加抗混叠低通滤波器。MATLAB 里可以用 resample 或直接抽取来观察混叠:
fs1 = 8000; f1 = 3000; % 3 kHz,满足 fs>2f
fs2 = 4000; f2 = 3000; % 3 kHz,不满足,会混叠到 1 kHz
n1 = 0:63; n2 = 0:31;
x1 = cos(2*pi*f1*n1/fs1);
x2 = cos(2*pi*f2*n2/fs2);
subplot(2,1,1); stem(n1, x1, 'filled'); title('f_s=8 kHz, 3 kHz 单音');
subplot(2,1,2); stem(n2, x2, 'filled'); title('f_s=4 kHz, 3 kHz 混叠为 1 kHz');
第二幅图看起来像 1 kHz 单音,这就是混叠的直观表现。判断是否混叠,不能只看波形“好不好看”,而要看采样率与信号带宽的关系;对带通信号则可用带通采样,但必须保证采样后频谱不重叠。
卷积与滤波:系统对信号的作用
离散线性时不变系统输出为卷积 y[n]=x[n]*h[n]=Σx[k]h[n-k]。MATLAB 中 conv(x,h) 做全卷积,filter(b,a,x) 做差分方程形式的滤波,fftfilt 适合长序列快速卷积。设计一个简单低通 FIR 并观察滤波效果:
h = fir1(64, 0.2); % 归一化截止 0.2×Nyquist
x = cos(2*pi*0.05*(0:255)) + 0.5*cos(2*pi*0.45*(0:255));
y = filter(h, 1, x);
[H,f] = freqz(h, 1, 1024, fs);
plot(f, 20*log10(abs(H))); grid on;
xlabel('频率 / Hz'); ylabel('幅度 / dB');
结果中 0.05 归一化频率分量应基本保留,0.45 分量被明显抑制。这里要区分“卷积长度”和“滤波延迟”:FIR 的群延迟约为 (N-1)/2 个样点,做匹配滤波或脉冲压缩时必须补偿这个延迟,否则测距/同步会偏移。
复基带、解析信号与希尔伯特变换
实带通信号 x(t)=A(t)cos(2πf_c t+φ(t)) 可以写成复基带形式 x(t)=Re{x_b(t)e^{j2πf_c t}},其中 x_b(t)=A(t)e^{jφ(t)} 是复包络。解析信号 x_a(t)=x(t)+j·H{x(t)} 只保留正频率分量,其频谱是原实信号正频率部分的两倍。MATLAB 中用 hilbert 得到解析信号,再乘以 exp(-j2πf_c t) 即可下变频到基带:
fc = 2000; fs = 20000; t = (0:1/fs:0.01-1/fs)';
x = cos(2*pi*fc*t) .* (1 + 0.3*cos(2*pi*50*t)); % AM 信号
xa = hilbert(x); % 解析信号
xb = xa .* exp(-1j*2*pi*fc*t); % 复基带
plot(t, real(xb), t, imag(xb)); grid on;
xlabel('t / s'); ylabel('幅度'); legend('I','Q');
结果中 I、Q 两路应呈现 50 Hz 包络变化,载波 2 kHz 被去掉。这里的关键是:hilbert 返回的是解析信号,不是实信号的希尔伯特变换本身;若只要正交分量,应取 imag(hilbert(x))。复基带表示让后续的匹配滤波、FFT、同步和均衡都可以在低采样率下完成,是通信与雷达原型中最常用的化简手段。