答案 0 :(得分:6)
Here是一个Matlab脚本示例,它使用Gray映射进行Star-16-QAM映射,为AWGN通道建模并进行决策和解映射。还计算误码率(BER)。我将很快解释它是如何工作的。
首先,我们创建一个随机位序列,其中“0”和“1”以相同的概率发生。星座图的内圆和外圆的半径也被定义。
% Random bit sequence
numberOfBits = 1e5;
x = rand(1, numberOfBits);
x( x < 0.5 ) = 0;
x( x >= 0.5 ) = 1;
% Radius of inner and outer circle
r1 = 1;
r2 = 2;
在下一步中,我们定义将整数索引号映射到复杂符号的映射表。这是以这样的方式完成的,即两个相邻符号仅在一个比特中不同。这称为灰度映射。
% Define mapping table applying Gray mapping
mappingTable(1) = r1 * exp(1i* 0);
mappingTable(2) = r1 * exp(1i* pi/4);
mappingTable(3) = r1 * exp(1i* 3*pi/4);
mappingTable(4) = r1 * exp(1i* pi/2);
mappingTable(5) = r1 * exp(1i* 7*pi/4);
mappingTable(6) = r1 * exp(1i* 3*pi/2);
mappingTable(7) = r1 * exp(1i* pi);
mappingTable(8) = r1 * exp(1i* 5*pi/4);
mappingTable(9:16) = mappingTable(1:8) ./ r1 .* r2;
现在,对于每个4位的块,我们计算符号索引并在映射表中查找相应的复杂符号。
if mod(numberOfBits, 4) ~= 0
error('numberOfBits must be a multiple of 4.');
end
mappedSymbols = zeros(1, numberOfBits / 4);
% Map bits to symbols
for i = 1:4:length(x)
symbolBits = x(i:i+3);
symbolIndex = 2^3 * symbolBits(1) + 2^2 * symbolBits(2) + 2^1 * symbolBits(3) + 2^0 * symbolBits(4);
% Mapping
mappedSymbols((i - 1)/4 + 1) = mappingTable( symbolIndex + 1);
end
在实际通信系统中,复数符号的实部和虚部现在将被转换为模拟信号(具有脉冲整形器)并被调制到射频载波上。在这里,我们假设D / A和A / D转换以及调制和解调是理想的,因此我们不需要对其进行建模。此外,假设信道是理想的,即在频域中是平坦的。但是,我们将通过添加白高斯噪声来考虑噪声。请注意,噪声功率均匀分布在信号的实部和虚部上。
% Add white Gaussian noise
snr = 20; % signal-to-noise ratio in dB
meanSignalPower = (r1^2 + r2^2)/2;
snr_lin = 10^(snr/10); % linear scale
meanNoisePower = meanSignalPower ./ snr_lin;
receivedSignal = mappedSymbols + randn(1, length(mappedSymbols)) * sqrt(meanNoisePower/2) +...
1i * randn(1, length(mappedSymbols)) * sqrt(meanNoisePower/2);
最后,对于每个接收到的符号,我们确定具有最小距离的星座点,并将符号索引转换回比特序列。
% Decision and demapping
receivedBits = zeros(1, numberOfBits / 4);
for i = 1:length(receivedSignal)
[mindiff minIndex] = min(receivedSignal(i) - mappingTable);
symbolIndex = minIndex - 1;
bitString = dec2bin(symbolIndex, 4);
receivedBits((i-1)*4 + 1) = str2double(bitString(1));
receivedBits((i-1)*4 + 2) = str2double(bitString(2));
receivedBits((i-1)*4 + 3) = str2double(bitString(3));
receivedBits((i-1)*4 + 4) = str2double(bitString(4));
end
当然,我们对比特错误的数量感兴趣:
numberOfBitErrors = nnz( x - receivedBits );
ber = numberOfBitErrors / numberOfBits; % bit error rate
disp(['SNR: ' num2str(snr) ' dB']);
disp(['Bit error rate (BER): ' num2str(ber)]);
绘制发射和接收信号产生典型的星座图:
figure;
plot( real(receivedSignal), imag(receivedSignal), '.'); hold on;
absLim = max( max(real(receivedSignal)), max(imag(receivedSignal)));
xyLimits = [-absLim*1.1 absLim*1.1];
xlim( xyLimits );
ylim( xyLimits );
plot( real(mappedSymbols), imag(mappedSymbols), '.r'); hold off;
xlim( xyLimits );
ylim( xyLimits );
xlabel('real part');
ylabel('imaginary part');
legend('received', 'transmitted');
我上传了完整的源代码:http://pastebin.com/MDcVLZhh
答案 1 :(得分:0)
最简单的方法是使用映射表。首先,生成具有所需星座点的矢量。即,
r1 = 1; % first radius
r2 = 2; % second radius
c = [ r1*exp(j*2*pi/8*[0..7]) r2*exp(j*2*pi/8*[0..7]) ];
c中星座点的顺序决定了从比特到符号的映射。 接下来,调制在1 ..长度(c)之间选择一个 i 的数字,并将c(i)作为星座点。
要从接收的数据解调回符号索引,只需选择最近的星座点。即,如果收到的嘈杂符号是'y':
[dummy, estimated_sym] = min(y - c);
警告:代码未经测试,可能需要进行少量调整。