0
点赞
收藏
分享

微信扫一扫

【Matlab通信仿真设计】

快乐码农Alan007 2022-01-20 阅读 42

DS-CDMA通信系统

基本过程

(1)设计一个采用直接序列扩频的码分多址系统DS-CDMA,仿真基站发送信息给两个用户的下行通信过程:发送给两个用户的信息速率相同,模拟信号采用matlab的相关指令产生至少200个范围在正负1的的随机信号;

(2)上述的随机信号经13折线PCM调制后变成数字信号(随机信号可理解为已经抽样后的信号,再经过量化和编码为二进制数字信号),两路数字信号分别经由正交的扩频码(PN1,PN2)进行10倍扩频, PN1和PN2选用64位长的两个不同walsh码;

(3)BPSK调制后的两路信号由基站汇合后发射,经过高斯白噪声信道后被用户1和用户2的手机接收;

(4)在接收端对分别对接收信号进行解扩,判决,得到恢复的数字信号,比较b1’(n)与b1(n),b2’(n)和b2(n),统计误比特率,绘制其中一个用户的误比特率随信噪比的变化曲线;

(5)最后将b1’(n)和b2’(n)进行PCM解码,跟发送端的模拟信号进行比较,统计在不同信噪比下的平均误差,绘制其中一个用户的误差值随信噪比的变化曲线。

流程图

图一
图二
图三

代码部分

clear
%生成序列
%user1 用户1的随机序列
%user2 用户2的随机序列
user1=2*rand(1,200)-1;%生成用户1随机序列
max1= max(abs(user1));
user2=2*rand(1,200)-1;%生成用户2随机序列
max2= max(abs(user2));

%PCM编码
%user1_code 用户1PCM码
%user2_code 用户2PCM码
user1_code=PCM(user1);%用户1调用PCM编码函数
user2_code=PCM(user2);%用户2调用PCM编码函数

%单极性转化双极性
%b1n 用户1PCM码转换的双极性码
%b2n 用户2PCM码转换的双极性码
b1n=user1_code;
b2n=user2_code;
b1n(b1n==0)=-1;%将PCM得到的user1单极性码转换为双极性
b2n(b2n==0)=-1;%将PCM得到的user2单极性码转换为双极性

%扩频码
%walsh_code 64*64的walsh矩阵
%pn1 第34行的walsh码
%pn2 第35行的walsh码
walsh_code=hadamard(64);%生成64位walsh矩阵
pn1=walsh_code(34,:);%选用walsh矩阵第33行作为用户1的扩频码
pn2=walsh_code(35,:);%选用walsh矩阵第33行作为用户1的扩频码
pn1=repmat(pn1,1,250);%16000÷64=250,因此需要将pn码循环250次。
pn2=repmat(pn2,1,250);%16000÷64=250,因此需要将pn码循环250次。

%扩频
b1n=rectpulse(b1n,10);%将数据延拓为原来的10倍,
b2n=rectpulse(b2n,10);%将数据延拓为原来的10倍,
user1_spread=spread_spectrum(b1n,pn1);%调用扩频函数
user2_spread=spread_spectrum(b2n,pn2);%调用扩频函数

n = 1;%储存误码率,平均误差

for snr=-20:0.1:20
%信道传输添加高斯白噪声
%code 输入信道前的码
%receive_code 信道传输后的码
    code=user1_spread+user2_spread;%将要在信道中传输的信号等于扩频后的b1n+b2n
    receive_code=awgn(code,snr);%接收到的信号经过存在高斯白噪声的信道
    %解扩
    %de_spread1 乘以pn1码后的解扩信号
    %de_spread2 乘以pn2码后的解扩信号
    de_spread1=de_spread_spectrum(receive_code,pn1);%对接收的信号使用pn1解扩
de_spread2=de_spread_spectrum(receive_code,pn2);%对接收的信号使用pn2解扩

    %判决
    de_user1_code = verdict( de_spread1);
    de_user2_code = verdict( de_spread2);

    %计算误码率
    bit_error_rate1(n)= error_num(user1_code,de_user1_code) / 1600;
    bit_error_rate2(n)= error_num(user2_code,de_user2_code) / 1600;

    %PCM译码
    %User1 给用户1的信号
    %User2 给用户1的信号    
    User1=PCMdecoding(de_user1_code,max1);%译码
    User2=PCMdecoding(de_user2_code,max2);%译码
    
 % 计算失真度
    errors1(n)=0; 
    for i=1:200
        dc=abs(User1(i)-user1(i))/200;
        errors1(n)=errors1(n)+dc;
    end
    errors2(n)=0; 
    for i=1:200
        dc=abs(User2(i)-user2(i))/200;
        errors2(n)=errors2(n)+dc;
    end
    n = n + 1;
end

figure;
X1 = (-20:0.1:20);
semilogy(X1,bit_error_rate1,'b');
xlabel('信噪比(dB)');
ylabel('误码率');
title('误码率随信噪比的变化曲线');
% axis([-20 20 0.000001 1]);
hold on;
semilogy(X1,bit_error_rate2,'r');
legend('用户1','用户2');
grid on;
%平均误差
figure;
X1 = (-20:0.1:20);
semilogy(X1,errors1,'b');
xlabel('信噪比(dB)');
ylabel('平均误差');
title('PCM编、译码后的平均误差随信噪比的变化曲线');
% axis([-20 20 0.000001 1]);
hold on;
semilogy(X1,errors2,'r');
legend('用户1','用户2');
grid on;

function user_code=PCM(user)%PCM编码函数
y=zeros(200,8); %使用一个0矩阵来储存PCM编码值
user_=fix(2048*abs(user));%使用abs函数取绝对值,乘以2048,然后四舍五入靠0取整。
user_code=zeros(1,1600);%最终输出时的矩阵序列初始值。
m=0;
for i=1:200
    %符号位判断
    if user(i)>0%原输入大于零则符号位为1,小于零则符号位为0,在这里不用变化
        y(i,1)=1;
    end
    %段落码判断
    if user_(i)>128&&user_(i)<2048 %在第五段与第八段之间,段落码第一位为1
        y(i,2)=1;
    end
    if (user_(i)>32&&user_(i)<128)||(user_(i)>512&&user_(i)<2048)%在第三第四第七第八段内,段落码第二位为1
        y(i,3)=1;
    end
    if (user_(i)>16&&user_(i)<32)||(user_(i)>64&&user_(i)<128)||(user_(i)>256&&user_(i)<512)||(user_(i)>1024&&user_(i)<2048)%在第二第四第六第八段内,段落码第三位为1
        y(i,4)=1;
    end
    %段内码判断
    n=zeros(200);
    for j=1:200
        n(j)=y(j,2)*4+y(j,3)*2+y(j,4)+1; %找到位于第几段
    end
    a=[0,16,32,64,128,256,512,1024]; %量化间隔
    b=[1,1,2,4,8,16,32,64]; %除以16,得到每段最小的量化间隔
    for j=1:200
        q=ceil((user_(j)-a(n(j)))/b(n(j))); %求出在段内的位置
        if q==0
            y(j,(5:8))=[0,0,0,0]; %输入为0,输出为0
        else
            k=num2str(dec2bin(q-1,4)); %段内码编码为二进制
            y(j,5)=str2num(k(1));
            y(j,6)=str2num(k(2));
            y(j,7)=str2num(k(3));
            y(j,8)=str2num(k(4));
        end
    end
end
for i=1:200
    for j=1:8
        m=m+1;
        user_code(1,m)=y(i,j);
    end
end
end

function res=spread_spectrum(bn,pn) %扩频函数
res=bn.*pn;%点乘
end

function res=de_spread_spectrum(code,pn) %解扩函数
res=code.*pn;%点乘
end

function data_decision = verdict( de_spread )%判决函数
%data_decision 对加扰信号进行解扰判别    matlab 索引是从1开始
%   de_spread 收到的加扰信号
%   data 原始信号
for i=1:1600
    for j = 1:10
        temp(j)=de_spread(10*(i-1)+j);
    end
    if(sum(temp) < 0)%判别
        data_decision(i)=0;
    else
        data_decision(i)=1;
    end
end
end

function user_Decode=PCMdecoding(de_user_code, max)%PCM译码
de_user_code=(reshape(de_user_code',8,length(de_user_code)/8))';
    l=size(de_user_code,1);
    a=[0,16,32,64,128,256,512,1024];
    b=[1 1 2 4 8 16 32 64];
    c=[0 1.5:15.5];
    for i=1:l
        x=de_user_code(i,1);
        T=bin2dec(num2str(de_user_code(i,(2:4))))+1;
        Y=bin2dec(num2str(de_user_code(i,(5:8))));
        if Y==0
            k(i)=a(T)/2048;
        else
            k(i)=(a(T)+b(T)*c(Y))/2048;
        end
        if x==0
            user_Decode(i)=-k(i);
        else
            user_Decode(i)=k(i);
        end
    end
    user_Decode = user_Decode*max;
end

function bit_error_num=error_num(user_code,de_user_code)%计算误码个数
%user_code PCM编码后的单极性码
%de_user_code 判决后的序列(单极性码)
%bit_error_numw 误差数量
bit_error_num=0;
for i=1:1600
    if(de_user_code(i)~=user_code(i))
        bit_error_num=bit_error_num+1;
    end
end
end

运行结果

图四
图五

总结

该码分多址系统使用matlab仿真基站发送信息给两个用户的下行通信过程。重点在于扩频倍数10倍与64位PN码的关系,例如该系统假设的用户数据为200个,那么总共的码元数为1600个(每个数据由8位码组成),若要扩频10倍则需使每个码再复制10倍,即16000个码,同时这16000个码恰为64的整数倍才可实现直接扩频。最终的结果以用户码传输前后平均误差和误码率呈现,信噪比越大,误差越小。可知信噪比对传输效率的影响有多重要。

举报

相关推荐

0 条评论