简介:一份基于MATLAB的QDPSK通信系统仿真文档,主要面向电子信息类、通信工程等专业的学生与工程师,用于理解四相相对移相键控(QDPSK)的原理及Simulink建模仿真方法。文档基于“信号与系统”课程教学场景,阐述如何将复杂的理论计算、绘图与系统设计过程通过可视化仿真变得简单直观。核心内容包括系统总体方案设计、DQPSK调制模块(随机数发生器、差分编码器、DQPSK调制器)、可调高斯白噪声信道模块、DQPSK解调模块(差分码反变换器、DQPSK解调器)以及误码率计算模块,并详细给出了各模块的图形化结构与参数配置步骤。文中还演示了绝对码到相对码的差分编码转换,支持在不同信噪比条件下运行仿真并对比解调性能,体现了Simulink在通信系统研究中的高效性。资源压缩包为1个doc文件,约196KB,全文图文并茂、层次清晰,既可作为课程设计或毕业设计的参考资料,也适合自学通信仿真入门。目前已有290人在CSDN学习下载,具备一定参考价值。
1. 在MATLAB里实现QDPSK通信系统仿真,先啃下“差分”两个字
很多人第一次接触QDPSK时,会把它当成带旋转的QPSK,直接去翻调制函数。真正用MATLAB搭链路才发现,QDPSK的难点不在星座图上有几个点,而在“差分”这两个字:信息不在绝对相位里,而在相邻符号的相位差里。这正是QDPSK在低复杂度接收机里被反复使用的原因:只要做一次复乘和取相位,就能绕开载波相位同步里的整周模糊问题。
本文从一组最小可运行的调制解调函数入手,逐步搭建包含成形滤波、AWGN信道和误码率统计在内的QDPSK通信系统仿真平台,并给出工程上最常用的验收技巧。适合通信算法工程师,以及准备在MATLAB里做通信仿真课程设计的同学直接落地。
2. QDPSK调制解调原理与MATLAB最小实现
2.1 相位增量映射表:信息其实藏在差里
QDPSK(四相相对相移键控)在英文资料里通常写作DQPSK,两者是一回事。在常规QPSK中,每个符号的绝对相位对应两个比特;发射机和接收机必须共享同一个绝对参考。一旦载波恢复出现π/2整数倍的相位模糊,所有符号都会判错。QDPSK的做法是:当前符号的相位等于上一个符号的相位加上一个由当前比特对决定的增量。这样接收机不需要知道绝对相位,只需要把当前符号和上一个符号共轭相乘,就能得到增量。实现上,QDPSK一般用格雷码把2比特映射到四个相位增量上,见下表。
| 信息比特 | 十进制 | 相位增量 | 格雷映射索引 |
|---|---|---|---|
| 00 | 0 | 0 | 0 |
| 01 | 1 | π/2 | 1 |
| 11 | 3 | π | 3 |
| 10 | 2 | 3π/2(即-π/2) | 2 |
表里的映射并不唯一,核心要求是相邻相位只错1个比特,这样误码率性能更好。注意格雷映射索引不是按十进制顺序排的,这也是初写代码最容易踩的坑。
2.2 调制端的MATLAB核心代码
function txSym = qdpsk_mod(bits) % QDPSK调制:输入比特列向量,长度为2N;输出N个基带复符号 N = length(bits) / 2; info = bi2de(reshape(bits, 2, N)', 'left-msb'); % 每2比特转十进制0~3 map = [0 1 3 2]; % 格雷编码的相位增量索引 delta = map(info + 1); % 查表得到增量索引 phase = cumsum(delta) * pi / 2; % 差分相位累计 txSym = exp(1j * phase); % 映射到单位圆 end逻辑说明:bi2de把每一行2个比特按left-msb转成0到3的整数,map(info+1)得到对应的相位增量索引。cumsum在这里做差分编码,也就是把“当前增量”累加到历史相位上。最后用exp(1j*phase)把相位变成复数基带符号,每个符号的平均能量是1。参数上,left-msb决定比特顺序,接收端必须用同样顺序恢复。如果希望第一个符号有确定参考相位,可以在phase前补一个0,并将输出改成exp(1j*[0; phase]),代价是多传一个参考符号。
2.3 解调端代码与相位模糊的消除
function bits = qdpsk_demod(rxSym) % QDPSK差分解调:输入N个接收符号,输出2*(N-1)个比特 d = rxSym(2:end) .* conj(rxSym(1:end-1)); ph = angle(d); % 相位差落在(-pi, pi] idx = round(ph / (pi/2)); % 量化到0, ±1, ±2 idx = mod(idx, 4); % 转为0~3 map = [0 1 3 2]; % 与发射端保持一致 info = map(idx + 1); bits = de2bi(info, 2, 'left-msb')'; bits = bits(:); end这段代码的核心是rxSym(2:end) .* conj(rxSym(1:end-1))。当前符号乘以前一个符号的共轭,如果信道上只有一个固定相偏θ,那么每个符号都带一个θ,共轭相乘后θ会被抵消,只剩信息相位增量。angle求出主值区间(-π, π]里的相位,round(ph/(pi/2))把它四舍五入到最近的π/2整倍数,mod(idx,4)把负索引归一到0~3。这里丢掉第一个符号对应的比特,是差分接收的正常开销。噪声较大时相位可能跨过±π/4判决边界,这属于系统固有的误码损失。
2.4 为什么QDPSK能省掉载波恢复,却省不掉频偏估计
相位模糊是绝对相移键控在低信噪比下的经典问题:接收机锁相环可能锁定在任何一个π/2整数倍相位上,导致整个星座旋转。QDPSK用差分相位把绝对参考从算法里删掉了,因此接收端不需要知道具体的载波初始相位。
但这不意味着可以放任任何相位误差。恒定相偏可以消除,线性增长的频偏却会残留在d里。频偏会让每个符号额外多旋转一个固定角度,差分解调后的星座簇整体偏移,一旦偏移量逼近±π/4判决边界,整个链路就会崩溃。这一点在后面第5章会专门验证。
3. 搭建QDPSK通信系统仿真链路:成形、AWGN与匹配滤波
3.1 发射端完整波形级仿真:上采样与成形滤波
符号级仿真的好处是快,但要评估带宽占用和码间串扰,必须把成形滤波加进来。MATLAB里一般用rcosdesign生成根升余弦滤波器,再用upsample和conv完成上采样与成型。
sps = 8; % 每个符号采样点 rolloff = 0.22; % 滚降系数 span = 6; % 滤波器截断的符号数 rrc = rcosdesign(rolloff, span, sps); bits = randi([0 1], 20000, 1); % 测试用比特流 sym = qdpsk_mod(bits); upsym = upsample(sym, sps); % 插入零值上采样 tx = conv(upsym, rrc, 'same'); % 成形滤波rcosdesign的第三个参数必须是整数,滤波器系数的总数是span*sps+1。滚降因子越大,占用带宽越大,但对定时误差越钝感。卫星链路常用0.2到0.35,这里取0.22。upsample在每两个符号之间插入sps-1个0,随后卷积完成插值。'same'让输出长度与输入一致,但会引入延迟,后续匹配滤波时必须处理。
3.2 AWGN信道与波形级仿真的噪声处理策略
波形级仿真最容易翻车的地方是噪声功率设置。过采样率、滤波器能量、匹配滤波增益都会影响最终符号信噪比,如果在这里纠结严密归一化,调试成本会非常高。我常用的做法是:波形级链路只负责“看清眼图和星座图”,用相对信噪比把信号加到能观察的程度;严格的Eb/N0误码率统计放到第4章的符号级仿真里做。
rx = awgn(tx, 30, 'measured'); % 先给一个相对信噪比,比如30dBawgn的'measured'选项会先测输入信号功率再叠加噪声,避免手动算功率。这段代码的目的不是得到精确的BER,而是验证滤波链路里有没有ISI和相位异常。如果波形级算出来BER异常,大概率不是噪声功率算错,而是滤波对齐出了问题。
提示:如果你确实要在波形级按指定Eb/N0加噪,噪声方差需要乘以过采样率,写成
noise = sqrt(N0*sps/2) * (randn(size(tx)) + 1j*randn(size(tx)))。不同滤波器归一化方式会改变这个系数,所以建议先用符号级仿真锁定调制解调逻辑,再回头调波形级噪声。
3.3 接收端匹配滤波与抽样对齐
匹配滤波器是发端成形滤波器的时域反转共轭。在MATLAB里用conv完成:
mf = conj(fliplr(rrc)); % 匹配滤波系数 y = conv(rx, mf, 'same'); % 匹配滤波 offset = sps/2 + 1; % 根据 'same' 的延迟估算 eyediagram(y(offset:end), sps); % 看眼图,确认无严重ISI down = y(offset : sps : end); % 下采样到每符号一个点 rxBits = qdpsk_demod(down);fliplr完成时间反转,conj匹配复数基带信号。由于conv(...,'same')会给输出引入(length(rrc)-1)/2个点延迟,而根升余弦滤波器长度为span*sps+1,最佳采样点经验上取sps/2+1附近。实际工程里这个经验值不一定稳,应该用一小段已知训练序列扫描不同偏移,选误码率最低的那一个。上面的offset在多数短滤波器配置下能跑通,但不保证所有参数都最优。
3.4 链路参数速查表
| 参数 | 推荐取法 | 影响 |
|---|---|---|
| sps | 4~16 | 越小仿真越快,但眼图越难观察;低于4会难以对齐采样点 |
| rolloff | 0.2~0.5 | 越小越省带宽,ISI越大;越大越抗定时抖动 |
| span | 4~10 | 滤波器截断长度,太短会造成频谱泄漏 |
| offset | 用训练序列扫最佳采样点 | 1个采样点错误就可能让BER恶化一个量级 |
参数之间不是独立的。提高span会让滤波器更接近理想根升余弦,但offset的敏感度也会变化。调参时固定sps和rolloff,只动offset,观察眼图张开程度,是最快的定位方式。
4. 用误码率曲线和星座图评估QDPSK仿真性能
4.1 蒙特卡洛误码率脚本:符号级仿真与波形级仿真分开
要得到BER曲线,不要直接用前面带成形的波形级链路跑一万次,过采样会让蒙特卡洛循环慢数十倍。正确顺序是先写一个符号级仿真,验证调制解调逻辑无错;确认后再把成形滤波加进去看具体损失。符号级仿真就是让sps=1,不加滤波器,直接把AWGN加到符号上。
EbN0_dB = 0:2:12; berSim = zeros(size(EbN0_dB)); Nbits = 1e6; for k = 1:length(EbN0_dB) bits = randi([0 1], Nbits, 1); sym = qdpsk_mod(bits); EbN0_lin = 10^(EbN0_dB(k)/10); N0 = 1 / (2 * EbN0_lin); % 每符号2比特,Es/N0=2*Eb/N0 noise = sqrt(N0/2) * (randn(size(sym)) + 1j*randn(size(sym))); rx = sym + noise; bitsHat = qdpsk_demod(rx); % 差分解调丢掉第一个符号,这里对齐到 bits(3:end) berSim(k) = sum(bitsHat ~= bits(3:end)) / length(bitsHat); end berTheory = berawgn(EbN0_dB, 'dpsk', 4); semilogy(EbN0_dB, berSim, 'o-', EbN0_dB, berTheory, 's-'); grid on;Nbits=1e6每个Eb/N0点大约产生5e5个符号,差分解调丢一个符号对统计几乎无影响。berawgn是MATLAB通信工具箱里直接给理论值的函数,对DPSK输入有效。如果手边没有通信工具箱,也可以用相干QPSK理论值qfunc(sqrt(2*EbN0_lin))做参考,但要记住两者差2到3dB,不能直接画在同一张图上当拟合对象。
4.2 仿真结果和理论值之间的合理差异
QDPSK差分解调时,每个比特判决依赖相邻两个符号,噪声被同时引入两次,等效信噪比低于相干QPSK。理论曲线与仿真曲线在低Eb/N0区域会基本重合,在高Eb/N0区域可能出现一条细缝,这通常是蒙特卡洛点数不足造成的。判断仿真可信度的标准不是两条曲线完全重叠,而是看斜率是否一致;若斜率不同,大概率是差分编码或解调出现了系统性错误。
下面这张表可以帮你快速判断误码率停在哪个量级属于“逻辑正常但参数不优”:
| Eb/N0 (dB) | 合理量级(差分解调QDPSK) | 常见异常 |
|---|---|---|
| 4 | 约1e-2量级 | 定时偏移会让它变成5e-2以上 |
| 8 | 约1e-3量级 | 频偏超阈值则“塌”到1e-1量级 |
| 12 | 约1e-5量级 | 滤波器长度不足时开始拖尾 |
如果仿真结果比表里的合理量级差很多,先别急着怀疑噪声功率,优先检查差分映射表和解调端的mod取模。
4.3 用星座图和相位直方图做故障定位
误码率只能告诉你坏了,不能告诉你为什么坏。工程上如果BER比理论差很多,先画接收符号的星座图:
rxDemo = rx(1:2000); plot(real(rxDemo), imag(rxDemo), '.'); axis equal; grid on;在差分系统里,星座图整体是旋转的,直观看不出“绝对相位错误”。更实用的是画解调前的差分相位图,也就是angle(rx(2:end).*conj(rx(1:end-1)))。正常链路应该有四个聚集簇,分别落在0、±90度、180度附近。一旦出现整体旋转或聚集簇分裂,说明残余频偏或定时偏差占主导。
5. 残余频偏环境下QDPSK的快速验收技巧
5.1 归一化频偏对差分相位的影响与门限估算
QDPSK虽然抗定值相偏,但抗不住频偏。假定收发本振之间有一个固定频偏Δf,符号周期为T,则每个符号期间相位额外旋转2πΔfT。差分解调的乘积项会把这个量作为常数偏差叠加到信息相位上。判决边界在±π/4,因此经验门限是:
|2πΔfT| < π/4,即|ΔfT| < 0.125
当符号速率为1 MHz时,0.125的归一化频偏对应125 kHz,对窄带低速系统来说并不是一个很宽松的数字。仿真里可以用下面这段代码注入频偏并观察BER退化:
fNorm = 0.02; % 归一化频偏 Δf*T,先给2% sn = (0:length(sym)-1).'; rxF = sym .* exp(1j*2*pi*fNorm*sn) + noise; % 沿用第4章的 noise 构造方式 bitsHatF = qdpsk_demod(rxF); berF = sum(bitsHatF ~= bits(3:end)) / length(bitsHatF);把fNorm分别取0、0.02、0.05、0.1,BER会从1e-4量级逐步退化到不可用。每增加0.01,差分相位会线性偏移约3.6度。如果不想跑完整BER循环,可以只打印接收符号与参考符号之间的累计相位旋转,快速判断链路能撑住多大频率误差。
5.2 用一张差分相位直方图完成验收
最后一个可复用的技巧:把BER验收换成“差分相位直方图”验收。对接收符号执行一次复共轭相乘,然后画出相位分布,四根峰的位置和形状就能说明问题:
d = rx(2:end) .* conj(rx(1:end-1)); ph = angle(d) * 180 / pi; histogram(ph, -180:10:180); xlabel('差分相位/度'); ylabel('计数');正常接收时,四根峰值分别位于-135、-45、45、135度附近,具体位置取决于映射表,峰谷分明。如果峰之间出现连续裙边,先怀疑信噪比不足;如果四个峰整体统一左移或右移,先怀疑频偏;如果只有两个峰变矮而另外两个变胖,多半是抽样点偏了。这套直觉比盯着BER曲线猜原因快很多。跑调优循环时把这张图存成png,按参数批次归档,回看数据比翻日志更直观。下次接手别人的QDPSK仿真模型,第一件事不是重跑BER,而是先画这张图。
本文还有配套的精品资源,点击获取