使用m序列仿真基础BPSK-DSSS直扩收发机,比对误码数量
(可以视作收发载波同步、无噪、信号起始位置已知)
原理:
直接扩频序列的原理就是对待输入信号乘以一组伪随机序列PN码。从时域上看,就是将原本较长的码元变成了一个个较短的chip。从频谱上看,时域相乘对应频谱卷积,等价于扩展了了频谱。直扩通信原理的时域、频域示意如图所示:
直扩通信原理时域、频域示意图
%代码示例
clc;clear all;
interpolation_rate =4; %内插系数
data_length =10; %测试数据长度
fc = 125e5; %载波数字频率fc/fs
fs = 100e6; %采样频率
w_carrier = fc/fs;
Sample_position = 0; %最佳采样点
EbN0 = 12;
%EbN0
n =3 ;%m序列长度(2^n-1)
%根升余弦滤波器
alpha = 0.35;
span = 6;
hrc = rcosdesign(alpha,span,interpolation_rate,'sqrt');
data_send = randi([0,1],data_length,1); %0/1序列
data_bio = 1-2*data_send; %对极序列
%%扩频
PN = mseq(n,[1 3], [1 1 1], 1);
PN =1-2*PN; %对极m序列
LPN = length(PN);%计算PN码的长度,即为扩频比
PN2 = fliplr(PN);%翻转PN序列
data_upsample_pn = upsample(data_bio,LPN);
stem(data_bio);title('发送源信号');
DS_data = conv(data_upsample_pn,PN); %完成直扩
plot(DS_data);title('扩频后信号');
DS_data_upsample = upsample(DS_data,interpolation_rate);%内插
plot(DS_data_upsample);title('内插后信号');
%成型滤波
baseband = conv(DS_data_upsample,hrc);
plot(baseband);title('成型滤波后信号');
carrier = cos(2*pi*w_carrier*[0:length(baseband)-1]); %载波
send_ds_bpsk = baseband'.*carrier; %载波调制
plot(send_ds_bpsk);title('载波调制后信号');
snr = EbN0 +10*log10(2)-10*log10(interpolation_rate)-10*log10(LPN);
rece_DS_bpsk = awgn(send_ds_bpsk,snr,'measured');%加噪
recv_carrier = rece_DS_bpsk.*carrier; %解调
plot(recv_carrier);title('解调后信号');
%匹配滤波
recv_data = conv(recv_carrier,hrc);
plot(recv_data);title('匹配滤波后信号');
data_rDS = conv(recv_data,upsample(PN2,interpolation_rate)); %解扩——与本地PN码相关
plot(data_rDS);title('解扩后信号');
dalay= length(hrc)+(LPN-1)*interpolation_rate;
data_rDS_eff = data_rDS(dalay:end-dalay+1);
plot(data_rDS_eff);
rdata_bipolar = downsample(data_rDS_eff,interpolation_rate*LPN,0);
stem(rdata_bipolar);hold on;stem(data_bio);hold off;
rdata = rdata_bipolar(1:data_length+1);
%码元判决
res = zeros(1,data_length);
for j = 1:data_length
if rdata(j) < 0
res(j) = 1;
end
end
rece_databio = res';
samebit = (rece_databio == data_send);
error = data_length-length(find(samebit == 1))
error_b = error/data_length;
fprintf('误码率: %f\n', error_b);
绘图结果
注意
1、 信噪比的计算不同于非扩频
snr = EbN0 +10log10(2)-10log10(内插系数)-10*log10(扩频比);
2、关于通过滤波器后产生的延时
应该是滤波器的延迟是其脉冲响应长度的一半。即length(hrc)/2。但是需要注意的一点是这里讲的延时是通过一次滤波器(进行一次卷积操作),而在整个通信系统中需要进行一次成型滤波和匹配滤波。因此在进行完匹配滤波后想要获取有效的数据应该从脉冲响应长度位置处开始截取:
%补偿延迟
recv_data = recv_data(length(hrc):end-length(hrc)+1);
但是本系统中由于扩频操作利用了卷积的形式,因此也存在一定的延时
dalay= length(hrc)+(LPN-1)interpolation_rate;
data_rDS_eff = data_rDS(dalay:end-dalay+1);
rdata_bipolar = downsample(data_rDS_eff,interpolation_rateLPN,0);
补充
m序列产生函数
function [mout] = mseq(n, taps, inidata, num)
% ****************************************************************
% n : m序列的阶数n[3]
% taps : 反馈寄存器的连接位置[1 3]
% inidata : 寄存器的初始值序列 是一个一维向量,[1 1 1]
% 指定 m 序列的初始状态。该向量的长度必须小于或等于 n。如果 init 的长度小于n,则在其前面填充零。
% num : 输出的m序列的个数
% mout : 输出的m序列,如果num>1,则每一行为一个m序列
% ****************************************************************
mout = zeros(num,2^n-1);
fpos = zeros(n,1);
fpos(taps) = 1;
for ii=1:2^n-1
mout(1,ii) = inidata(n); % 寄存器的输出值
temp = mod(inidata*fpos,2); % 计算反馈数据
inidata(2:n) = inidata(1:n-1); % 寄存器移位一次
inidata(1) = temp; % 更新第1个寄存器的值
end
if num > 1 %如果要输出多个m序列,生成其他m序列
for ii=2:num
mout(ii,:) = shift(mout(ii-1,:),1);
end
end