基于MATLAB的QAM调制与星座图(附完整代码与分析)

2024-06-19 18:04

本文主要是介绍基于MATLAB的QAM调制与星座图(附完整代码与分析),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一. 写在前面

二. 调制与散点图

2.1 16-QAM调制

2.2 256-QAM调制

三. 对随机数据进行QAM调制

四. 对不同的编码QAM调制

五.引入噪声的QAM调制

六. QAM解调

七.总结

7.1 调制阶数

7.2 调制前的信号

7.3 编码方式

7.4 qammod函数内的Name-Value


一. 写在前面

(1)本文章主要讨论QAM调制,全称为Quadrature amplitude modulation;

(2)本文章的源代码参考自MATLAB官方文件;

(3)每行代码我都尝试写清楚含义,非常适合初学者

二. 调制与散点图

先看两个简单例子,不考虑通信功率等限制。

2.1 16-QAM调制

MATLAB代码与解释如下:

M=16; %设置调制阶数为16x=(0:M-1)'; 
%调制之前的数据,为向量x=(0,1,2,3,.....,15)
%最后面的'代表列向量的含义y=qammod(x,M); 
%QAM调制函数为qammod,代表对输入信号x进行QAM调制,调制的阶数为M
%y即为调制后的信号scatterplot(y)
%画星座图
%星座图的横轴代表"In-Phase",也就是同相
% 纵轴代表“Quadrature”,也就是正交。跟调制方式相呼应
%简单理解就是数据分为两路,分别进行载波调制

运行结果:

2.2 256-QAM调制

MATLAB代码:

M=256; %设置调制阶数为256x=(0:M-1)'; 
%调制之前的数据,为向量x=(0,1,2,3,.....,255)
%最后面的'代表列向量的含义y=qammod(x,M); 
%QAM调制函数为qammod,代表对输入信号x进行QAM调制,调制的阶数为M
%y即为调制后的信号scatterplot(y)
%画星座图
%星座图的横轴代表"In-Phase",也就是同相
% 纵轴代表Quadrature,也就是正交跟调制方式相呼应
%简单理解就是数据分为两路,分别进行载波调制

运行结果:

三. 对随机数据进行QAM调制

接下来,我们讨论对随机数据信号进行QAM调制。代码中奖考虑实际的通信系统是有功率限制的。

MATLAB代码如下:

%清空页面
clear;clc;close all;M=64;
%设定调制阶数为64x=randi([0 M-1],1000,1);
%randi产生随机数,范围为0~M-1
%1000行1列,一共1000个数据y=qammod(x,M,'UnitAveragePower',true);
%'UnitAveragePower'代表平均功率
%true在MATLAB中为1,此处即为限定输出的信号平均功率为1
%函数的语法环境为y = qammod(___,Name,Value) avgPower=mean(abs(y).^2);
%abs代表绝对值,mean代表平均值
%因为y是向量所以平方运算的前面有个.号
%随机信号的均方值通常为功率,可以验证功率为1,注意会略微有些偏差scatterplot(y)
%画星座图title('64-QAM, 平均功率 = 1 W')
%给图像取名

运行结果:

有关平均功率,在很多论文中经常会看到:

发射功率约束:

E\lbrace |x|^2 \rbrace\leq P

四. 对不同的编码QAM调制

对数据进行编码的方式可以直接转为二进制(binary),也可以使用格雷码(Grey),甚至可以自定义。

格雷码(Gray code)也叫交替二进制码,相邻的星座图点只相差一个比特不同。

MATLAB代码如下:

%清空页面
clear;clc;close all;M=16;
%调制阶数(modulation order)为16d=[0:M-1];
%创建一个数据序列,从0~15,一共16个整数
%将这些整数可以写成二进制
%有16个点,所以后面均为16-QAM调制%%格雷码
y=qammod(d,M,'PlotConstellation',true);
%'PlotConstellation'与true需要连在一起,前者代表星座图,后者代表逻辑运算1,也就是确实要画图
%可以把true改为1也可以
%此处没有给出编码方式,就是默认为格雷码
%注意格雷码是不按顺序的,与直接的二进制转化有区别%%直接二进制编码
z=qammod(d,M,'bin','PlotConstellation',true);
%bin代表直接将数据d转为二进制,是按顺序的
%'PlotConstellation'与true代表画星座图%%自定义的编码
smap=randperm(M)-1;
%randperm代表对数据进行随机排列,M代表从1~M个数据
%需要注意的是调制需要从0开始,所以需要-1
w=qammod(d,M,smap,'PlotConstellation',true);

运行结果与解释:

解释:红色叉叉右上角的数字代表信号,从上往下看,很明显不是按照二进制顺序的,这其实是依据格雷码来进行排列的。

解释:从上往下,一列一列地看,是按照数字大小排列的,这就是直接把数字转为二进制的编码方式。

平均功率(图中UnitAveragePower)为false指的是QAM星座图中任意两点直接的距离为最近两点的距离,也就是对星座图进行了缩放。

解释:随机排列,无任何顺序

五.引入噪声的QAM调制

MATLAB代码:

%清除所有无关变量
clear;clc;close all;M=64;
%调制阶数为64k=log2(M);
%log以2为底的运算
%每个数据对应的比特长度data=randi([0 1],1000*k,1);
%从0或1中随机抽取,1000*k行,1列
%每个数据为k比特长,所以总数应该为k的倍数
%相当于产生了1000个symboltxSig=qammod(data,M,'InputType','bit','UnitAveragePower',true);
%对数据data进行QAM调制,调制阶数为M
%'InputType'与'bit'代表输入数据的格式为比特
%'UnitAveragePower'与true代表平均功率为1rxSig=awgn(txSig,25);
%将调制后的信号txSign输入到带噪的信道中
%加性高斯白噪声(AWGN),信噪比(SNR)为25cd=comm.ConstellationDiagram('ShowReferenceConstellation',false);
%comm.ConstellationDiagram函数调用出调制后的平面
%平面中in-phase代表实轴,quadrature代表虚轴
%'ShowReferenceConstellation'与false代表不显示出参考点
%如果将false改为true,则会出现四个红色的参考点,大家可以试一试cd(rxSig)
%显示出星座图

运行结果

理解:图中有1000个数据点

六. QAM解调

MATLAB代码:

%清除所有无关变量
clear;clc;close all;M=64;
%调制阶数为64bitsPerSym=log2(M);
%bits per symbol,,每个符号的比特长度x=randi([0 1],10*bitsPerSym,1);
%randi产生随机数,从0或1中随机选取
%10*bitsPerSym行1列,很明显是比特串的形式
%行数需要是bitsPerSym的倍数,一共有10个符号点y=qammod(x,M,'bin','InputType','bit','OutputDataType',numerictype(1,16,10));
%x与M代表对输入数据x进行M-QAM调制
%'InputType'与'bit'解释输入的数据为比特串形式
%'OutputDataType'与numerictype(1,16,10)代表对输出数据格式进行限定z=qamdemod(y,M,'bin','OutputType','bit');
%qamdemod代表QAM解调
%bin代表y的编码方式为直接转为二进制
%'OutputType'与'bit'代表解调后的数据为比特串s=isequal(x,double(z))
%x为调制前的数据,z为解调后的数据
%isequal对比两者数据是否相等
%double代表双精度浮点数
%无噪传输可以想到,结果肯定相等

运行结果:

s = logical  1
 

解释:逻辑结果为1代表两者相等。QAM解调成功

七.总结

7.1 调制阶数

QAM调制阶数需要是2的指数形式,可代表信号星座图中的点数(就是那些参考点的数量)。

7.2 调制前的信号

可以是一个标量,也可以是一个向量,还可以是一个矩阵。

可以是比特串,也可以取自整数。如果是整数的话,其取值范围为0~M-1,其中M为调制阶数。

如果输入是二进制的比特串时,在MATLAB中需要给出'InputType','bit'。一个码元对应的比特长度为log2(M),所以输入信号的长度需要是log2(M)的倍数。

7.3 编码方式

编码方式通常有三种:(1)格雷码顺序(2)二进制直接转换(3)自定义顺序

一共有M个星座点,取值为0~M-1。第一个元素的值为最左上角,依次往下。

7.4 qammod函数内的Name-Value

在以上的代码中,我们曾看到:

y=qammod(x,M,'InputType','bit')

表明输入信号为二进制的比特串,行数需要是log2(M)的倍数;

如果将'bit'改为'integer',则表明输入信号的取值为0~M-1内的整数。

还有命令'UnitAveragePower'代表的是Unit average power flag,紧跟在后面的是false(代表0),或者true(代表1)。这个命令主要是对星座图进行缩放。

调制后的数据格式可以使用'OutputDataType'来进行限定,需要搭配函数numerictype,通常的数据格式不外乎single或者double,建议不用调整。

还可以搭配'PlotConstellation'命令来进行画星座图,同样也是紧跟着false(代表0),或者true(代表1)。

这篇关于基于MATLAB的QAM调制与星座图(附完整代码与分析)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1075749

相关文章

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

SpringBoot多数据源配置完整指南

《SpringBoot多数据源配置完整指南》在复杂的企业应用中,经常需要连接多个数据库,SpringBoot提供了灵活的多数据源配置方式,以下是详细的实现方案,需要的朋友可以参考下... 目录一、基础多数据源配置1. 添加依赖2. 配置多个数据源3. 配置数据源Bean二、JPA多数据源配置1. 配置主数据

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

SpringBoot中配置Redis连接池的完整指南

《SpringBoot中配置Redis连接池的完整指南》这篇文章主要为大家详细介绍了SpringBoot中配置Redis连接池的完整指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以... 目录一、添加依赖二、配置 Redis 连接池三、测试 Redis 操作四、完整示例代码(一)pom.

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle