用自己的手机做网站,wordpress输出用户中心链接,网站建设接外包流程,电影网站膜拜工作之余学习16-QAM
写在前面
网上看到许多示例#xff0c;但一般都比较难以跑通。所以#xff0c;还是老方法#xff0c;先将matlab自带的例子研究下。 Examine 16-QAM Using MATLAB
Examine 16-QAM Using MATLAB
或者#xff0c;在matlab中#xff0c;键入#x…工作之余学习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对我这样的学习的人还是造成了一定的困扰。 初学者在实操时往往同时面对几个到十几个知识要学习难以确定自己哪里是可以确认的。 正确的图像是这样的在eb 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_lengthn/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));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. x cast(1,like,x): This adds 1 to each element of the input vector x. 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. 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 M2const comm.internal.qam.getSquareConstellation(M);z(:) genqamdemod(y,const);else % Square constellation, starting with M4% 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
endcomputeHardInt中这两句是重点 % 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 SignalStep 3 of 3 in Compute BER for QAM System with AWGN Using MATLAB 因为还没有看所以不做评述。但是看来这个例子应该是比较全面的。不仅仅是编解码。