2FSK数字通信系统matalb实现

2FSK数字通信系统matalb实现
最近一直想自己手动写一个通信程序,将整个通信过程一点一滴实现一下,下面将整个过程给大家分享一下下。
整个通信系统结构
英文文本作为信源,然后对信源进行ASCII编码,编码后进行了循环编码BCH(127,64),然后进行2FSK调制,再过信道,解调,信道译码、信源译码,最后准确无误得出最初的英文文本。
下面详细介绍一下整个过程。
首先是信源编码,直接对英文文本取十进制值然后将它转为二进制,每个字母用8比特表示,比较简单。
然后是BCH信道编码。编码的实现比较简单,但是这部分是我查资料最多的部分。BCH详细的编码原理这里不说了,确实比较复杂,具体实现过程为:用码字多项式乘以x^(n-k)与生成多项式相除所得余式再与他们的乘积相加。编码过程就结束了,具体实现时不一定非得在伽罗瓦域,只要模2就好了。
然后是调制部分,2FSK,也比较简单,只要对信源取反分别和载频相乘就好。
解调可以用相干解调,但在突发信号的情况下,需要极其精确的突发信号检测才能保证准确无误。解调时也可以对信号进行分帧,分帧长度取信号码元长度,做fft后检测对应频点的幅度,来解调,适用情况更多一些。这一期就现给大家分享相干解调。
信道解码部分自己实现确实比较困难,因此我调用了matalb内置函数bchdec。
信源解码比较简单,每8位转为十进制,再对应字母即可。
下面就给大家展示一下成果吧。(matalb2020b)第一个代码是2FSK调制解调,使用相干解调法。

% function Modulatation = Modulate(bin,Fs,Fc,Bw,Rb)
% 
% end
clc,clear;
Rb = 200;           %码元速率200
T = 1/Rb;           %码元宽度
Tm = 100;
M = 100;             %码元个数
totalT = T*M;       %信号持续时间

dt = T/Tm;          %采样间隔
Fs = 1/dt;
Fc = 1600;
Bw = 600;

t = 0:dt:totalT-dt;     %时间
wave = randi([0,1],1,M); %待调制数据
n = length(t);

jidai1 = zeros(1,length(t));
n = length(t);

for i = 1:length(t)
    flag = mod(i,100);
    if flag ~=0
    j = floor(i/100)+1;
    jidai1(i) = wave(j);
    else j = j+1;
    end
end

figure(1);                  % 绘制第2幅图
subplot(511);               % 窗口分割成2*1的,当前是第1个子图 
plot(t,jidai1,'LineWidth',2) % 绘制基带码元波形,线宽为2
title('基带信号波形')% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签
axis([0,totalT,-0.1,1.1])   % 坐标范围限制

jidai2 = mod(jidai1 + 1,2);   
carry1 = cos(2*pi*(Fc+Bw/2)*t);
carry2 = cos(2*pi*(Fc-Bw/2)*t);


fsk = jidai1.*carry1 + jidai2.*carry2;

fsk=awgn(fsk,30);           % 信号fsk中加入白噪声,信噪比为SNR=20dB


fp1=2*(Fc-Bw/2-Rb);             % 第一个带通滤波器频率1
fs1=2*(Fc-Bw/2+Rb);             % 第一个带通滤波器频率2
b1=fir1(30, [fp1/Fs fs1/Fs], boxcar(31));% 生成fir滤波器系统函数中分子多项式的系数

band1=fftfilt(b1,fsk);      % 对信号进行滤波,fsk是等待滤波的信号,b1是fir滤波器的系统函数的分子多项式系数
subplot(512)                % 窗口分割成3*1的,当前是第2个子图 
plot(t,band1,'LineWidth',2) % 绘制经过低通滤波器后的信号
axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("fsk经过带通滤波器1后的信号");% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签



fp2=2*(Fc+Bw/2-Rb);             % 第二个带通滤波器频率1
fs2=2*(Fc+Bw/2+Rb);             % 第二个带通滤波器频率2
b2=fir1(30, [fp2/Fs fs2/Fs], boxcar(31));% 生成fir滤波器系统函数中分子多项式的系数

band2=fftfilt(b2,fsk);      % 对信号进行滤波,fsk是等待滤波的信号,b1是fir滤波器的系统函数的分子多项式系数
subplot(513)                % 窗口分割成3*1的,当前是第2个子图 
plot(t,band2,'LineWidth',2) % 绘制经过低通滤波器后的信号
axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("fsk经过带通滤波器2后的信号");% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签

subplot(514)  
fftband1 = abs(fft(band1))/n*2;
fftband2 = fftband1(1:n/2);
f = Fs/n-1:Fs/n:Fs/2-1;
plot(f,fftband2,'LineWidth',2) % 绘制经过低通滤波器后的信号
% axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("fsk经过带通滤波器1后的频谱");% 标题
xlabel('频率/f');           % x轴标签
ylabel('幅度');             % y轴标签

subplot(515)  
fftband3 = abs(fft(band2))/n*2;
fftband4 = fftband3(1:n/2);
f = Fs/n-1:Fs/n:Fs/2-1;
plot(f,fftband4,'LineWidth',2) % 绘制经过低通滤波器后的信号
% axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("fsk经过带通滤波器2后的频谱");% 标题
xlabel('频率/f');           % x轴标签
ylabel('幅度');             % y轴标签



figure(2)
s1 = band1.*band1;
subplot(511)                % 窗口分割成3*1的,当前是第2个子图 
plot(t,s1,'LineWidth',2) % 绘制经过低通滤波器后的信号
axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("与低频相乘");% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签


s2 = band2.*band2;
subplot(512)                % 窗口分割成3*1的,当前是第2个子图 
plot(t,s2,'LineWidth',2) % 绘制经过低通滤波器后的信号
axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("与高频相乘");% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签

fp3=2*Rb;                   % 低通滤波器截止频率
b3=fir1(30, fp3/Fs, boxcar(31));% 生成fir滤波器系统函数中分子多项式的系数

lvbo1=fftfilt(b3,s1);      % 对信号进行滤波,jt1是等待滤波的信号,b3是fir滤波器的系统函数的分子多项式系数
lvbo2=fftfilt(b3,s2);      % 对信号进行滤波,jt2是等待滤波的信号,b3是fir滤波器的系统函数的分子多项式系数
subplot(513)                % 窗口分割成3*1的,当前是第2个子图 
plot(t,lvbo1,'LineWidth',2) % 绘制经过低通滤波器后的信号
axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("低频支路");% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签
subplot(514)                % 窗口分割成3*1的,当前是第2个子图 
plot(t,lvbo2,'LineWidth',2) % 绘制经过低通滤波器后的信号
axis([0,totalT,-1.1,1.1]);  % 设置坐标范围
title("高频支路");% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签


%抽样判决
unmodulate = zeros(1,M);
for i = 1:M
    if abs(lvbo1(100*(i-1)+50))>abs(lvbo2(100*(i-1)+50))
        unmodulate(i) = 0;
    else
        unmodulate(i) = 1;
    end
end 

下面这一段是信源编码部分

 words = input("Input your string:","S") ;  %含提示的字符串输入
% words = fileattrib('"D:\兴趣\wdqwd.txt"','+w');
bits = abs(words);%将输入文本转化为ASCII码对应的10进制
data = [];
for i = 1:length(bits)
    data1 = de2bi(bits(i));
    b = data1;
    for j = 1:length(data1)
        data1(j) = b(length(data1)-j+1);
    end
        if length(data1) < 8
            data2 = [zeros(1,8-length(data1)) data1];
        else
        end
        data = [data,data2];
end

下面是信道编码部分,生成多项式gx是系统码的生成多项式,可以在许多书籍中查到,也可以是使用函数生成。

gx = 1206534025570773100045;             %其最高项次数位n-k
bin = oct2bin(gx);                       %将生成多项式用二进制数字表示
n = 127;k = 64; e = 10;
while 0 == bin(1)    
    bin = bin(2:length(bin));
end
R = mod(length(data),64);                %将待编码数据补0成为64的倍数
if R~=0
    data = [data,zeros(1,64-R)];   
end
m1 = zeros(1,64);                        %寄存分割后的信源序列
x1=zeros(1,n-k+1);               
x1(1)=1;                                 %x^n-k
encode = [];                             %最终编码数据
for i = 1:length(data)/64
    m1 = data((i-1)*64+1:(i-1)*64+64);
    c1=conv(m1,x1);              %m(x)* x^n-k    
    c1 = mod(c1,2);
    [~,r]=deconv(c1,bin);        
    r=mod(r,2);                  %取m(x)* x^n-k/g(x)的余式
    c = mod(c1+r,2);             %m(x)* x^n-k/g(x)的余式与m(x)* x^n-k相加                                     
    encode = [encode,c];
end

最后是整个完整的代码,速速Ctrl+C

% function Modulatation = Modulate(bin,Fs,Fc,Bw,Rb)
% 
% end
clc,clear;
Rb = 200;           %码元速率200
T = 1/Rb;           %码元宽度
Tm = 100;
 words = input("Input your string:","S") ;  %含提示的字符串输入
% words = fileattrib('"D:\兴趣\wdqwd.txt"','+w');
bits = abs(words);%将输入文本转化为ASCII码对应的10进制
data = [];
for i = 1:length(bits)
    data1 = de2bi(bits(i));
    b = data1;
    for j = 1:length(data1)
        data1(j) = b(length(data1)-j+1);
    end
        if length(data1) < 8
            data2 = [zeros(1,8-length(data1)) data1];
        else
        end
        data = [data,data2];
end

%%
%%信道编码BCH(127,64),纠错能力为10
gx = 1206534025570773100045;             %其最高项次数位n-k
bin = oct2bin(gx);                       %将生成多项式用二进制数字表示
n = 127;k = 64; e = 10;
while 0 == bin(1)    
    bin = bin(2:length(bin));
end
R = mod(length(data),64);                %将待编码数据补0成为64的倍数
if R~=0
    data = [data,zeros(1,64-R)];   
end
m1 = zeros(1,64);                        %寄存分割后的信源序列
x1=zeros(1,n-k+1);               
x1(1)=1;                                 %x^n-k
encode = [];                             %最终编码数据
for i = 1:length(data)/64
    m1 = data((i-1)*64+1:(i-1)*64+64);
    c1=conv(m1,x1);              %m(x)* x^n-k    
    c1 = mod(c1,2);
    [~,r]=deconv(c1,bin);        
    r=mod(r,2);                  %取m(x)* x^n-k/g(x)的余式
    c = mod(c1+r,2);             %m(x)* x^n-k/g(x)的余式与m(x)* x^n-k相加                                     
    encode = [encode,c];
end


%%
%进行2FSK调制
M = length(encode);   %信道编码后码元个数
totalT = T*M;       %信号持续时间
dt = T/Tm;          %采样间隔
Fs = 1/dt;
Fc = 1600;
Bw = 600;
t = 0:dt:totalT-dt;     %时间
n = length(t);

jidai1 = zeros(1,length(t));
n = length(t);
for i = 1:length(t)
    flag = mod(i,100);
    if flag ~=0
    j = floor(i/100)+1;
    jidai1(i) = encode(j);
    else j = j+1;
    end
end
figure(1);                  % 绘制第2幅图
subplot(511);               % 窗口分割成2*1的,当前是第1个子图 
plot(t,jidai1,'LineWidth',2) % 绘制基带码元波形,线宽为2
title('基带信号波形')% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签
axis([0,totalT,-0.1,1.1])   % 坐标范围限制

jidai2 = mod(jidai1 + 1,2);   
carry1 = cos(2*pi*(Fc+Bw/2)*t);
carry2 = cos(2*pi*(Fc-Bw/2)*t);
fsk = jidai1.*carry1 + jidai2.*carry2;

fsk=awgn(fsk,30);           % 信号fsk中加入白噪声,信噪比为SNR=20dB

fftfsk = abs(fft(fsk))/n*2;
fftfsk2 = fftfsk(1:n/2);
f = Fs/n-1:Fs/n:Fs/2-1;
subplot(512);   
plot(f,fftfsk2,'LineWidth',2) % 绘制经过低通滤波器后的信号
title("fsk频谱");% 标题
xlabel('频率/f');           % x轴标签
ylabel('幅度');             % y轴标签

%%
%解调
fp1=2*(Fc-Bw/2-Rb);             % 第一个带通滤波器频率1
fs1=2*(Fc-Bw/2+Rb);             % 第一个带通滤波器频率2
b1=fir1(30, [fp1/Fs fs1/Fs], boxcar(31));% 生成fir滤波器系统函数中分子多项式的系数
band1=fftfilt(b1,fsk);      % 对信号进行滤波,fsk是等待滤波的信号,b1是fir滤波器的系统函数的分子多项式系数

fp2=2*(Fc+Bw/2-Rb);             % 第二个带通滤波器频率1
fs2=2*(Fc+Bw/2+Rb);             % 第二个带通滤波器频率2
b2=fir1(30, [fp2/Fs fs2/Fs], boxcar(31));% 生成fir滤波器系统函数中分子多项式的系数
band2=fftfilt(b2,fsk);      % 对信号进行滤波,fsk是等待滤波的信号,b1是fir滤波器的系统函数的分子多项式系数
 
%相干
s1 = band1.*band1;
s2 = band2.*band2;
%低通滤波
fp3=2*Rb;                   % 低通滤波器截止频率
b3=fir1(30, fp3/Fs, boxcar(31));% 生成fir滤波器系统函数中分子多项式的系数
lvbo1=fftfilt(b3,s1);      % 对信号进行滤波,jt1是等待滤波的信号,b3是fir滤波器的系统函数的分子多项式系数
lvbo2=fftfilt(b3,s2);      % 对信号进行滤波,jt2是等待滤波的信号,b3是fir滤波器的系统函数的分子多项式系数
%抽样判决
unmodulate = zeros(1,M);
for i = 1:M
    if abs(lvbo1(100*(i-1)+50))>abs(lvbo2(100*(i-1)+50))
        unmodulate(i) = 0;
    else
        unmodulate(i) = 1;
    end
end

unmodulate1 = zeros(1,length(t));
for i = 1:length(t)
    flag = mod(i,100);
    if flag ~=0
    j = floor(i/100)+1;
    unmodulate1(i) = unmodulate(j);
    else j = j+1;
    end
end
subplot(513)                % 窗口分割成3*1的,当前是第2个子图 
plot(t,unmodulate1,'LineWidth',2) % 绘制经过低通滤波器后的信号
axis([0,totalT,0,1.1]);  % 设置坐标范围
title("解调波形");% 标题
xlabel('时间/s');           % x轴标签
ylabel('幅度');             % y轴标签

%%
%信道译码
encode2 = zeros(length(unmodulate)/127,127);
for i = 1:length(unmodulate)/127
    for j = 1:127
        encode2(i,j) = unmodulate(j+127*(i-1));
    end
end

encode1 = gf(encode2);
uncode = bchdec(encode1,127,64);
undata = [];
 if mod(length(unmodulate)/127,2) == 0
    for i = 0:2:length(unmodulate)/127-1
    undata = [undata uncode(i+1,:) uncode(i+2,:)];
    end
 else
     for i = 0:2:length(unmodulate)/127-3
        undata = [undata uncode(i+1,:) uncode(i+2,:)];
        if i == length(unmodulate)-3
            break;
        end
     end
   undata = [undata uncode(length(unmodulate)/127,:)];
end
%%
%信源译码

dec = [];
for j = 1:length(undata)/8;
    c = undata(8*(j-1)+1:8*(j-1)+8);
    dec =[dec bin2dec(num2str(c.x))];
    
end
   txt = char(dec);

    fid = fopen('D:\matalb2020\uncode_text\text.txt', 'w');
    fprintf(fid, '%s', txt);
    fclose(fid);
  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值