%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 课程作业-直接序列扩频信号的产生与捕获模拟
% 调用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