⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsss.m

📁 主要是仿真了gold码、数据的调制、加噪、解调以及数据恢复的过程。
💻 M
字号:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   课程作业-直接序列扩频信号的产生与捕获模拟
%           调用GoldGenerator.m生成GOLD伪码
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fPN = 1023;         % 伪码速率
fCarrier = fPN*30;    % 载波频率 > 伪码速率
fSample = fCarrier * 4; % 载波的采样点频率
%chip = 31;          % 伪码长度,普通码31位
chip = 1023;       % 伪码长度,GOLD码1023位
dataLength = 10;   % 待发送数据位数


% 初始化随机数,每次不同
rand('twister', sum(100*clock)); %产生均匀分布的随机变量
randn('state', sum(100*clock));  %产生高斯分布的随机变量
% 待发送数据
sourceData = randsrc(1, dataLength, [0 1]); % 0,1的数据源
sourceData
sendDataLength = dataLength * chip; % 准备调制发送时的数据长度,目前一样,没有在数据前面加噪音
figure(1);
stem(sourceData);
title('数据源');


% 生成GOLD码
pnSequence = GoldGenerator();          % GOLD码1024位
figure(2);
stem(pnSequence(1:50));
title('1023位gold码');

% 扩频
spreadData = zeros(1, dataLength*chip);
temp = ones(1, chip);
for i = 1:dataLength
    temp = ones(1, chip)*sourceData(i);
    % 相加模2,异或
    spreadData(((i-1)*chip+1):i*chip) = xor(temp, pnSequence);
end
figure(3);
stem(spreadData(1:50));
title('扩频后的数据');

% 调制输出
%[sendedMData,t] = modulate(h, spreadData);
%h = modem.pskmod();
%sendedMData = modulate(h, spreadData);
[sendedMData,t] = dmod(spreadData, fCarrier, fPN, fSample, 'psk', 2);
sendedMDataLength = length(sendedMData);
figure(4);
plot(t(1:50),sendedMData(1:50));
title('经BPSK调制后的数据');

% 附加白噪声
recvMData = awgn(sendedMData, -20, 'measured', 'dB'); 
%recvMData = sendedMData;
figure(5);
plot(recvMData(1:50));
title('附加白噪声后的数据');
% 解调成数字信号
recvDData = ddemod(recvMData, fCarrier, fPN, fSample, 'psk', 2);
recvDDataLen = length(recvDData);       % 捕获到的数据长度
figure(6);
stem(recvDData(1:50));
title('解调后的信号');

% 接收数据有效码捕获的阈值
thresholdUp = 0.2;
thresholdDn = 0.8;

% 每次取5个码字长度的数据进行捕获测试
testVCodes = 5;

% 解调数据末尾追加4倍chip的0,防止在捕获时数据溢出
recvDData = [recvDData zeros(1, chip*(testVCodes-1))];

despreadData = zeros(1, dataLength);    % 存放解扩后的数据

    
% 判断阈值的依据
power = zeros(1, chip*testVCodes);
for i=1:chip*testVCodes
    power(i) = sum(xor(pnSequence, recvDData(i:i+chip-1)))/chip;    % 计算能量
end

figure(8);
plot(power);
title('能量对比');

% TAG111

% 采用串行方法捕获
m = 1;
i = 1;
while(m <= (recvDDataLen-chip+1))
    % 查看是否是码字的起始位置
    % 取连续5个码字长度的数据,一起作为判断依据
    toVerf = recvDData(m: m+chip*testVCodes-1);
    totalVCodes = 0;    % 此次检测站,总检测的码字数
    yesVCodes = 0;      % 超过阈值,认为是码字的数目
    noVCodes = 0;       % 不认为是的数目
    while (totalVCodes < testVCodes)
        if (totalVCodes*chip+m > recvDDataLen)    % 后面的已经不需要再计算了,没有数据 
            break;
        end
        power = sum(xor(pnSequence, toVerf((totalVCodes*chip+1):(totalVCodes+1)*chip)))/chip;    % 计算能量
        if((power >= thresholdUp) || (power <= thresholdDn))
            yesVCodes = yesVCodes + 1;
        end
        totalVCodes = totalVCodes + 1;
    end
    
    % 阈值判断是否是有效码字, 0.7
    if(yesVCodes < totalVCodes*0.7)
        m = m+1;
        continue;
    end

    % 是有效码字
    % 对码块数据与伪码进行加1模2,恢复原数据
	% M/N判别
	if sum(xor(pnSequence, recvDData(m:m+chip-1))) > chip*thresholdUp
    	despreadData(i) = 1;
    else
    	despreadData(i) = 0;
	end
    m = m + chip;
    i = i + 1;
end
% 判断正确数据的个数
correct = 0;
for i = 1:dataLength
    if despreadData(i) == sourceData(i)
        correct = correct + 1;
    end
end
despreadData
figure(7);
stem(despreadData);
title('恢复后的数据');
correct/dataLength

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -