我需要star 16 QAM调制器和解调器设计matlab代码
请建议我如何制作代码。下面给出的示例星座图。我想用不同的环半径为这个星座制作代码。
这是一个示例 Matlab 脚本,它使用灰度映射进行 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
最简单的是使用映射表。首先,生成具有所需星座点的向量。IE,
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 .. length(c) 之间的数字i,并将 c(i) 作为星座点。
要将接收到的数据解调回符号索引,只需选择最近的星座点。即,如果接收到的噪声符号是'y':
[dummy, estimated_sym] = min(y - c);
警告:代码未经测试,可能需要稍作调整。