第【22】期--多个场景实战 DS-CDMA全链路仿真--matlab完整代码

文章目录

    • 摘要
    • [1 研究背景](#1 研究背景)
    • 2本文工作
      • [2.1 无扩频](#2.1 无扩频)
      • [2.2 无扩频有宽带干扰](#2.2 无扩频有宽带干扰)
      • [2.3 有扩频+无宽带干扰](#2.3 有扩频+无宽带干扰)
      • [2.4 接收端已知的扩频码不完全正确](#2.4 接收端已知的扩频码不完全正确)
      • [2.5 有扩频有宽带干扰](#2.5 有扩频有宽带干扰)
    • [3 总结](#3 总结)

摘要

在直接序列扩频通信(DS-CDMA)中,扩频码的选择直接决定了系统的抗干扰、抗截获及多址接入能力。为探究不同码型在真实战场与复杂电磁环境下的实际表现,本文基于 RS(18,16) 编码与 16-QAM 调制,设计并对比了五个递进式仿真场景,聚焦于工程中最经典的 Gold 码 与 Walsh 码。仿真结果表明:Walsh 码凭借完美正交性在无干扰纯净链路中独占鳌头,但其高度结构化的周期特征在面对宽带干扰和码片估计误差时极度脆弱,性能断崖式下跌;而 Gold 码凭借接近白噪声的伪随机统计特性,在抗干扰压制与抗恶意截获方面展现出优于walsh的特点。

1 研究背景

  • 自军事通信步入数字化以来,直接序列扩频(DSSS)凭借其低截获概率和抗窄带干扰能力,一直是战术数据链、卫星通信及 GPS 导航的物理层基石。其核心理念是将窄带信息扩展至宽频带传输,使敌方难以侦测,同时利用解扩增益压制外来干扰。
  • 在工程实现中,两类扩频码长期占据主导地位,但其设计哲学截然相反:
    Walsh 码:源于哈达玛矩阵,具有严格的正交性。在同步且无多径的理想信道下,其自相关旁瓣为零,可以实现多用户间零干扰,因此在 IS-95 等蜂窝通信的前向链路中被广泛采用。但其致命的"阿喀琉斯之踵"在于结构过于规整,一旦同步误差或码片错位,其正交性瞬间瓦解,且在频域呈现极强的离散谱线特征,极易被干扰机识别并针对性打击。
    Gold 码:由一对优选 m 序列异或生成,具有优良的互相关特性和类噪声包络。虽然其自相关存在非零旁瓣,不具备完美的数学正交性,但其巨大的序列空间和极其平坦的功率谱密度,使其在抗多径衰落和对抗码字侦测方面拥有天然优势。

2本文工作

本文聚焦于工程中最经典的 Gold 码 与 Walsh 码基于 RS(18,16) 编码与 16-QAM 调制,设计并对比了五个递进式仿真场景。具体见后文:

2.1 无扩频

本小节验证了 RS 编码和 16-QAM 在单纯awgn信道下的基础性能。

2.2 无扩频有宽带干扰

  • 宽带干扰在通信对抗中,是指干扰信号的频谱宽度与有用信号的频谱宽度相当,甚至更宽。
    其中,宽带干扰的生成逻辑为
c 复制代码
jammer = sqrt(jammerPower/2) .* (randn(size(receivedSymbols)) + 1i*randn(size(receivedSymbols)));
  • 这句代码生成复基带高斯白噪声干扰,含义为:在数字通信中,时域的随机白噪声 经过傅里叶变换后,在频域上表现为平坦的功率谱密度(即均匀覆盖整个信号采样带宽)。因为采用的16-QAM 信号占满了整个基带带宽,而这个干扰均匀地叠加在每一个采样点上,所以它"宽"到覆盖了整个信号频带。
  • jammerPower = signalPower * 10^(jammerToSignalDb/10); signalPower是发射信号的平均功率,案例 2 中的 -9dB,意味着 jammerPower = signalPower * 0.125(干扰功率只有信号的 12.5%)。
  • 结果表明,无扩频系统在面对宽带干扰时极度脆弱,凸显了引入扩频码的必要性。

2.3 有扩频+无宽带干扰

  • 实现了基于GOLD和walsh码扩频的通信系统

2.4 接收端已知的扩频码不完全正确

  • 发射端使用原始码扩频,但接收端使用的解扩码与原始码存在部分码片错位
  • gold 码本质是由两个 m 序列异或产生,具有一定伪随机性。少量码片错误其残余的相关性依然较强,仍能恢复部分有用信息;
  • Walsh 码的高度结构化和严格正交性是其优势也是其致命弱点。一旦出现码片错位,其正交性被严重破坏,解扩时旁瓣急剧抬升,导致信噪比损失大于gold

2.5 有扩频有宽带干扰

可以看到,相比于案例3,Gold 和 Walsh 码的误码率性能下降很严重。

部分代码:

c 复制代码
function output = simulate_thesis_link( ...
    informationBits, transmitCode, receiveCode, snrDb, ...
    jammerToSignalDb, cfg, randomSeedOffset)

informationBits = logical(informationBits(:));
transmitBits = apply_periodic_code(informationBits, transmitCode);
encodedBits = rs1816_encode(transmitBits);

transmittedSymbols = qammod( ...
    double(encodedBits), cfg.modulationOrder, "gray", ...
    InputType="bit", UnitAveragePower=false);
signalPower = mean(abs(transmittedSymbols).^2);

output.ber = zeros(size(snrDb));
output.constellation = [];

for snrIndex = 1:numel(snrDb)
    receivedSymbols = apply_channel( ...
        transmittedSymbols, signalPower, snrDb(snrIndex), ...
        jammerToSignalDb, ...
        cfg.randomSeed + 1000*randomSeedOffset + snrIndex);

    if snrDb(snrIndex) == cfg.constellationSnrDb
        numberToKeep = min( ...
            cfg.maximumConstellationPoints, numel(receivedSymbols));
        output.constellation = receivedSymbols(1:numberToKeep);
    end

    demodulatedBits = qamdemod( ...
        receivedSymbols, cfg.modulationOrder, "gray", ...
        OutputType="bit", UnitAveragePower=false);
    decodedBits = rs1816_decode(demodulatedBits);
    recoveredBits = apply_periodic_code(decodedBits, receiveCode);
    output.ber(snrIndex) = mean(recoveredBits ~= informationBits);
end

if isempty(output.constellation)
    constellationSymbols = apply_channel( ...
        transmittedSymbols, signalPower, cfg.constellationSnrDb, ...
        jammerToSignalDb, ...
        cfg.randomSeed + 1000*randomSeedOffset + 99);
    numberToKeep = min( ...
        cfg.maximumConstellationPoints, numel(constellationSymbols));
    output.constellation = constellationSymbols(1:numberToKeep);
end
end

function outputBits = apply_periodic_code(inputBits, code)
inputBits = logical(inputBits(:));
if isempty(code)
    outputBits = inputBits;
    return;
end

code = logical(code(:));
repetitions = ceil(numel(inputBits) / numel(code));
codeStream = repmat(code, repetitions, 1);
outputBits = xor(inputBits, codeStream(1:numel(inputBits)));
end

function receivedSymbols = apply_channel( ...
    transmittedSymbols, signalPower, snrDb, jammerToSignalDb, seed)
rng(seed, "twister");
receivedSymbols = awgn(transmittedSymbols, snrDb, "measured");

if isfinite(jammerToSignalDb)
    jammerPower = signalPower * 10^(jammerToSignalDb/10);
    jammer = sqrt(jammerPower/2) .* ( ...
        randn(size(receivedSymbols)) + ...
        1i*randn(size(receivedSymbols)));
    receivedSymbols = receivedSymbols + jammer;
end
end

3 总结

需要设计一种 抗干扰能力强,且保密性好的扩频码。

  • 源代码 出图所见即所得,代码获取方式见VX公众号