原文链接:
Link16通信战术数据链分析与MATLAB仿真程序 - 知乎写在前面:本文没有仿真Link16关于数据消息的组成以及时隙转发,仅仅仿真了Link16的通信链路关键技术,即通信波形。 MATLAB程序在文末,为了方便理解,可将文末最后的主程序与正文结合阅读。 如果本文对你有所帮助…https://zhuanlan.zhihu.com/p/462753171
目录
一、Link16通信战术数据链
1.1 基本概念
1.2 Link16数据链的技术特点
1.3 Link16数据链的TDMA接入方式
1.4 Link16数据链的消息结构
1.5 Link16数据链的传输波形
二、Link16 关键技术研究及通信数据链路仿真分析
2.1 CRC 检错码
2.2 RS 纠错码
2.2.1 RS编码技术仿真分析
2.3 交织技术
2.3.1 RS编码与交织技术结合的仿真
2.4 扩频技术
2.4.1 扩频技术基础
2.4.2 软扩频CCSK
2.5 信号调制映射
2.6 跳频传输
2.7 Link16通信数据链路的仿真
2.7.1 仿真结果
三、总结分析
四、MATLAB程序
五、参考文献
写在前面:
本文没有仿真Link16关于数据消息的组成以及时隙转发,仅仅仿真了Link16的通信链路关键技术,即通信波形。
MATLAB程序在文末,为了方便理解,可将文末最后的主程序与正文结合阅读。
如果本文对你有所帮助,请点赞支持一下!
贼详细的8PSK调制与解调详细过程 - 知乎一、关于1.花了几天写了一个8PSK调制的MATLAB程序,从产生序列到最后解调出原始信号。 2.我在网上查资料的时候发现并没有详细的一个调制完整过程,于是我把写的完整过程贴出来。 3.要想把通信专业学好的话,脑子里…https://zhuanlan.zhihu.com/p/47258287OFDM完整仿真过程及解释(MATLAB) - 知乎如有专业问题或者需要仿真可以点下面付费咨询链接。知乎用户 2020/5/12更新(感谢评论区@赵武休息下 提出的错误,已修改。): 挺多同学私信问子载波间隔、带宽、OFDM符号长度之间的关系?最开始学到这里可能有点…https://zhuanlan.zhihu.com/p/57967971
一、Link16通信战术数据链
1.1 基本概念
Link16是美国国防部选择的高速超视距战术数据链。Link16目前的通信载体是联合战术信息分发系统(Joint Tactical Information Distribution System,JTIDS),如下图所示。JTIDS包括射频设备、2类终端软件、硬件以及由它产生的具有保密、大容量和抗干扰特性的波形。Link16由TDMA协议、波形和TADILJ消息标准组成。
Link16 的组成
1.2 Link16数据链的技术特点
Link16数据链是一个集通信、导航和识别于一体的系统,使用TADIL J系列消息标准,为视距范围内的成员提供一个公共通信网络。当网络中有一个或者多个成员作为中继时,网络可以延伸到视距范围外的平台。
Link16数据链的技术特点如下:
1)抗干扰能力强,采用了多达7种抗干扰措施;
2)改进了保密性,采用了传输加密和消息加密两种加密方式;
3)提高了数据速率;
4)增加了信息交换的数量和量化度;
5)减小了终端的大小,可以安装在战斗机上;
6)具有数字化抗干扰保密话音的能力;
7)相对导航能力;
8)精确定位和识别的能力。
1.3 Link16数据链的TDMA接入方式
Link16是一种采用TDMA方式的无线广播网络。每个网络成员按照要求,依次轮流占用一定的时隙广播本平台产生的信息;当网络成员不广播信息时,则按照协议要求,接收其他网络成员广播的信息。Link16以一个任意指定成员的时钟为基准时钟,其它成员的时钟与基准时钟同步,从而形成一个统一的系统时钟。其中,作为基准时钟的成员被称为网络时间基准(Network Time Reference,NTR)。因为网络中所有成员的设备功能均相同,所以NTR可以接替,但是在任何时候系统中只能有一个NTR。
为了让广播能在成员间依次有序地轮转,Link16把系统时间细分成时元、时帧和时隙。1天24小时被划分为112.5个时元,即一个时元12.8min;每个时元又被划分为64个时帧,即一个时帧12s;每个时帧再进一步被细分为1536个时隙,即一个时隙7.8125ms。故每个时元包含的时隙数为98304个。其中,时隙是Link16网络的基本时间单位,网络成员按照管理要求按时隙发送和接收消息。
1.4 Link16数据链的消息结构
Link16系统所辐射的是成串的脉冲信号,每个时隙发射的信息构成一条消息。每个脉冲的宽度是6.4us,可以用一个码片宽度为0.2us的32位伪随机序列来表示。因为 ,所以每个脉冲可以载5比特信息。脉冲之间的间隔为13us。
关于具体脉冲字符格式、基本的传输结构、数据的封装结构、以及时隙类型这里不做详述,请自行查阅文献。
1.5 Link16数据链的传输波形
Link16信号源可以产生Link16波形,此波形可以在敌我对抗的复杂电磁环境下为多个网络用户提供完整可靠的通信服务。为了获得最强的抗干扰能力,Link16波形采取的抗干扰措施有:CRC检错编码、RS纠错编码、随机交织、双脉冲冗余,软扩频(CCSK)、抖动和跳频。Link16信号传输波形的产生流程图如下所示。
Link16 信号传输波形的生成
从上述流程图可以看出,Link16信号波形的产生有以下步骤:
第一步将要发射的数据分为210bit的一组或几组,再加上15bit的航迹号TN。第二步判断消息是否是自由电文,如果是则转到第四步。
第三步对每组的225bit(210bit的数据加上15bit的航迹号TN)作检错编码CRC(237,225)。
第四步按照图2.4中报头的格式,加上报头的其他数据使其扩充到35bit。
第五步是对上述的二进制比特数据进行基带加密处理。
第六步将数据以5bit为一个码元进行处理,并判断自由电文是否需要RS纠错编码,如果不需要则转到第八步。
第七步是在码元的基础上对报头和消息数据分别进行RS(16,7)和RS(31,15)。
第八步是对上述码元进行随机交织处理。
第九步用Link16规定的32位CCSK序列的不同移位代替相应的码元,即作CCSK(32,5),形成字符。
第十步是用32bit伪随机码对CCSK码字进行加密。
上述十步完成了所要发射消息的码字和消息的形成,可以称为消息/码字处理。接下来的步骤都被称为发射字符处理,这些步骤的处理改变的是发射信号的波形。
第十一步是发射字符的生成,即单脉冲字符或者双脉冲字符的生成。
第十二步是在报头前面按照协议要求加上粗同步头和精同步头。
第十三步完成MSK调制,并选择合适的跳频频率,将消息发送出去。
二、Link16 关键技术研究及通信数据链路仿真分析
由于采用了检纠错编码、随机交织和混合扩频等技术,使Link16系统具有很强的抗干扰能力。Link16系统模型如图所示。
Link16 系统框图
2.1 CRC 检错码
检错编码只能用于检错,而不能用于纠错。Link16采用的循环冗余检错编码CRC具有编译码简单、效率高和检测能力强等优点。CRC的基本思想是:在发送端将待发送的k位二进制消息序列,用约定的生成多项式g(x)产生一组r位的CRC校验码,然后将这n=k+r位数据发送出去;在接收端,将接收到n位码序列用与发送端相同的生成多项式g(x)去除它,若余数为0,则说明没有出现误码,传输正确。
Linkl6数据链中CRC模块采用的生成多项式是 ,是将210bit数据与15bit航迹号进行CRC(237,225),产生12bit的CRC校验位。210bit数据分为3组,每组70bit;12bit的校验位分为3组,每组4bit,再在每组的数据后加上一位“0”从而形成5bit的监督位。5bit监督校验位和70bit数据组成了75bit的Link16消息字。
2.2 RS 纠错码
RS码是由I.S.Reed和G.Solomon两人于1960年提出的,它是一种多进制BCH码,具有很强的纠错能力。RS码特别适用于突发信道中的纠错,如移动衰落信道。若其码长用n表示,则对于m进制的RS码,其码长n要满足:
对于能够纠正t个错误的RS码,其监督码元数r=2t,这时的最小码距d=2t+1。RS码的生成多项式是:
Link16数据链对消息和报头数据分别使用了RS(31,15)和RS(15,7)两种纠错编码,它们分别能够纠正8个和4个字符误码。比如RS(31,15)中的每个码字有31个字符,其中只有 15 个字符载有信息,其余 16 个字符是在发射机中为在接收时 纠错而附加上的检错字符。
2.2.1 RS编码技术仿真分析
RS 编码的性能
通过在AWGN信道下对RS码的误码性能进行仿真,比较有无RS码对系统产生的影响,其结果如上图所示。从图中可以看出,当信噪比SNR大于-2dB时,在相同的信噪比条件下,有RS码的系统的误码率明显低于没有RS码的系统,这就证明RS码具有纠正误码的能力,能够改善其误码性能。但是在信噪比SNR小于-2dB时,有RS码和没有RS码的系统的误码率都差不多,说明这时的RS码没有起到纠错的作用,这是因为系统误码的个数超出了其纠错能力。它能够纠正误码的个数肯定有一个上限,当超出这个上限时,RS码将不再发挥有效作用,还有可能越纠越错。Link16中采用的RS(31,15)和RS(16,7)的纠错上限分别是8个和4个。因此,要使RS编码能够正常的工作,则必须在一定的信噪比条件下,使误码的个数低于RS码纠错能力的上限。
2.3 交织技术
交织技术主要用于有记忆的信道,尤其是无线通信信道。交织技术的思想与RS码相反,RS码是为了适应信道,而交织技术则是为了改造通信信道。一个有记忆的突发信道通过交织和去交织技术可以改造成为一个独立的无记忆信道,如下图所示。许多信道差错都是突发的,即产生的误码往往有较强的相关性。这时由于误码都集中在一起,就有可能超出了纠错码的纠错上限。因此,在编码后采用交织技术,在译码前采用相应的解交织技术,就可以把一连串的突发错误分散开来变为独立的随机错误,这样就能充分利用RS码的作用了。
RS 码与交织系统框图
2.3.1 RS编码与交织技术结合的仿真
交织和 RS 编码的仿真
从上图可以看出,当信噪比SNR大于-4dB时,采用RS码和交织技术相结合的系统的误码率明显小于单独使用RS码的系统。因为当误码成串出现且超出RS码的纠错上限时,随机交织技术可以将成串的误码分散成为小的误码块,这样就可以减少连续误码的数目,使误码数在其纠错范围内;当SNR小于-4dB时,有无交织技术的两种系统的误码率相差不大,因为这时的信噪比过小,即误码数目很大,通过交织技术也不能将连续误码数减少到RS码的纠错上限内。
2.4 扩频技术
为了提高系统的抗干扰能力,Link16数据链采用了软扩频CCSK、跳频FH和跳时TH相结合的混合扩频技术。软扩频CCSK的采用使Link16波形具有很低的功率谱密度,敌方的实时侦查和破译就会变得很困难;跳频技术的采用使信号的载频伪随机变化,采用躲避的方式来对抗干扰,且不同的发端具有不同的跳频图案,跳频图案的不同能确保多个端机间不会产生相互干扰;跳时技术的使用使得敌方很难掌握信号发射的起始时间和传输规律。混合扩频技术的采用使Link16信号集合了这三种扩频方式的优势,提高了系统的可靠性。
2.4.1 扩频技术基础
扩频技术是指将待发送的信号扩展到很宽的频带上后再发射出去,使系统扩展后的射频带宽比扩展前原信号的带宽大得多。香农(Shannon)定理表明通信系统在高斯白噪声干扰下,其信道容量C(极限传输速率)是
其中,B为信号带宽;S是信号的平均功率;N是噪声功率。
由Shannon定理可知:
1)提高通信系统的传输速率,即增加信道容量C。增加C可以通过增加信号的带宽B或者增加信噪比S/N来完成。带宽B与系统容量C成正比,而信噪比S/N与C是对数关系。因此,对于增加信道容量C,增加B比增加S/N更有效。
2)当C为常数时,B与S/N可以互换。表明我们可以通过提高带宽B来降低对信噪比S/N的要求;也可以通过增加信号功率S(即增加S/N)来减小对信号带宽B的要求。
3)当带宽B提高到一定的程度后,C却不可能无限地增大。这是因为带宽B的增大使得噪声功率 也跟着增大,则S/N逐渐减小,进而影响了C的增加。考虑香农公式的极限情况,当带宽B趋于无限大时,信道容量C为 。
2.4.2 软扩频CCSK
①CCSK扩频
软扩频CCSK,又名循环码移键控,本质上是一种(N,m)编码,即m位原始信息用N位伪随机序列来表示。m位信息总共有 个状态,则需要 个长度为N的伪随机序列去表示这m位信息的 个状态。扩频率是N/m。Link16系统采用的是CCSK(32,5),其扩频系数是6.4,即用32位伪随机序列的循环移位去表示5bit的信息码,其对应关系如下表所示。这种软扩频方式所占带宽仅是传统二进制扩频方式的1/5。因此,软扩频非常适用于频谱宽度有限且又要求有一定扩频增益的场合。
Link16 采用的 32 位 CCSK 序列
②CCSK解扩
本文中的解扩利用了M序列的自相关特性。首先将接收到的32位序列与本地产生的32路不同循环移位的M序列进行相关运算,选取相关值最大的一路作为正确的解扩信号,然后根据相应的循环移位次数计算出原序列。
扩频序列性能的优劣很大程度上取决于其伪随机序列的自相关性能和互相关 性能。其中,自相关性能好则便于检测,而互相关性能好则便于抗多用户干扰。 因此,Link16 要求 CCSK 序列具有良好的自相关性。实际中,Link16采用的32位CCSK序列,即基码 : 具有良好的自相关性,它的Max(Ri)为4,在相关接收时最多能够容忍6bit的误码。若能找到一个序列,使它的Max(Ri)小于4,则它便具有更好的自相关性。基于这种思想,这里给出一个新的CCSK序列。
新的 CCSK 序列
将 Link16 采用的 CCSK 序列和上述新的 CCSK 序列的自相关性能进行对比,其仿真结果如下图所示。
自相关性验证代码:
close all; clear all;clc
m = [0 1 1 1 1 1 0 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 1 1 1 0 1 1 0 0];
N = length(m);v = 2*m-1;
n = 2*m-1;
corr1=pncorr(n,v,N);
%画图
figure
plot(-(N-1):(N-1),corr1,'b--');
hold on
title('CCSK32序列自相关性仿真');
xlabel('CCSK序列循环移位位数');ylabel('CCSK序列自相关值');
grid onx = [1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1 0];
NN = length(x);
vv = 2*x-1;
nn = 2*x-1;
corr2=pncorr(nn,vv,NN);
%画图
% figure
plot(-(N-1):(N-1),corr2,'r-');
% title('CCSK32序列自相关性仿真');
xlabel('CCSK序列循环移位位数');ylabel('CCSK序列自相关值');
grid on
legend('原来的CCSK序列','改进的CCSK序列')
axis([-32,32,-inf,inf])% ymin ymax
从仿真图中可以看出,新的CCSK序列的Max(Ri)仅为0,小于原CCSK序列的值4,即新的CCSK序列具有更好的自相关性。新的CCSK序列在相关解扩时具有7比特误码的纠正能力,比原序列多1比特。
2.5 信号调制映射
Link16采用的是MSK调制方式,最小频移键控(MSK)可以被看做是一种特殊的2FSK调制,它具有包络恒定、带宽最小、相位连续并且严格正交等特点。
关于MSK具体数学分析这里就不展开了,本文除了仿真Link16所采用的的MSK调制映射方式外,还仿真了BPSK、QPSK、16QAM、64QAM。
2.6 跳频传输
跳频通信系统的载频是由伪随机序列控制和选择的,其载频不断地伪随机跳变。不同于直接扩频通信系统,跳频通信系统中的伪码序列并不直接传递信息,而是被用于信道的选择。跳频通信的基本原理是:在发端,未调信号对频率是fs的载波做MSK调制,从而变为带宽为R的已调信号。频率控制字控制频率源在不同的时隙输出跳频通信所需要的本振信号,用它对已调信号进行上变频,使上变频后的射频信号频率按照跳频序列跳变。在收端,采用与发端跳变规律一致的本振信号对接收到的射频信号做下变频,从而可以把频率从射频下变频到fs以实现解跳。最后在本地载波的参与下,解跳后的已调信号经MSK解调后就可以恢复出原始的未调信息,跳频和解跳的框图如下图所示。
跳频系统实现框图
Link16 在 969~1206MHz 频段上按照 3MHz 的频率间隔选取 51 个频率作为其跳频点,如下图所示。系统工作时相邻脉冲间所选频点的间隔均要不小于 30MHz, 即 Link16 采用的是一种宽间隔跳频方式。
Link16 工作的 51 个跳频点
2.7 Link16通信数据链路的仿真
根据前面对 Link16 系统中关键技术的分析,使用Matlab完成系统仿真。
输入信号经过 CRC 校验、RS 编码、交织、CCSK 扩 频和 MSK 调制后,再选择合适的跳频频率发射出去;经过 AWGN 信道后,在接收端采用与输入端对应的解跳、MSK 解调、解扩、解交织、RS 译码和CRC解校验得到接收到的信号。通过计算误码率,分析系统抗干扰能力。
Link16通信数据链路仿真模型
2.7.1 仿真结果
三、总结分析
前面主要给出了Link16波形产生的过程,本文在信源的调制映射方式中只给出了MSK,其余QPSK、16QAM、64QAM原理类似,这里就不细说了。
四、MATLAB程序
下面是整个仿真过程的主程序,在实际应用中并非所有抗干扰技术都要使用上,根据需要进行取舍。
修改参数就可以用。
如果本文对你所有帮助,请点赞支持一下呀!
%% 知乎链接:https://www.zhihu.com/people/san-hao-bai-du-ren-79
%% 微信公众号:一个安静的资料号%% 简易跳频系统误比特率统计分析
% 调制-->跳频-->信道-->解跳-->解调-->误码分析
tic
clc;clear;close all;%% 参数设置
FH = 1; % 0: 不跳频传输 1:跳频传输
XINGZUO = 4;%BPSK:0 QPSK:1 '16QAM':2 '64QAM':3 'MSK':4
CRC_CODE = 0;%1: CRC编码 0:不CRC编码
DatainCode = 1;%'NO': 0 不编码 || 'rs':1 RS(31,15)编码 || 'juanji':2 (2,1,7)卷积编码
interwine = 1;
CCSK = 1;
% ******************** 系统参数设置*****************%
Rb = 5e4; % 速率:50Kb/s
Tb = 1 / Rb; % bit间隔% ********************跳频参数设置 *****************%
hopping = 1000; % 跳频速率
bitsPerHop = Rb / hopping; % 每跳bit数目(必须为整数)
samp = 20; % 过采样倍数
fs = samp*Rb; % 采样率
BW = 5e6; % 跳频带宽
freqNum = floor(BW / (Rb*4)); % 跳频频点数目
freqInterval = BW / freqNum; % 频点间隔
freqSeq = ([0:freqNum-1] - floor(freqNum/2)) * freqInterval; % 跳频频点序列
carrier = 3e6; % 跳频中心频率
carrierSeq = carrier + freqSeq; % 发送时跳频频点序列ts = 1/fs;
fd = 300; %多普勒频偏
pathPower = [-1.0 -1.0 -1.0 0 0 0 -3.0 -5.0 -7.0];
pathDelays = [0 50 120 200 230 500 1600 2300 5000]*1e-8;
rchan = comm.RayleighChannel('SampleRate',fs, ...'PathDelays',pathDelays,'AveragePathGains',pathPower, ...'MaximumDopplerShift',fd,'FadingTechnique','Sum of sinusoids');switch FHcase 0FIG_FH = '非跳频传输';case 1FIG_FH = '跳频传输';
end
% ********************调制参数设置 *****************%
switch XINGZUOcase 0 %'BPSK'xz_n = 1;FIG_XINGZUO = 'BPSK';case 1 %'QPSK'xz_n = 2;FIG_XINGZUO = 'QPSK';case 2 %'16QAM'xz_n = 4;FIG_XINGZUO = '16QAM';case 3 %'64QAM'xz_n = 6;FIG_XINGZUO = '64QAM';case 4 %'MSK'xz_n = 4;FIG_XINGZUO = 'MSK';
end
M = 2^xz_n;% ***************CRC(237,225) X^12+1 *****************%
switch CRC_CODEcase 0 %不采取检错编码crc_n = 1;case 1 %(237,225)检错编码crc_n = 225;
end
% ***************RS(31,15)编码参数*****************%
switch DatainCodecase 0 %0:不编码
% rs_m = 1;rs_k = 1;rs_m = 5; rs_n = 2^rs_m - 1;rs_t = 8; rs_k = rs_n - 2*rs_t ;%t: 能纠正的符号错误个数 k: 信息段长度FIG_code = '无纠错编码';case 1 %1: RS(31,15)编码rs_m = 5; rs_n = 2^rs_m - 1;rs_t = 8; rs_k = rs_n - 2*rs_t ;%t: 能纠正的符号错误个数 k: 信息段长度FIG_code = 'RS(31,15)编码';case 2 %2: (2,1,7)卷积编码
% rs_m = 1;rs_k = 1;rs_m = 5; rs_n = 2^rs_m - 1;rs_t = 8; rs_k = rs_n - 2*rs_t ;%t: 能纠正的符号错误个数 k: 信息段长度FIG_code = '(2,1,7)卷积编码';
end
% ************************产生信源信号*******************%
MSG_len = rs_m * rs_k * xz_n*crc_n; % 输入大小最好为rs_m * rs_k*xz_n的整数倍(后面会每rs_m位转换为十进制,然后gf的输入的列数必须为rs_k)
% ***************** 传输信息参数设置*****************%
SYNC_BIT_NUM = 0; % 同步bit数目
frameNum = 1; % 传输帧数目
PACKET_NUM = 3; % 每一帧的包数目
BIT_PER_PACKET = MSG_len*bitsPerHop; %每一包的比特数
MSG_BIT_NUM = BIT_PER_PACKET*PACKET_NUM; % 有效消息bit数目
TX_BIT_NUM = SYNC_BIT_NUM + MSG_BIT_NUM; % 需要发送的bit数目%% 构造发送序列
SYNC = randi([0 ,1] , 1 , SYNC_BIT_NUM); % 同步二进制序列(用一串随机序列代替)
MSG = randi([0,1] ,1 ,TX_BIT_NUM - SYNC_BIT_NUM); % 消息字符号
dataIn = [SYNC , MSG]; % 构造整个发送bit序列 % %% CRC检错编码
switch CRC_CODEcase 0dataIn_crc = dataIn';FIG_CRC_CODE = 'no CRC';case 1 %(237,225)检错编码poly = 'z12+1'; %多项式ChecksumsPerFrame = length(dataIn)/crc_n;%将传入帧细分为ChecksumsPerFrame个等长的子帧。因为每crc_n位数据编码一次crcgenerator = comm.CRCGenerator(poly,'ChecksumsPerFrame',ChecksumsPerFrame);%CRC编码生成器crcdetector = comm.CRCDetector(poly,'ChecksumsPerFrame',ChecksumsPerFrame);%CRC解码生成器dataIn_crc = crcgenerator(dataIn'); %CRC编码 输入应是列向量FIG_CRC_CODE = 'CRC(237,225)';
end
dataIn_crc = dataIn_crc';%转换回行向量%% 信源纠错编码
switch DatainCodecase 0encoded_msg = dataIn_crc; %1*30 0000case 1 %'rs' 每kk位编码为nn位%下面是(31,15)RS编码(每15个用31个来表示)nn = rs_n; %编码后码字长度(信息段+监督段)kk = rs_k; %信息段长度encoded_msg = LSY_RSCode(dataIn_crc,nn,kk);%1 * 62 0000%encoded_msg2 = LSY_RSCode(dataIn_crc,nn,kk);%第二种RS编码写法 这两种都是对的case 2 %'juanji' 每k位编码为n位%(n,k,m) n为输出长度 k为输入长度 m为编码约束度 n*(m+1)为约束长度 k/n为码率%下面是(2,1,7)卷积码L = 7; %约束长度tbdepth = 42; % Traceback depth for Viterbi decoder Viterbi译码器回溯深度 一般是约束长度的5-9倍trel = poly2trellis(L,[171,133]); %卷积码生成多项式encoded_msg = convenc(dataIn_crc,trel); %卷积编码 1*60 0000
end%% 交织 (对原数据分块进行处理:只是改变数据位置 不改变数据数量)
interwine_msg = zeros(1,length(encoded_msg));
switch interwinecase 0interwine_msg = encoded_msg;FIG_interwine = 'NO interwine';case 1rows = 10;cols = 100;%设定交织的深度与宽度 rows*cols应该等于输入矩阵的行数(因为交织按列取来做填充)division = length(encoded_msg)/(rows*cols);%交织次数for i =1:divisiontemp_data_1 = encoded_msg(1,(((i-1)*(rows*cols))+1):(i*(rows*cols)));%通过按列填充矩阵,并按行输出符号来恢复符号排序 https://www.jianshu.com/p/ac6c18fc3545temp_data_2 = matintrlv(temp_data_1,rows,cols);interwine_msg(1:i*rows*cols) = horzcat(interwine_msg(1:(i-1)*rows*cols),temp_data_2);endFIG_interwine = 'interwine';
end
%% CCSK软扩频 CCSK序列为32位switch CCSKcase 0ccsk_msg = interwine_msg;FIG_CCSK = 'NO CCSK';case 1% ccskcode=[0 1 1 1 1 1 0 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 1 1 1 0 1 1 0 0]';%Link16的CCSK序列 自相关性并不是最优ccskcode=[1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 1 1 0]';%优化后的CCSK序列 相关性更好 Link16 关键技术研究及系统建模%n_ccsk = 32;%CCSK序列长度ccsk_msg = LSY_CCSK32(interwine_msg,ccskcode);FIG_CCSK = 'NO CCSK';
end
%% 星座映射
data_xz= reshape(ccsk_msg,log2(M),[])'; %以每组log2(M)比特进行分组,M=4
data_xzde= bi2de(data_xz,'left-msb'); %二进制转化为十进制switch XINGZUOcase 0 %'BPSK'txSig = pskmod(data_xzde,M,pi/M); %已经归一化case 1 %'QPSK'txSig = pskmod(data_xzde,M,pi/M); %已经归一化case 2 %'16QAM'txSig = qammod(data_xzde,M,'UnitAveragePower',true);case 3 %'64QAM'txSig = qammod(data_xzde,M,'UnitAveragePower',true);case 4 %'MSK'TX_BIT_MAT = reshape(ccsk_msg , bitsPerHop , []); %如果是MSK 则按频点处理TX_BIT_MAT = TX_BIT_MAT'; [biNRZ , txSig0] = MSKmodulator(samp, TX_BIT_MAT); % 复基带调制矩阵txSig = reshape(txSig0' , [] , 1);
endavgPower = mean(abs(txSig).^2);
% scatterplot(txSig);title([FIG_XINGZUO,'星座图 ']);%% 补零(因为经过一系列处理后 数据不再是整数矩阵)
HOP_NUM = ceil(length(txSig) / (samp*bitsPerHop)); % 发送所有的bit需要的跳频点数
%(由于总的发送bit数目不一定是每跳bit数目bitsPerHop的整数倍,所以,构造为bitsPerHop的整数倍,在解调后去除多余bit即可)
EXCEED_BIT = HOP_NUM * samp * bitsPerHop - length(txSig); % 多余的bit
txSig = [txSig;zeros(EXCEED_BIT,1)];
% msgModMatrix = reshape(txSig , HOP_NUM , samp*bitsPerHop); % 将待发送序列转成一个矩阵,行:跳频点数,列: 每跳对应的bit序列
msgModMatrix = reshape(txSig , samp*bitsPerHop , HOP_NUM); % 将待发送序列转成一个矩阵,行:跳频点数,列: 每跳对应的bit序列
msgModMatrix = msgModMatrix.';%% 误比特分析参数设置snr = (-10:1:10); % Eb/No values (dB)
%snr = (0:0.2:15); % Eb/No values (dB)
rate = 1/2; % 码率
ber = zeros(1 , length(snr)); % 误bit率
berPacket = zeros(1 , length(snr)); % 误包率
CRC = zeros(1,length(snr));%% 误bit率分析(通过在不同的信噪比下传输多个帧做统计分析,可以通过增加传输帧数目获取更加精确的误比特率;更改信噪比获取不同信噪比下的性能)
for ii = 1 : length(snr)sumErrBit = 0;sumErrPacket = 0;snrdB = snr(ii) + 10*log10(log2(M)*rate); % Convert Eb/No to SNR for jj = 1 : frameNum%% 跳频
switch FHcase 0txFHmodulated = reshape(msgModMatrix.' , numel(msgModMatrix) , 1); % 将矩阵形式的信号转化为实际的1维信号 N_Interval = 200;N_Length= 4;
% txFHmodulated = tufaxindao(N_Interval,N_Length,txFHmodulated);
% channel_out = step(rchan,txFHmodulated);rcvNoisy = awgn(txFHmodulated , snrdB); % 添加噪声
% rcvNoisyMat = reshape(txFHmodulated , numel(txFHmodulated) / HOP_NUM , HOP_NUM); % 为了便于后面的解跳/解跳操作, 将1维信号还原为矩阵形式rcvNoisyMat = reshape(rcvNoisy , numel(rcvNoisy) / HOP_NUM , HOP_NUM); % 为了便于后面的解跳/解跳操作, 将1维信号还原为矩阵形式rcvBBmat = rcvNoisyMat.'; case 1fhIndex = randi([1 , freqNum] , 1 , HOP_NUM); % 根据跳频点数生成随机频点序列索引txFHtable = carrierSeq(fhIndex); % 根据随机频点序列索引生成跳频频点(收发频点保持一致才可以解跳)txFHmodulatedMat = FHmodulator(msgModMatrix , txFHtable , fs); % 跳频后的信号%% 信道txFHmodulated = reshape(txFHmodulatedMat.' , 1 , numel(txFHmodulatedMat)); % 将矩阵形式的信号转化为实际的1维信号rcvNoisy = awgn(txFHmodulated , snrdB); % 添加噪声rcvNoisyMat = reshape(rcvNoisy , numel(rcvNoisy) / HOP_NUM , HOP_NUM); % 为了便于后面的解跳/解跳操作, 将1维信号还原为矩阵形式rcvNoisyMat = rcvNoisyMat.'; % 行:跳数,列: 每跳对应的带噪声的调制信号% scatterplot(rxSig)% eyediagram(z,16);%眼图%% 解跳并去掉冗余bitrcvBBmat = FHdemodulator(rcvNoisyMat , txFHtable , fs); % 根据冗余bit数目去除多余bit
endrcvBB1dim = reshape(rcvBBmat.' , 1, numel(rcvBBmat));rcv_data = rcvBB1dim(1:end-EXCEED_BIT); %去掉末尾的0 %% 星座解调 % 还原信号为连续形式rxSig = reshape(rcv_data,[],1);switch XINGZUOcase 0 %'BPSK'data_dec = pskdemod(rxSig,M,pi/M);data_dec = reshape(data_dec,[],1);data_dec_bi = de2bi(data_dec, log2(M), 'left-msb');%转换成m位二进制dmdBit = reshape(data_dec_bi',1,[]);case 1 %'QPSK'data_dec = pskdemod(rxSig,M,pi/M);data_dec = reshape(data_dec,[],1);data_dec_bi = de2bi(data_dec, log2(M), 'left-msb');%转换成m位二进制dmdBit = reshape(data_dec_bi',1,[]);case 2 %'16QAM'data_dec = qamdemod(rxSig,M,'UnitAveragePower',true);data_dec = reshape(data_dec,[],1);data_dec_bi = de2bi(data_dec, log2(M), 'left-msb');%转换成m位二进制dmdBit = reshape(data_dec_bi',1,[]);case 3 %'64QAM'data_dec = qamdemod(rxSig,M,'UnitAveragePower',true);data_dec = reshape(data_dec,[],1);data_dec_bi = de2bi(data_dec, log2(M), 'left-msb');%转换成m位二进制dmdBit = reshape(data_dec_bi',1,[]);case 4 %'MSK'% 差分解调rxSig = reshape(rxSig , 1 , numel(rxSig)); % 还原信号为连续形式rcvBBsamp = reshape(rxSig , samp , numel(rxSig)/samp); % 转换成每samp一个单元(即以bit为采样单元)dmdBit = imag(conj(rcvBBsamp(samp,:)) .* rcvBBsamp(1,:)) >0; %conj函数:用于计算复数的共轭值 end%% 解扩
switch CCSKcase 0ccsk_dec = double(dmdBit);case 1ccsk_dec = LSY_CCSKde32(dmdBit,ccskcode);
end
%% 解交织
deinterwine_data = zeros(1,length(ccsk_dec));
switch interwinecase 0deinterwine_data = ccsk_dec;case 1for k = 1:divisiontemp_data_1 = ccsk_dec(1,(((k-1)*(rows*cols))+1):(k*(rows*cols)));temp_data_2 = matdeintrlv(temp_data_1,rows,cols);deinterwine_data(1:k*rows*cols) = horzcat(deinterwine_data(1:(k-1)*rows*cols),temp_data_2);end
end
%% 信道译码
switch DatainCodecase 0 %'NO'dataOut_dc = deinterwine_data;case 1 %'rs' dataOut_dc = LSY_RSDec(deinterwine_data,nn,kk);
% [num,Ber(i)]=biterr(dataOut_dc,dataIn);case 2 %'juanji'dataOut_dc = vitdec(deinterwine_data,trel,tbdepth,'trunc','hard'); %Viterbi译码 %cont表示连续调用模式(此时在第一个被解码的符号出现在输出中之前,会出现一个等于输入tbdepth符号的延迟。误比特计算要用下面这种方式) trunc表示截断模式
end
%% 检错解码
switch CRC_CODEcase 0dataOut = dataOut_dc;case 1 %(237,225)检错编码[dataOut_crc, dataOut_crc_err] = crcdetector(dataOut_dc');%输入为列向量 dataOut_crc CRC解码输出 dataOut_crc_err错误个数CRC(i) = sum(dataOut_crc_err);dataOut = dataOut_crc';
end
% [num,Ber(i)] = biterr(dataOut,dataIn); %计算误比特率% 计算误bit数(包括同步序列和消息序列,不包括冗余序列)errBitNum = sum(dataIn ~= dataOut);sumErrBit = sumErrBit + errBitNum;% 计算误包率orignalPacket = dataIn(SYNC_BIT_NUM+1 : end);dmdPacket = dataOut(SYNC_BIT_NUM+1 : end); orignalPacketMat = reshape(orignalPacket , MSG_BIT_NUM/PACKET_NUM , PACKET_NUM); % bit序列转换成包,每一列一包dmdPacketMat = reshape(dmdPacket , MSG_BIT_NUM/PACKET_NUM , PACKET_NUM); % bit序列转换成包,每一列一包% 统计误包(比较一包里面的bit是否与发送端向相同,不同加1,相同加0)sumErrPacket = ...(sum(orignalPacketMat(:, 1) ~= dmdPacketMat(:, 1))>0)+...(sum(orignalPacketMat(:, 2) ~= dmdPacketMat(:, 2))>0)+...(sum(orignalPacketMat(:, 3) ~= dmdPacketMat(:, 3))>0)+sumErrPacket;[ii jj]end % 计算误bit率ber(ii) = sumErrBit / (frameNum*TX_BIT_NUM);berPacket(ii) = sumErrPacket/(frameNum*PACKET_NUM);
end%% 误码输出
figure
semilogy(snr,ber,'-*')
save MSK+RS+CCSK+FH ber
hold on
grid onBER_qpsk = duibizu_qpsk(dataIn,snr,PACKET_NUM);
save MSK+RS+CCSK BER_qpsk
semilogy(snr,BER_qpsk,'-o')
hold onBER_16qam = duibizu_16qam(dataIn,snr,PACKET_NUM);
save MSK+CCSK BER_16qam
semilogy(snr,BER_16qam,'-x')
hold onBER_64qam = duibizu_64qam(dataIn,snr,PACKET_NUM);
save MSK BER_64qam
semilogy(snr,BER_64qam,'-s')
hold ongrid on
xlabel('Eb/No (dB)')%如果不进行转换就是SNR
ylabel('误比特率')%如果不进行转换就是误码率legend('MSK+RS+CCSK+FH','MSK+RS+CCSK','MSK+CCSK','MSK')toc
五、参考文献
[1]姚超. Link16数据链抗干扰技术研究及中频信号源的实现[D].重庆大学,2015.
[2]李伟. 对Link16数据链的干扰技术研究[D].西安电子科技大学,2018.
[3]黄承江. Link16数据链物理层波形关键技术研究与验证[D].电子科技大学,2019.