【无标题】ADC-B报文识别&CRC检码&采样率转换

加载一段1090ES信号,对标准112位报文(详情请自查)通过阈值进行识别,并且提取标准报文段。

clc
clear all
file = "D:\ADS_B_data.dat";
fid = fopen(file, 'r');
N = 327680;
s_array = fread(fid,[327680, 375],'int16');

% 数据处理 采样率转换

% 12.8MHz*5/4=16MHz
si = 18;
thr = 80;
s = s_array(:, si);
s = s(2:2:end) + sqrt(-1) * s(1:2:end);
Fs = 1.28e7;
T = 1/Fs;
s_n = 0: T: T*(length(s)-1);
s_amp = abs(s);
%% 插值滤波 滤波插值
% interp
inter_Fs = 5*Fs;
inter_T = 1/inter_Fs;
int_s = zeros(5*length(s), 1);
int_s(1:5:end) = s;
int_s_amp = abs(int_s);
int_n = 0:inter_T:(5*length(s)-1)*inter_T;
%filt1
v = lowpass(int_s, Fs*5/64 *10, inter_Fs);  % 10MHz
v_amp = abs(v);
%filt2
v1 = lowpass(v, Fs*5/64 *5, inter_Fs);  % 5MHz
v1_amp = abs(v1);
% deci
dec_Fs = 5*Fs/4;
dec_T = 1/dec_Fs;
dec_s = v1(1:4:end);
dec_n = 0: dec_T: (5*length(s)/4-1)*dec_T;
dec_amp = abs(dec_s);
figure(1); stem(dec_amp, "b", "filled"); title("Decimated Sequence");

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 根据门限值检测LEP(上升沿)并记录点索引
LEP_index = [];
for i = 1:length(dec_amp)
    if dec_amp(i) > thr
        LEP_index = [LEP_index, i];
    end
end
% disp(length(LEP_index));
% 记录连续continue_n个有效样本值的点为有效高脉冲VPP(高脉冲带宽)
VPP_index = [];
continue_n = 5;
for i = 1: length(LEP_index)-continue_n  % 防止超出索引
    if sum(LEP_index(i:i+4))-continue_n*LEP_index(i)==10
        VPP_index = [VPP_index, LEP_index(i)];
    end
end

% 选择只记录VPP首值索引
repet_index = []; % 记录VPP中其他索引值
for i = 2:length(VPP_index)
    if VPP_index(i-1)+1 == VPP_index(i) 
       repet_index = [repet_index, i];
    end
end
VPP_index(repet_index) = []; % 将VPP中其他索引值置0
%disp(VPP_index);
% VPP间隔点数
Delta_ns = [];
for i = 2: length(VPP_index)
    Delta_n = VPP_index(i) - VPP_index(i-1);
    Delta_ns = [Delta_ns, Delta_n];
end
%disp(Delta_ns);
% VPP 间隔时间
VPP_n = dec_n(VPP_index);
Delta_ts = [];
for i = 2: length(VPP_n)
    Delta_t = VPP_n(i) - VPP_n(i-1);
    Delta_ts = [Delta_ts, Delta_t];
end
% disp(sum(Delta_ts));
% 根据报头间距记录报头位置 % 根据间距查找尾部
%disp(Delta_ts);
Err_toler = 3*T;  % 误差三个点
head_index = [];
end_index = [];
for i = 1: length(Delta_ts)-2
    if abs(Delta_ts(i)-1e-6) < Err_toler & abs(Delta_ts(i+1)-2.5*1e-6) < Err_toler & abs(Delta_ts(i+2)-1e-6) < Err_toler
        head_index = [head_index, VPP_index(i)];
        for j = i+4:length(Delta_ts)
            if Delta_ts(j) > 2.2*1e-6
               end_index = [end_index, VPP_index(j)];
               break        
            end
        end
    end
end
% 补齐end_index最后一值
if length(head_index) ~= length(end_index) 
    end_index = [end_index, VPP_index(end)];
end
% 去除非112位长度的报文编码
Code_Len = end_index-head_index;
head_index(Code_Len < 112*16) = []; % 将不符合长度的去掉
end_index(Code_Len < 112*16) = [];
disp([si, head_index, end_index, end_index - head_index]);
if isempty(head_index)
    error("未检出合格ADS_B编码!");
end
% 求取自适应阈值 = 一个VPP幅值均值与底噪差的一半并加上底噪均值。
signal_mean = sum(dec_amp(head_index(1):head_index(1)+7))/8;
noise_mean = sum(dec_amp(head_index(1)-8:head_index(1)-1))/8;
thr_ada = (signal_mean-noise_mean)/2+noise_mean; 
disp(thr_ada);
% 转换成二值信号
binary_sequence = [];
for i = head_index(1): head_index(1)+16*120-1
    if dec_amp(i) > thr_ada
        binary_sequence(i-head_index(1)+1) = 1;
    else 
        binary_sequence(i-head_index(1)+1) = 0;
    end
end    
%disp(binary_sequence)
figure(2);subplot(211); plot(binary_sequence); %axis([-20, 1050, -0.5, 3]); title("Binary sequence");
% 计算报文编码(前高后低为1,前低后高为0)
ADS_B_code = [];
for i = 16*8+1: 16: length(binary_sequence)
    if mean(binary_sequence(i:i+7)) > 0.8 & mean(binary_sequence(i+8:i+15)) < 0.2
        ADS_B_code = [ADS_B_code, 1];
    else 
        ADS_B_code = [ADS_B_code, 0];
    end
end
%disp(ADS_B_code);
figure(2);subplot(212); stem(ADS_B_code, "b", "filled"); 
%Code_ME_Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Code_DF = bin2dec(num2str(ADS_B_code(1:5)));  % 数值到char
if Code_DF == 17
    disp("DF=17 用于S模式应答机发出ADS-B报文");
    Code_ME = ADS_B_code(33: 88);
    ME_Type = bin2dec(num2str(Code_ME(1:5)));



elseif Code_DF == 18
    disp("DF=18 用于非S模式应答机发出ADS-B报文或TIS-B报文!")
elseif Code_DF == 19
    disp("DF=19用于军事用途!")
else
    disp([Code_DF, "报文格式不符合!"])
end

%disp(ADS_B_code(end-23: end))

获取到标准112位报文后需进行 CRC校验(原理待更新…)

K = ADS_B_code;
G = [1 1 1 1  1 1 1 1  1 1 1 1  1 0 1 0  0 0 0 0  0 1 0 0  1];% 25位的生成多项式
R = mod2div(K, G); % 模二除法函数
if ~R
    disp("报文校验通过!");
    %disp(R);
else
    disp("报文校验不通过!");
    disp(R);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 模二除法函数
function r = mod2div(K, G)  % 余数 被除数 除数
    while length(K) ~= length(G)-1
        if K(1) == 1
            r = xor(K(1: length(G)), G);
            K = [r(2:length(G)), K(length(G)+1: end)];
        else
            r = xor(K(1: length(G)), zeros(1, length(G)));
            K = [r(2:length(G)), K(length(G)+1: end)];
    
        end
    end
    r = K; % 被除数位数不足除数除数时即为余数
end




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值