第一次记录QPSK,BSPK,MPSK,QAM—MATLAB实现

news2025/1/16 21:52:18

最近有偶然的机会学习了一次QPSK防止以后忘记又得找资料,这里就详细的记录一下

        基于 QPSK 的通信系统如图 1 所示,QPSK 调制是目前最常用的一种卫星数字和数 字集群信号调制方式,它具有较高的频谱利用率、较强的抗干扰性、在电路上实现也较为简单,在后文仅仅使用MATLAB进行模拟。

图 1 基于QOSK调制的通信系统模型

        其相位图如图 2 所示,二进制数 0 和 1 分别表示两个相位,为了提高传输速率,通 常可以采用多项调制的方法,即将待发的数字信号按两比特一组的方式组合,两位二进 制数的组合方式又四种—(00,01,10,11)。每个组合是一个双比特码,通常可以用四 个不同的相位值表示这四组双比特码。在传输过程中,相位改变一次,传输两个二进制 数。这种调相方法成为四项调相或四项调制,广泛广泛应用 于卫星链路、数字集群等 通信业务。

图2相位图

如图 3 所示,QPSK 信号可以采用正交调制器来实现 

图3 QPSK信号生成原理图

 根据图1和图3的原理图,就可以开始着手写MATLAB代码了。 我将其分为以下几个方面

  1. 模拟源信号
  2. 源信号->双极性信号
  3. 双极性信号转为QPSK信号
  4. QPSK信号经过模拟信道传输,引起失真。
  5. 采用相干解调法分离QPSK信号。
  6. 低通滤波过滤噪音
  7. 抽样判决获得信号
  8. 最后将信号极性反转获得源信号

QPSK详细代码如下,在代码中已经做好注释了。

%% 采用代码实现的4PSK通信系统仿真
% 假设在T=1,加入高斯噪声
clc;
clear all;
close all;
%% 发端
% 1.调制,生成二进制信号
bit_in = randi([0 1],1000,1); 
% 2.变为双极性码
data = -2*bit_in+1;        
% 3.串并转换模块:奇数位为I,偶数为为Q
data_I  = data(1:2:1000);   % 间断获取 I
data_Q  = data(2:2:1000);   % 间断获取 Q
data_I1=repmat(data_I',20,1);
data_Q1=repmat(data_Q',20,1);

% 按列优先将data_I1中的数据存入data_I2
for i=1:1e4
    data_I2(i)=data_I1(i);
    data_Q2(i)=data_Q1(i);
end

% 4.产生升余弦的基带信号
f=0:0.1:1;
xrc=0.5+0.5*cos(pi*f); 

data_I2_rc=conv(data_I2,xrc)/5.5;
data_Q2_rc=conv(data_Q2,xrc)/5.5;

figure
subplot(2,2,1)
stem(bit_in(1:20),'black','LineWidth',2);
axis([0,20,0,1]);
title("发送的消息序列");
subplot(2,2,2)
plot(f,xrc,'black','LineWidth',2);
title("升余弦信号");
subplot(2,2,3)
plot(data_I2_rc(1:20),'black','LineWidth',2);
title("升余弦I信号");
subplot(2,2,4)
plot(data_Q2_rc(1:20),'black','LineWidth',2);
title("升余弦Q信号");

% 5. 正交调制(调相法:将基带数字信号(双极性)与载波信号直接相乘的方法)
f1=1;                        % 载波频率
t1=0:0.1:1e3+0.9;

I_rc=data_I2_rc.*cos(2*pi*f1*t1);
Q_rc=data_Q2_rc.*sin(2*pi*f1*t1);
x=(sqrt(1/2).*I_rc+sqrt(1/2).*Q_rc);

figure(1)
subplot(2,1,1);
plot(t1,x,'black','LineWidth',2); xlabel('t'); ylabel('幅度'); 
grid on; 
axis([0 1/f1*10 -1.2 1.2]);  % 输出2个周期的信号
title('QPSK信号'); 

%% 6.仿真信道噪声
n0=rand(size(t1))/2;
y=x+n0;

subplot(2,1,2);
plot(t1,y,'black','LineWidth',2); xlabel('t'); ylabel('幅度'); 
grid on; 
axis([0 1/f1*10 -2 2]);  % 输出2个周期的信号
title('带噪声的QPSK信号'); 


%% 仿真接收端
% 7.正交解调:只能采用相干解调
I_demo=y.*cos(2*pi*f1*t1);
Q_demo=y.*sin(2*pi*f1*t1);
% 8.低通滤波
I_recover=conv(I_demo,xrc);    
Q_recover=conv(Q_demo,xrc);
I=I_recover(11:10010);
Q=Q_recover(11:10010);

% 9.抽样判决
data_recover=[];
for i=1:20:10000
    data_recover=[data_recover I(i:1:i+19) Q(i:1:i+19)];
end
bit_recover=[];
for i=1:20:20000
    if sum(data_recover(i:i+19))>0
        data_recover_a(i:i+19)=1;
        bit_recover=[bit_recover 1];
    else
        data_recover_a(i:i+19)=-1;
        bit_recover=[bit_recover -1];
    end
end

% 10.变为单极性码
bit_recovered=(1-bit_recover)/2; 
figure(2)
subplot(2,1,1)
stem(bit_in(1:20),'black','LineWidth',2);
axis([0,20,0,1]);
title("发送的消息序列");

subplot(2,1,2)
stem(bit_recovered(1:20),'black','LineWidth',2);
axis([0,20,0,1]);
title("接收的消息序列");

figure(3)
subplot(2,1,1)
stem(bit_in(1:20),'black','LineWidth',2);
axis([0,20,0,1]);
title("发送的消息序列");

subplot(2,1,2)
stem(data(1:20),'black','LineWidth',2);
axis([0,20,-1,1]);
title("双极性码");
set(gcf,'color','w')

BSPK的代码也贴在这里

clc
clear
close all;

%%初始化参数设置
data_len = 100000;                       % 原始数据长度
SNR_dB = 0:10;                           % 信噪比 dB形式
SNR = 10.^(SNR_dB/10);                   % Eb/N0
Eb = 1; % 每比特能量
N0 = Eb./SNR ; %噪声功率
error2 = zeros(1,length(SNR_dB));          % 码元错误个数
simu_ber_BPSK = zeros(1,length(SNR_dB));         % 仿真误误码率
theory_ber_BPSK = zeros(1,length(SNR_dB));   % BPSK理论误码率
demod2_signal= zeros(1,data_len);         % 解调信号

%%基带信号产生
data_source = round(rand(1,data_len));  % 二进制随机序列

%%BPSK基带调制   
send_signal2 = (data_source - 1/2)*2; % 双极性不归零序列 

%%高斯信道无编码
for z = 1:length(SNR_dB)
     noise2 = sqrt(N0(z)/2) * randn(1,data_len); %高斯白噪声
     receive_signal2 = send_signal2 + noise2;
     demod_signal2 = zeros(1,data_len);
        for w = 1:data_len
                if (receive_signal2(w) > 0)
                demod_signal2(w) = 1;              % 接收信号大于0  则判1
                else
                demod_signal2(w) = 0;              % 接收信号小于0  则判0
                end
        end
        %统计错误码元个数
       for w = 1:data_len
           if(demod_signal2(w) ~=data_source(w) )
                  error2(z) = error2(z) + 1;    % 错误比特个数
           end
       end
           %计算误码率
        simu_ber_BPSK(z) = error2(z) / data_len;         % 仿真误比特率
        theory_ber_BPSK(z) = qfunc(sqrt(2*SNR(z)));   % 理论误比特率
end

    

%%二进制序列、基带信号图像
figure(1);
stem(data_source);
title("二进制随机序列");
axis([0,50,0,1]);
figure(2);
stem(send_signal2);
title("BPSK基带调制--发送信号");
axis([0,50,-1.5,1.5]);

figure(4);
stem(noise2);
title("高斯白噪声");
axis([0,50,-0.5,0.5]);

figure(5)
stem(receive_signal2);
title("接收信号");
axis([0,50,-1.5,1.5]);

figure(7)
stem(demod_signal2);
title("解调信号");
axis([0,50,0,1]);

figure(8);
 semilogy(SNR_dB,simu_ber_BPSK,'M-X',SNR_dB,theory_ber_BPSK,'k-s');     

grid on;                                      
axis([0 10 10^-5 10^-1])                      
xlabel('Eb/N0 (dB)');                     
ylabel('BER');                                  
 legend('BPSK仿真误码率','BPSK理论误码率');  

%%画星座图
scatterplot(send_signal2);
title('发送信号星座图');
scatterplot(receive_signal2);
title('接收信号星座图');
scatterplot(demod_signal2);
title('解码信号星座图');


MPSK代码

clc;
clear all;
close all;
%% 调用库函数实现MPSK的通信系统仿真

M=4;
cycl=80;       % 运行次数
SNR=0:1:30;    % 信噪比
s=randi([0 M-1],1,1000);  % 输入信息一行1000列;

BER1=zeros(cycl,length(SNR));

for  n=1:cycl
    for k=1:length(SNR)
        x=pskmod(s,M,pi/4);               % M进制PSK
        y=awgn(x,SNR(k),'measured');      % 在传输序列中加入噪声
        r=pskdemod(y,M,pi/4);             % 解调
        r1=reshape(r',1,[]);
        [num,rat]=biterr(r1,s,log2(M));           % 误码率计算
        BER1(n,k)=rat;
    end
end

figure(1)
subplot(2,1,1)
stem(s(1:20),'black','LineWidth',2);
axis([0,20,0,M]);
title("发送的消息序列");

subplot(2,1,2)
stem(r1(1:20),'black','LineWidth',2);
axis([0,20,0,M]);
title("接收的消息序列");


%% 8PSK
M=8;
cycl=80;       % 运行次数
SNR=0:1:30;    % 信噪比
s=randi([0 M-1],1,1000);  % 输入信息一行1000列;

BER2=zeros(cycl,length(SNR));

for  n=1:cycl
    for k=1:length(SNR)
        x=pskmod(s,M,pi/4);               % M进制PSK
        y=awgn(x,SNR(k),'measured');      % 在传输序列中加入噪声
        r=pskdemod(y,M,pi/4);             % 解调
        r1=reshape(r',1,[]);
        [num,rat]=biterr(r1,s,log2(M));           % 误码率计算
        BER2(n,k)=rat;
    end
end

figure(2)
subplot(2,1,1)
stem(s(1:20),'black','LineWidth',2);
axis([0,20,0,M]);
title("原始消息序列");

subplot(2,1,2)
stem(r1(1:20),'black','LineWidth',2);
axis([0,20,0,M]);
title("传递消息序列");

% 统计平均误码率
figure(3)

BER1=mean(BER1);
subplot(2,1,1)
semilogy(SNR,BER1,'k-o','LineWidth',2);
xlabel('SNR/dB'); ylabel('BER');
title("4PSK");
grid on

BER2=mean(BER2);
subplot(2,1,2)
semilogy(SNR,BER2,'k-o','LineWidth',2);
xlabel('SNR/dB'); ylabel('BER');
title("8PSK");
grid on

QAM代码也在这里

clc;
clear all;
close all;
%% 基于16QAM的通信系统仿真
% 发端
nbit=10000; 
M=16;                                              % M表示QAM调制的阶数
k=log2(M);
graycode=[0 1 3 2 4 5 7 6 12 13 15 14 8 9 11 10];  % 格雷映射编码规则
EsN0=5:20;                         % 信噪比范围
snr=10.^(EsN0/10);                 % 将db转换为线性值
% 产生16进制的消息符号
s=randi([0,1],1,nbit);         
s_reshape=reshape(s,k,nbit/k)';    % 对数据流进行分组,对于16QAM,则每4位一组
msg=bi2de(s_reshape,'left-msb');   % 转化成10进制,作为qammod的输入
% 进行格雷映射
msg1=graycode(msg+1);        
% 调制
r=qammod(msg1,M);         % 调用matlab中的qammod函数,16QAM调制方式的调用(输入0到15的数,M表示QAM调制的阶数)得到调制后符号
spow1=norm(r).^2/nbit;    % 取a+bj的模.^2得到功率除整个符号得到每个符号的平均功率
for i=1:length(EsN0)
    % 信道
    sigma=sqrt(spow1/(2*snr(i)));                          % 16QAM根据符号功率求出噪声的功率
    x=r+sigma*(randn(1,length(r))+1i*randn(1,length(r)));  % 16QAM混入高斯加性白噪声
    % 16QAM的解调
    y1=qamdemod(x,M);             
    % 格雷逆映射
    y2=graycode(y1+1);        % 返回译码出来的信息,十进制
    test=de2bi(y2,k,'left-msb');
    y3=reshape(test',1,nbit);
    [err1,ber1(i)]=biterr(s,y3); 
end
%% 绘图
figure(1)
subplot(2,1,1)
stem(s(1:20),'black','LineWidth',2);
axis([0,20,0,1.2]);
title("发送的消息序列");

subplot(2,1,2)
stem(y3(1:20),'black','LineWidth',2);
axis([0,20,0,1.2]);
title("接收的消息序列");

scatterplot(r);           % 调用matlab中的scatterplot函数,画星座点图
scatterplot(x);           % 调用matlab中的scatterplot函数,画rx星座点图

% 16QAM调制信号在AWGN信道的性能
figure( )
semilogy(EsN0,ber1,'black','LineWidth',2);                            % ber ser比特仿真值 ser1理论误码率 ber1理论误比特率
title('16QAM调制信号在AWGN信道的性能分析');grid;
xlabel('Es/N0(dB)');                      
ylabel('误比特率');                          

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1331500.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于STM32单片机模拟智能电梯步进电机控制升降毕业设计3

STM32单片机模拟智能电梯步进电机控制数码管显示3 演示视频(复制到浏览器打开): 基于STM32单片机的智能电梯控制系统模拟智能电梯步进电机控制系统设计数码管显示楼层设计/DIY开发板套件3 产品功能描述: 本系统由STM32F103C8T6单…

技术交底二维码的应用

二维码技术交底可以逐级落实、责任到人、有据可查、是目前最方便、实用的交底方式,下面我们讲解技术交底二维码的应用。 1、生成对应的技术交底二维码,将施工方案、技术资料、安全教育资料等内容上传到二维码里。打印出来现场粘贴,便于作业班…

(一)深入理解Mysql底层数据结构和算法

什么是索引 索引是帮助MySQL高效获取数据的排好序的数据结构 数据结构有哪些 数据结构模拟网站:Data Structure Visualization 二叉树 不适合做自增ID的数据结构。如下示意图,假设采用二叉树作为表自增主键ID的数据存储结果如下:当查询i…

行列式:方程组未知数的计算:克拉默法则

行列式:方程组未知数的计算 ![ ](https://img-blog.csdnimg.cn/direct/4a9c2800da3746ea95c1a3c93057d796.png)

VS Code实现“Ctr+save”保存代码自动格式化

一、下载Prettier - Code formatter插件 点击安装即可 二、配置 【1】打开文件——首选项——设置 或者左下角齿轮打开设置 【2】搜索设置框输入editor default formatter(意思是默认格式化设置),接着下拉选中刚下好的插件名称Prettier - C…

【Vulnhub 靶场】【Corrosion: 1】【简单】【20210731】

1、环境介绍 靶场介绍:https://www.vulnhub.com/entry/corrosion-1,730/ 靶场下载:https://download.vulnhub.com/corrosion/Corrosion.ova 靶场难度:简单 发布日期:2021年07月31日 文件大小:7.8 GB 靶场作者&#xf…

Windows安装cnpm报错 The operation was rejected by your operating system.

Windows在安装cnpm时出现如下错误 npm ERR! The operation was rejected by your operating system. npm ERR! Its possible that the file was already in use (by a text editor or antivirus), npm ERR! or that you lack permissions to access it. npm ERR! npm ERR! If y…

[vue]Echart使用手册

[vue]Echart使用手册 使用环境Echart的使用Echart所有组件和图表类型Echart 使用方法 使用环境 之前是在JQuery阶段使用Echart,直接引入Echart的js文件即可,现在是在vue中使用,不仅仅时echarts包,还需要安装vue-echarts: "…

智能优化算法应用:基于鹈鹕算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于鹈鹕算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于鹈鹕算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鹈鹕算法4.实验参数设定5.算法结果6.参考文献7.MA…

C语言——小细节和小知识6

一、转义字符相关 \ 反斜杠,转义字符中的转义序列符 \? 将?转义,防止他被识别成三字母词(很早的东西)中的问号 //三字母词 //??(是[ //??)是] printf("%s","??(??)"); //打印结果是[] 二、fopen函数fc…

Linux 基础指令三

一、cat命令 默认是顺序查看,可同时查看多个文件,只能看普通文件,不能看文件以外 使用格式: cat [选项] 文件名 常用选项 -n显示行号-b跳过空白行编号-s将所有的连续的多个空行替换为一个空行(压缩成一个空行&#xff0…

适配器模式学习

适配器模式(Adapter)将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 适配器模式分为类适配器模式和对象适配器模式两种,前者类之间的耦合度比后者高,且要…

在Linux安装卸载文件

目录 一、Linux系统应用程序 1.典型的应用程序的目录结构 2、常见的软件包封装类型 二、RPM软件包管理 1、RPM是什么? 2、rpm一般命名格式 3、RPM安装包从何而来?如何挂载? 4、挂载的注意事项: 5、目的:提供安装包 6、查…

初学链表(分析建立学生信息链表)

本题要求实现一个将输入的学生成绩组织成单向链表的简单函数。 #include <stdio.h> #include <stdlib.h> #include <string.h> struct stud_node { int num; char name[20]; int score; struct stud_node *next; }; struct stu…

又是阿里,通义灵码免费平替GitHub Copilot

毫无疑问&#xff0c;人工智能已经在影响着我们日常生活的方方面面&#xff0c;同样的在软件开发领域&#xff0c;AI正在改变我们的开发方式。在软件开发领域&#xff0c;尽管有许多强大的AI编码工具&#xff0c;但国产&#xff0c;免费&#xff0c;使用门槛低&#xff0c;用起…

配置IPv4静态路由与静态BFD联动示例

静态路由简介 定义 静态路由是一种需要管理员手工配置的特殊路由。 目的 静态路由在不同网络环境中有不同的目的&#xff1a; 当网络结构比较简单时&#xff0c;只需配置静态路由就可以使网络正常工作。 在复杂网络环境中&#xff0c;配置静态路由可以改进网络的性能&…

备份至关重要!如何解决iCloud的上次备份无法完成的问题

将iPhone和iPad备份到iCloud对于在设备发生故障或丢失时确保数据安全至关重要。但iOS用户有时会收到一条令人不安的消息&#xff0c;“上次备份无法完成。”下面我们来看看可能导致此问题的原因&#xff0c;如何解决此问题&#xff0c;并使你的iCloud备份再次顺利运行。 这些故…

爬虫字典生成工具,CeWL使用教程

爬虫字典生成工具,CeWL使用教程 1.工具概述2.参数解析3.使用实例1.工具概述 CeWL 是一个 ruby 应用程序,它将给定的 URL 爬到指定的深度,可以选择跟随外部链接,并返回一个单词列表,然后可用于密码破解者 Cewl 是黑客武器库中的强大工具,因为它允许创建有针对性的单词列…

sql_lab之sqli中的报错注入,less13

报错注入&#xff08;less-13&#xff09; 正常报错注入&#xff1a; 1.输入用户名和密码123 123显示登录错误 2.输入用户名和密码123’ 123显示登录错误 123后面有’)说明是’)注入 3.查询数据库名 1) and updatexml(<a><b></b></a>,concat(1111…

收支明细记录与图表展示:轻松管理财务,掌控财务状况!

在财务管理中&#xff0c;了解每个项目的支出占比是关键的&#xff0c;这有助于精确掌握项目开销和预算管理。为了帮助你轻松实现这一目标&#xff0c;我们向你介绍一项强大的功能&#xff1a;项目支出明细记录与项目图表相结合。现在&#xff0c;你可以快速一目了然地查看每个…