当前位置: 首页 > news >正文

Matlab示例-Examine 16-QAM Using MATLAB学习笔记

​工作之余学习16-QAM

写在前面

网上看到许多示例,但一般都比较难以跑通。所以,还是老方法,先将matlab自带的例子研究下。
Examine 16-QAM Using MATLAB

Examine 16-QAM Using MATLAB

或者,在matlab中,键入:

openExample(‘comm/Examine16QAMUsingMATLABExample’)

会打开:

~\Document\MATLAB\Examples\R2022b\comm\Examine16QAMUsingMATLABExample

不得不感叹,WathWorks公司,依然在飞速的进步,其文档代码一体化能力,已经非常强了。
要注意有梯子之后,这个例子,可以直接在浏览器中运行和单步Trace.
在这里插入图片描述在这里插入图片描述不由得有些哀叹。软件这东西怎么说呢,越落后,就越落后。因为人家是在加速,我们则永远在零和搞一年就放弃归零的循环中。

我们能想象,如果MathWorks是中国公司,当你和老板说,我们也开发个网页版的调试器后,老板第一件事就问你这有用吗?这耽误我们挣钱吗?好吧,这玩意真的没什么用处,但真的是太cool了。
而且,下面就是有用的地方:

【注意】Matlab的示例,网页中的一般是最新的,而我们安装好的matlab所带的例子,往往,存在一些小的缺陷,并没有得到修正。

所以,当发生怀疑是不是哪里出错的时候,可以将被怀疑的代码段,与网页版的代码section 进行下比较。

比如当前的这个例子,的最后一段:

网页版是:

scatterplot(symgray,1,0,'b*');
for k = 1:Mtext(real(symgray(k)) - 0.0,imag(symgray(k)) + 0.3, ...dec2base(x(k),2,4),'Color',[0 1 0]);text(real(symgray(k)) - 0.5,imag(symgray(k)) + 0.3, ...num2str(x(k)),'Color',[0 1 0]);text(real(symbin(k)) - 0.0,imag(symbin(k)) - 0.3, ...dec2base(x(k),2,4),'Color',[1 0 0]);text(real(symbin(k)) - 0.5,imag(symbin(k)) - 0.3, ...num2str(x(k)),'Color',[1 0 0]);
end
title('16-QAM Symbol Mapping')
axis([-4 4 -4 4])

可是matlab中:

scatterplot(symgray,1,0,'b*');
for k = 1:Mtext(real(symgray(k)) - 0.0,imag(symgray(k)) + 0.3, ...dec2base(x(k),2,4));text(real(symgray(k)) - 0.5,imag(symgray(k)) + 0.3, ...num2str(x(k)));text(real(symbin(k)) - 0.0,imag(symbin(k)) - 0.3, ...dec2base(x(k),2,4),'Color',[1 0 0]);text(real(symbin(k)) - 0.5,imag(symbin(k)) - 0.3, ...num2str(x(k)),'Color',[1 0 0]);
end
title('16-QAM Symbol Mapping')
axis([-4 4 -4 4])

​要注意,matlab中的代码,for循环中,少了一小段:
dec2base(x(k),2,4),‘Color’,[0 1 0]);
少了的这段Color,对我这样的学习的人,还是造成了一定的困扰。
初学者,在实操时,往往同时面对几个到十几个知识要学习,难以确定自己哪里是可以确认的。
正确的图像是这样的(在Web Cloud版跑出来的):
在这里插入图片描述
下面不对的是这样的:
在这里插入图片描述
所以,我很久都没有看懂——因为这张图。
看原图,很清楚是想让我们了解自然码与Gray Code的区别。

修改第一部分代码

这个示例的第一段是准备数据。

dataIn = randi([0 1],n,1); % Generate vector of binary data

但这一段,对于我来说,是不太喜欢的。因为作为初学者,要可控。
所以,我打算将数据进行变换,变换成为标准的0,1,2,3,…,15的样子。
所以,这是我第一步要做的。
在与ChatGPT进行了一番不对等的沟通之后,大致改好了,事实上,我花了不少时间。。。

clc;
clear all;
close all;M = 16; % Modulation order (alphabet size or number of points in signal constellation)
k = log2(M); % Number of bits per symbol
n = 256; % Number of bits to process
sps = 1; % Number of samples per symbol (oversampling factor)

上面的代码是将总binary长度,减为256

array_length=n/4% Create an array named input_data and fill it cyclically with numbers from 0 to 15
decimalArray = mod(0:array_length-1, 16);% Convert decimal array to binary array
binaryArray = dec2bin(decimalArray) - '0';
%swap columns
swappedBinaryArray = binaryArray(:, [4 3 2 1]);% Concatenate each line of binaryArray
%onerow_binaryArray = binaryArray_pose(:);
onerow_binaryArray = swappedBinaryArray(:);% Transpose the binary array to a column vector
%transposedBinaryArray = onerow_binaryArray.';dataIn = onerow_binaryArray;

这段花了不少时间,是因为这里面的矩阵的变换自己不是不熟,是完全不知道如何操作。。。
这一次是学明白了。

这段是为了得到可控的输出
在这里插入图片描述

在这里插入图片描述
然后我们直接到调制

Modulate Using 16-QAM
Use the qammod function to apply 16-QAM modulation to the dataSymbolsIn column vector for natural-encoded and Gray-encoded binary bit-to-symbol mappings.

dataMod = qammod(dataSymbolsIn,M,'bin'); % Binary coding with phase offset of zero
dataModG = qammod(dataSymbolsIn,M); % Gray coding with phase offset of zero

然后是开始Trace这个函数
在跟踪之前,不得不先学习格雷码。
关于格雷码(Gray Code),最好的文章是wikipedia的内容:https://en.wikipedia.org/wiki/Gray_code

还有一篇也不错:
QAM格雷码映射的规则(Gray Code Mapping in QAM)
自己biying

这句是得到自然码的调制后编码,
dataMod = qammod(dataSymbolsIn,M,‘bin’); % Binary coding with phase offset of zero

然后,下面这句是得到Gray的编码
dataModG = qammod(dataSymbolsIn,M); % Gray coding with phase offset of zero
汇总后见下图:
在这里插入图片描述
然后,进入matlab的qammod函数:
在这里插入图片描述从这里

    [y, const] = comm.internal.qam.modulate(x, M, symbolOrder, symbolOrderVector, ...bitInput, unitAveragePower, outputDataType);
function y = processIntInput(x, M, symbolOrder, symbolOrderVector, const)msg = processSymbols(x, M, symbolOrder, symbolOrderVector);y = lookupTable(const, msg);
end
function [y, const] = modulate(x, M, symbolOrderStr, ...symbolOrderVector, bitInput, unitAveragePower, outputDataType)y = processIntInput(x, Mnew, symbolOrderStr, symbolOrderVector, newConst);
end

重点是这句:
y = lookupTable(const, msg);


function y = lookupTable(table, x)y = coder.nullcopy(zeros(size(x),'like',table));y(:) = table(x + cast(1,'like',x));
end

重点是这句:

 y(:) = table(x + cast(1,'like',x));

  1. cast(1,'like',x): This part casts the value 1 to the same data type as the input variable x. This is necessary to ensure that the indexing operation doesn’t cause any type mismatches.

  2. x + cast(1,'like',x): This adds 1 to each element of the input vector x.

  3. table(x + cast(1,'like',x)): This indexes the table array using the modified values of x + cast(1,'like',x). It effectively looks up values in the table corresponding to the modified indices.

  4. y(:) = table(x + cast(1,'like',x));: This assigns the values obtained from the lookup to the entire vector y. The (:) syntax is used to linearize y into a column vector.

Let’s walk through an example:

  • Original x values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
  • Modified indices: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
  • Values from the table corresponding to the modified indices: [-3 + 1i, -3 - 1i, -3 - 3i, -1 + 3i, -1 + 1i, -1 - 1i, -1 - 3i, 1 + 3i, 1 + 1i, 1 - 1i, 1 - 3i, 3 + 3i, 3 + 1i, 3 - 1i, 3 - 3i]

So, the resulting y would be the values obtained from the table using the modified indices. The purpose seems to be to perform a table lookup operation using the input vector x to generate the output vector y.


解调的部分

注意,条件检查的部分,我省略了,实际我也是详细看了的,写得很精妙!
Demodulate 16-QAM
Use the qamdemod function to demodulate the received data and output integer-valued data symbols.

dataSymbolsOut = qamdemod(receivedSignal,M,'bin');
dataSymbolsOutG = qamdemod(receivedSignalG,M);function x = qamdemod(y, M, varargin)   x = comm.internal.qam.demodulate(y, M, symbolOrderStr, symbolOrderVector, unitAveragePower, ...outputType, noiseVar);
end
function x = demodulate(y, M, symbolOrderStr, symbolOrderVector, ...unitAveragePower, outputType, noiseVar)intX = computeHardInt(y, Mnew);        

这里是关键函数


function z = computeHardInt(y, M)if isa(y,'single')z = coder.nullcopy(zeros(size(y), 'single'));elsez = coder.nullcopy(zeros(size(y), 'double'));endif mod(log2(M), 2) % Cross constellation, including M=2const = comm.internal.qam.getSquareConstellation(M);z(:) = genqamdemod(y,const);else % Square constellation, starting with M=4% Precompute for later usesqrtM = sqrt(M);% Inphase/real rail% Move the real part of input signal; scale appropriately and round the% values to get index ideal constellation pointsrIdx = round( ((real(y) + (sqrtM-1)) ./ 2) );% clip values that are outside the valid rangerIdx(rIdx < 0) = 0;rIdx(rIdx > (sqrtM-1)) = sqrtM-1;% Quadrature/imaginary rail% Move the imaginary part of input signal; scale appropriately and round% the values to get index of ideal constellation pointsiIdx = round(((imag(y) + (sqrtM-1)) ./ 2));% clip values that are outside the valid rangeiIdx(iIdx < 0) = 0;iIdx(iIdx > (sqrtM-1)) = sqrtM-1;% compute output from indices of ideal constellation pointsz(:) = sqrtM-iIdx-1 +  sqrtM*rIdx;end
end

computeHardInt中,这两句是重点

        % Inphase/real rail% Move the real part of input signal; scale appropriately and round the% values to get index ideal constellation pointsrIdx = round( ((real(y) + (sqrtM-1)) ./ 2) );% Quadrature/imaginary rail% Move the imaginary part of input signal; scale appropriately and round% the values to get index of ideal constellation pointsiIdx = round(((imag(y) + (sqrtM-1)) ./ 2));

格雷码,并没有多大不同,调制是后处理,解调是前处理,将数据重新映射。
以上是所有的内容。
可惜这个例子只有基带的处理,没有信号的调制与解调。
是为遗憾。
希望再找个更全面的例子。

后记

写完才想起来这个例子,很前显有一个向导栏:
在这里插入图片描述
分别为:Use Pulse Shaping on 16-QAM Signal
和 Use Forward Error Correction on 16-QAM Signal(Step 3 of 3 in Compute BER for QAM System with AWGN Using MATLAB )
因为还没有看,所以不做评述。但是看来这个例子,应该是比较全面的。不仅仅是编解码。

相关文章:

Matlab示例-Examine 16-QAM Using MATLAB学习笔记

​工作之余学习16-QAM 写在前面 网上看到许多示例&#xff0c;但一般都比较难以跑通。所以&#xff0c;还是老方法&#xff0c;先将matlab自带的例子研究下。 Examine 16-QAM Using MATLAB Examine 16-QAM Using MATLAB 或者&#xff0c;在matlab中&#xff0c;键入&#x…...

ArcGIS Pro SDK运行消息只提示一次

工具大部分都是异步执行&#xff0c;所以提示信息需要异步执行完再进行,所以注意async和await的使用。 相关async和await的文章请查看C# 彻底搞懂async/await_c# async await-CSDN博客 public async Task InformationPrompt() {string message String.Empty;await ArcGIS.De…...

通话状态监听-Android13

通话状态监听-Android13 1、Android Telephony 模块结构2、监听和广播获取通话状态2.1 注册2.2 通话状态通知2.3 通话状态 3、通知状态流程* 关键日志 frameworks/base/core/java/android/telephony/PhoneStateListener.java 1、Android Telephony 模块结构 Android Telephony…...

无懈可击的防泄密之旅:迅软DSE在民营银行的成功实践

客户简要介绍 某股份有限公司主体是中部地区的民营银行&#xff0c;由其母公司联合9家知名民营企业共同发起设立。正式开业于2016年&#xff0c;紧紧围绕目标产业生态圈和消费金融&#xff0c;着力打造产业银行、便捷银行、数字银行、财富管理银行为一体的BEST银行&#xff0c…...

【送书活动】智能汽车、自动驾驶、车联网的发展趋势和关键技术

文章目录 前言01 《智能汽车》推荐语 02 《SoC底层软件低功耗系统设计与实现》推荐语 03 《SoC设计指南》推荐语 05 《智能汽车网络安全权威指南&#xff08;上册&#xff09;》推荐语 06 《智能汽车网络安全权威指南&#xff08;下册&#xff09;》推荐语 后记赠书活动 前言 …...

不同版本QT使用qmake时创建QML项目的区别

不同版本QT使用qmake时创建QML项目的区别 文章目录 不同版本QT使用qmake时创建QML项目的区别一、QT5新建QML项目1.1 目录结构1.2 .pro 文件内容1.3 main.cpp1.4 main.qml 二、QT6新建QML项目2.1 目录结构2.2 .pro文件内容2.3 main.cpp2.4 main.qml 三、两个版本使用资源文件的区…...

【PHP入门】1.1-PHP初步语法

-PHP语法初步- PHP是一种运行在服务器端的脚本语言&#xff0c;可以嵌入到HTML中。 1.1.1PHP代码标记 在PHP历史发展中&#xff0c;可以使用多种标记来区分PHP脚本 ASP标记&#xff1a; <% php代码 %>短标记&#xff1a; <? Php代码 ?>&#xff0c;以上两种…...

如何在jenkins容器中安装python+httprunner+pytest+git+allure(一)

背景&#xff1a; API接口自动化使用python语言实现&#xff0c;利用httprunner框架编写自动化用例场景&#xff08;执行的时候还是依赖pytest),使用jenkins自动构建git上的源代码&#xff0c;并产生allure报告可视化展示API执行结果。 步骤 1.进入jenkins容器 注意使用roo…...

Android终端模拟器Termux上使用Ubuntu

Termux 上安装各种 Linux 系统是通过 proot-distro 工具来实现的&#xff0c;所以先安装一下 proot-distro 工具。 ~ $ pkg install proot-distro 查看Termux支持安装那些Linux ~ $ proot-distro listSupported distributions:* Alpine LinuxAlias: alpineInstalled: noComme…...

【神器】wakatime代码时间追踪工具

文章目录 wakatime简介支持的IDE安装步骤API文档插件费用写在最后 wakatime简介 wakatime就是一个IDE插件&#xff0c;一个代码时间追踪工具。可自动获取码编码时长和度量指标&#xff0c;以产生很多的coding图形报表。这些指标图形可以为开发者统计coding信息&#xff0c;比如…...

UML统一建模语言

一、建模语言的背景&#xff1a; 通俗地阐述就是&#xff1a;客户一开始不知道要什么&#xff0c;开发通过客户的阐述进行理解和分析&#xff0c;这个过程中间可能会产生一些误解。为了避免此类事件&#xff0c;所以需要建模。类似于要建造一栋楼&#xff0c;建筑设计师根据住…...

Linux命令行控制小米电源开关

飞灵科技产品 flyelf-tech.com&#xff0c;flyelf.taobao.com 最近有需求通过命令控制局域网内小米电源开关&#xff0c;以便于写脚本对产品进行反复上电的启动测试。参考了这篇文章&#xff1a;https://blog.csdn.net/2301_77209380/article/details/129797846 获取小米设备的…...

docker nginx 部署静态网站

1、dockerfile FROM nginx AS baseWORKDIR /appEXPOSE 80COPY . /app2、dockercompose.yaml version: 3 services:adminservice:container_name: adminwebbuild:context: ./dockerfile: Dockerfileports:- "5000:80"labels:description: adminwebrestart: always3、…...

uniapp之屏幕右侧出现滚动条去掉、隐藏、删除【好用!】

目录 问题解决大佬地址最后 问题 解决 在最外层view上加上class“content”;输入以下样式。注意&#xff1a;两个都必须存在在生效。 .content {/* 跟屏幕高度一样高,不管view中有没有内容,都撑开屏幕高的高度 */height: 100vh; overflow: auto; } .content::-webkit-scrollb…...

Linux 系统开机启动流程

可能没有完全理解&#xff0c;后期整理完Linux的内容&#xff0c;应该理解会深入一些&#xff0c;试着用更简洁的方式和图形来记录&#xff0c;以及一些概念的完善 2023-12-14 一、开机流程 BIOS MBR/GPT 加载 BIOS 的硬件信息与进行自检&#xff0c;并依据设定取得第一个可…...

vue2源码解析---watch和computed

监听属性watch 监听属性介绍 我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数wach 可以用于异步任务 监听属性的初始化 watch和computed都先走initSate判断传入选项 export function initState(vm) {const opts vm.$options; // 获取所有的选项if (opts.…...

【云原生】华为云踩坑日志(更新于2023.12.10)

1、华为云建议我们把sfs容量型升级到turbo版本&#xff0c;但是CCE产品storageclass sfs-turbo共享存储卷不支持动态绑定&#xff0c;官网文档可以实现动态创建子目录&#xff0c;建议大家直接选择这个&#xff0c;不要踩坑了 2、CCE 涉及到的产品&#xff0c;有的需要查看产品…...

计算机网络:自顶向下第八版学习指南笔记和课后实验--网络层(控制平面)

网络层&#xff1a;控制平面 记录一些学习计算机网络:自顶向下的学习笔记和心得 Github地址&#xff0c;欢迎star ⭐️⭐️⭐️⭐️⭐️ 控制平面作为一种网络范围的逻辑&#xff0c;不仅控制沿着从源主机到目的主机的端到端路径间的路由器如何转发数据报&#xff0c;而且控制…...

MFC 窗口创建过程与消息处理

目录 钩子简介 代码编写 窗口创建过程分析 消息处理 钩子简介 介绍几个钩子函数&#xff0c;因为它们与窗口创建工程有关 安装钩子函数 HHOOK SetWindowsHookExA([in] int idHook,[in] HOOKPROC lpfn,[in] HINSTANCE hmod,[in] DWORD dwThreadId ); 参数说明…...

基于JavaWeb+SSM+Vue微信小程序的移动学习平台系统的设计和实现

基于JavaWebSSMVue微信小程序的移动学习平台系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 第1章 绪论 1 1.1 课题背景 1 1.2 课题意义 1 1.3 研究内容 2 第2章 开发环…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

ui框架-文件列表展示

ui框架-文件列表展示 介绍 UI框架的文件列表展示组件&#xff0c;可以展示文件夹&#xff0c;支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项&#xff0c;适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...