2发1收STBC-MIMO系统的MATLAB实现

2发1收STBC(空时分组码)-MIMO系统,包括编码、传输、接收和解码过程。

系统模型

2发1收STBC-MIMO系统使用Alamouti编码方案,这是最著名的空时分组码之一。系统模型如下:

  • 发射端:2个天线
  • 接收端:1个天线
  • 编码方案:Alamouti编码
  • 调制方式:可配置(如BPSK, QPSK, 16QAM等)

代码

% 2发1收STBC-MIMO系统仿真
clear all;
close all;
clc;

%% 参数设置
numTx = 2;          % 发射天线数
numRx = 1;          % 接收天线数
modulation = 'QPSK'; % 调制方式: 'BPSK', 'QPSK', '16QAM', '64QAM'
numBits = 10000;    % 传输比特数
SNR_dB = 0:2:20;    % 信噪比范围(dB)
numFrames = 100;    % 每个SNR下的帧数

% 根据调制方式设置参数
switch modulation
    case 'BPSK'
        modOrder = 1;
        demodOrder = 1;
        symbolMap = [0, 1];
    case 'QPSK'
        modOrder = 2;
        demodOrder = 2;
        symbolMap = [0, 1, 2, 3];
    case '16QAM'
        modOrder = 4;
        demodOrder = 4;
        symbolMap = 0:15;
    case '64QAM'
        modOrder = 6;
        demodOrder = 6;
        symbolMap = 0:63;
    otherwise
        error('不支持的调制方式');
end

% 确保比特数是调制阶数的整数倍
numBits = ceil(numBits / modOrder) * modOrder;

%% 主仿真循环
ber = zeros(size(SNR_dB));
for snrIdx = 1:length(SNR_dB)
    fprintf('处理 SNR = %d dB\n', SNR_dB(snrIdx));
    
    totalErrors = 0;
    totalBits = 0;
    
    for frame = 1:numFrames
        %% 数据生成
        dataBits = randi([0 1], numBits, 1);
        
        %% 调制
        modulatedSymbols = modulator(dataBits, modulation);
        
        %% Alamouti编码
        encodedSymbols = alamouti_encoder(modulatedSymbols);
        
        %% 信道传输
        % 生成瑞利衰落信道
        H = (randn(numRx, numTx, size(encodedSymbols, 2)) + ...
             1i * randn(numRx, numTx, size(encodedSymbols, 2))) / sqrt(2);
        
        % 添加高斯白噪声
        receivedSymbols = mimo_channel(encodedSymbols, H, SNR_dB(snrIdx));
        
        %% Alamouti解码
        decodedSymbols = alamouti_decoder(receivedSymbols, H);
        
        %% 解调
        demodulatedBits = demodulator(decodedSymbols, modulation);
        
        %% 误码率计算
        [numErrors, ~] = biterr(dataBits, demodulatedBits);
        totalErrors = totalErrors + numErrors;
        totalBits = totalBits + length(dataBits);
    end
    
    ber(snrIdx) = totalErrors / totalBits;
end

%% 结果可视化
figure;
semilogy(SNR_dB, ber, 'b-o', 'LineWidth', 2);
grid on;
xlabel('SNR (dB)');
ylabel('误码率 (BER)');
title(['2发1收STBC-MIMO系统性能 (', modulation, ')']);
legend('STBC-MIMO');

% 理论性能曲线(瑞利衰落信道)
hold on;
if strcmp(modulation, 'BPSK')
    theoryBER = 0.5 * (1 - sqrt(SNR_dB./(SNR_dB + 2)));
    semilogy(SNR_dB, theoryBER, 'r--', 'LineWidth', 2);
    legend('STBC-MIMO', '理论BPSK');
end

%% 调制器函数
function modulatedSymbols = modulator(bits, modulation)
    % 将比特流调制为符号
    switch modulation
        case 'BPSK'
            % BPSK调制: 0 -> 1, 1 -> -1
            modulatedSymbols = 1 - 2 * bits;
        case 'QPSK'
            % 重组比特为符号
            symbols = reshape(bits, 2, [])';
            % 转换为十进制
            symbols = bi2de(symbols, 'left-msb');
            % QPSK调制
            modulatedSymbols = exp(1i * (2*pi/4 * symbols + pi/4));
        case '16QAM'
            % 重组比特为符号
            symbols = reshape(bits, 4, [])';
            % 转换为十进制
            symbols = bi2de(symbols, 'left-msb');
            % 16QAM调制 (归一化因子使平均功率为1)
            modulatedSymbols = qammod(symbols, 16, 'UnitAveragePower', true);
        case '64QAM'
            % 重组比特为符号
            symbols = reshape(bits, 6, [])';
            % 转换为十进制
            symbols = bi2de(symbols, 'left-msb');
            % 64QAM调制
            modulatedSymbols = qammod(symbols, 64, 'UnitAveragePower', true);
    end
end

%% 解调器函数
function demodulatedBits = demodulator(symbols, modulation)
    % 将符号解调为比特流
    switch modulation
        case 'BPSK'
            % BPSK解调
            demodulatedBits = real(symbols) < 0;
        case 'QPSK'
            % QPSK解调
            demodulatedSymbols = angle(symbols);
            demodulatedSymbols = mod(round((demodulatedSymbols - pi/4) / (pi/2)), 4);
            demodulatedBits = de2bi(demodulatedSymbols, 2, 'left-msb')';
            demodulatedBits = demodulatedBits(:);
        case '16QAM'
            % 16QAM解调
            demodulatedSymbols = qamdemod(symbols, 16, 'UnitAveragePower', true);
            demodulatedBits = de2bi(demodulatedSymbols, 4, 'left-msb')';
            demodulatedBits = demodulatedBits(:);
        case '64QAM'
            % 64QAM解调
            demodulatedSymbols = qamdemod(symbols, 64, 'UnitAveragePower', true);
            demodulatedBits = de2bi(demodulatedSymbols, 6, 'left-msb')';
            demodulatedBits = demodulatedBits(:);
    end
end

%% Alamouti编码器函数
function encodedSymbols = alamouti_encoder(symbols)
    % Alamouti空时编码器
    % 输入: 符号向量
    % 输出: 2×N矩阵,每列对应一个时隙的两个发射天线
    
    numSymbols = length(symbols);
    encodedSymbols = zeros(2, numSymbols);
    
    for i = 1:2:numSymbols-1
        % Alamouti编码矩阵:
        % 时隙1: [s1, s2]
        % 时隙2: [-s2*, s1*]
        s1 = symbols(i);
        s2 = symbols(i+1);
        
        encodedSymbols(1, i) = s1;
        encodedSymbols(2, i) = s2;
        
        encodedSymbols(1, i+1) = -conj(s2);
        encodedSymbols(2, i+1) = conj(s1);
    end
end

%% MIMO信道函数
function receivedSymbols = mimo_channel(transmittedSymbols, H, SNR_dB)
    % MIMO信道传输
    % 输入: 
    %   transmittedSymbols: 2×N传输符号矩阵
    %   H: 3D信道矩阵 (numRx × numTx × N)
    %   SNR_dB: 信噪比(dB)
    % 输出: 接收符号向量
    
    [numTx, numSymbols] = size(transmittedSymbols);
    numRx = size(H, 1);
    
    % 初始化接收信号
    receivedSymbols = zeros(numRx, numSymbols);
    
    % 计算噪声功率
    SNR = 10^(SNR_dB/10);
    noisePower = 1 / SNR;
    
    for t = 1:numSymbols
        % 通过信道传输
        channel_output = H(:, :, t) * transmittedSymbols(:, t);
        
        % 添加复高斯噪声
        noise = sqrt(noisePower/2) * (randn(numRx, 1) + 1i * randn(numRx, 1));
        
        receivedSymbols(:, t) = channel_output + noise;
    end
end

%% Alamouti解码器函数
function decodedSymbols = alamouti_decoder(receivedSymbols, H)
    % Alamouti空时解码器
    % 输入:
    %   receivedSymbols: 接收符号矩阵 (numRx × numSymbols)
    %   H: 3D信道矩阵 (numRx × numTx × numSymbols)
    % 输出: 解码后的符号向量
    
    numSymbols = size(receivedSymbols, 2);
    decodedSymbols = zeros(1, numSymbols);
    
    for i = 1:2:numSymbols-1
        % 提取两个连续时隙的接收信号
        y1 = receivedSymbols(:, i);
        y2 = receivedSymbols(:, i+1);
        
        % 提取两个时隙的信道矩阵
        H1 = H(:, :, i);
        H2 = H(:, :, i+1);
        
        % Alamouti组合器
        % 对于2x1系统,组合公式为:
        % s̃₁ = h₁*y₁ + h₂y₂*
        % s̃₂ = h₂*y₁ - h₁y₂*
        
        h1 = H1(1, 1);  % 天线1到接收天线的信道
        h2 = H1(1, 2);  % 天线2到接收天线的信道
        
        % 计算组合信号
        s1_tilde = conj(h1) * y1 + h2 * conj(y2);
        s2_tilde = conj(h2) * y1 - h1 * conj(y2);
        
        % 计算信道增益因子
        channel_gain = abs(h1)^2 + abs(h2)^2;
        
        % 归一化组合信号
        decodedSymbols(i) = s1_tilde / channel_gain;
        decodedSymbols(i+1) = s2_tilde / channel_gain;
    end
end

扩展功能:信道估计和均衡

在实际系统中,通常需要估计信道状态信息。以下是添加了信道估计功能的扩展版本:

%% 带有信道估计的2发1收STBC-MIMO系统
function ber = stbc_mimo_with_channel_estimation()
    % 参数设置
    numTx = 2;
    numRx = 1;
    modulation = 'QPSK';
    numBits = 10000;
    SNR_dB = 0:2:20;
    numFrames = 100;
    
    % 导频符号(用于信道估计)
    pilotSymbols = [1; -1]; % 简单的BPSK导频
    
    % 根据调制方式设置参数
    switch modulation
        case 'BPSK'
            modOrder = 1;
        case 'QPSK'
            modOrder = 2;
        case '16QAM'
            modOrder = 4;
        case '64QAM'
            modOrder = 6;
    end
    
    % 确保比特数是调制阶数的整数倍
    numBits = ceil(numBits / modOrder) * modOrder;
    
    % 主仿真循环
    ber = zeros(size(SNR_dB));
    for snrIdx = 1:length(SNR_dB)
        fprintf('处理 SNR = %d dB\n', SNR_dB(snrIdx));
        
        totalErrors = 0;
        totalBits = 0;
        
        for frame = 1:numFrames
            %% 数据生成和调制
            dataBits = randi([0 1], numBits, 1);
            modulatedSymbols = modulator(dataBits, modulation);
            
            %% 插入导频
            % 每10个数据符号插入一组导频
            pilotInterval = 10;
            numPilots = ceil(length(modulatedSymbols) / pilotInterval);
            txSymbolsWithPilots = [];
            pilotIndices = [];
            
            for i = 1:pilotInterval:length(modulatedSymbols)
                % 插入导频
                txSymbolsWithPilots = [txSymbolsWithPilots; pilotSymbols];
                pilotIndices = [pilotIndices, length(txSymbolsWithPilots)-1, length(txSymbolsWithPilots)];
                
                % 插入数据
                endIdx = min(i+pilotInterval-1, length(modulatedSymbols));
                txSymbolsWithPilots = [txSymbolsWithPilots; modulatedSymbols(i:endIdx)];
            end
            
            %% Alamouti编码
            encodedSymbols = alamouti_encoder(txSymbolsWithPilots);
            
            %% 信道传输
            % 生成时变瑞利衰落信道
            H = (randn(numRx, numTx, size(encodedSymbols, 2)) + ...
                 1i * randn(numRx, numTx, size(encodedSymbols, 2))) / sqrt(2);
            
            % 添加高斯白噪声
            receivedSymbols = mimo_channel(encodedSymbols, H, SNR_dB(snrIdx));
            
            %% 信道估计
            % 使用导频符号估计信道
            H_est = zeros(size(H));
            
            for i = 1:2:length(pilotIndices)-1
                pilotIdx = pilotIndices(i);
                
                % 提取接收到的导频信号
                y_pilot1 = receivedSymbols(:, pilotIdx);
                y_pilot2 = receivedSymbols(:, pilotIdx+1);
                
                % Alamouti解码导频信号
                h1_est = (conj(pilotSymbols(1)) * y_pilot1 + pilotSymbols(2) * conj(y_pilot2)) / ...
                         (abs(pilotSymbols(1))^2 + abs(pilotSymbols(2))^2);
                h2_est = (conj(pilotSymbols(2)) * y_pilot1 - pilotSymbols(1) * conj(y_pilot2)) / ...
                         (abs(pilotSymbols(1))^2 + abs(pilotSymbols(2))^2);
                
                % 存储信道估计值
                H_est(1, 1, pilotIdx:pilotIdx+1) = h1_est;
                H_est(1, 2, pilotIdx:pilotIdx+1) = h2_est;
            end
            
            % 对数据符号位置的信道进行插值
            for tx = 1:numTx
                for rx = 1:numRx
                    % 提取导频位置的信道估计
                    pilotH = squeeze(H_est(rx, tx, pilotIndices));
                    
                    % 线性插值
                    interpH = interp1(pilotIndices, pilotH, 1:size(H_est, 3), 'linear', 'extrap');
                    
                    % 存储插值结果
                    H_est(rx, tx, :) = interpH;
                end
            end
            
            %% Alamouti解码(使用估计的信道)
            decodedSymbolsWithPilots = alamouti_decoder(receivedSymbols, H_est);
            
            %% 移除导频符号
            decodedSymbols = decodedSymbolsWithPilots;
            decodedSymbols(pilotIndices) = []; % 移除导频位置
            
            %% 解调
            demodulatedBits = demodulator(decodedSymbols, modulation);
            
            %% 误码率计算
            [numErrors, ~] = biterr(dataBits, demodulatedBits);
            totalErrors = totalErrors + numErrors;
            totalBits = totalBits + length(dataBits);
        end
        
        ber(snrIdx) = totalErrors / totalBits;
    end
    
    % 结果可视化
    figure;
    semilogy(SNR_dB, ber, 'b-o', 'LineWidth', 2);
    grid on;
    xlabel('SNR (dB)');
    ylabel('误码率 (BER)');
    title(['带信道估计的2发1收STBC-MIMO系统性能 (', modulation, ')']);
end

性能分析与比较

%% 性能比较:STBC-MIMO vs. SISO
function compare_stbc_siso()
    % 参数设置
    modulation = 'QPSK';
    numBits = 10000;
    SNR_dB = 0:2:20;
    numFrames = 100;
    
    % STBC-MIMO性能
    ber_stbc = zeros(size(SNR_dB));
    
    % SISO性能
    ber_siso = zeros(size(SNR_dB));
    
    for snrIdx = 1:length(SNR_dB)
        fprintf('处理 SNR = %d dB\n', SNR_dB(snrIdx));
        
        errors_stbc = 0;
        errors_siso = 0;
        totalBits = 0;
        
        for frame = 1:numFrames
            %% 数据生成
            dataBits = randi([0 1], numBits, 1);
            
            %% 调制
            modulatedSymbols = modulator(dataBits, modulation);
            
            %% STBC-MIMO传输
            % Alamouti编码
            encodedSymbols = alamouti_encoder(modulatedSymbols);
            
            % 生成瑞利衰落信道
            H = (randn(1, 2, size(encodedSymbols, 2)) + ...
                 1i * randn(1, 2, size(encodedSymbols, 2))) / sqrt(2);
            
            % 添加高斯白噪声
            receivedSymbols = mimo_channel(encodedSymbols, H, SNR_dB(snrIdx));
            
            % Alamouti解码
            decodedSymbols = alamouti_decoder(receivedSymbols, H);
            
            % 解调
            demodulatedBits = demodulator(decodedSymbols, modulation);
            
            % 误码计数
            [numErrors, ~] = biterr(dataBits, demodulatedBits);
            errors_stbc = errors_stbc + numErrors;
            
            %% SISO传输
            % 生成瑞利衰落信道
            h = (randn(1, 1, length(modulatedSymbols)) + ...
                 1i * randn(1, 1, length(modulatedSymbols))) / sqrt(2);
            
            % 通过信道传输
            receivedSISO = zeros(1, length(modulatedSymbols));
            for i = 1:length(modulatedSymbols)
                receivedSISO(i) = h(1, 1, i) * modulatedSymbols(i);
            end
            
            % 添加高斯白噪声
            SNR = 10^(SNR_dB(snrIdx)/10);
            noisePower = 1 / SNR;
            noise = sqrt(noisePower/2) * (randn(1, length(modulatedSymbols)) + ...
                    1i * randn(1, length(modulatedSymbols)));
            receivedSISO = receivedSISO + noise;
            
            % 最大比合并(对于SISO,就是信道均衡)
            equalizedSISO = receivedSISO ./ squeeze(h);
            
            % 解调
            demodulatedBitsSISO = demodulator(equalizedSISO, modulation);
            
            % 误码计数
            [numErrors, ~] = biterr(dataBits, demodulatedBitsSISO);
            errors_siso = errors_siso + numErrors;
            
            totalBits = totalBits + length(dataBits);
        end
        
        ber_stbc(snrIdx) = errors_stbc / totalBits;
        ber_siso(snrIdx) = errors_siso / totalBits;
    end
    
    % 结果可视化
    figure;
    semilogy(SNR_dB, ber_stbc, 'b-o', 'LineWidth', 2, 'DisplayName', 'STBC-MIMO (2x1)');
    hold on;
    semilogy(SNR_dB, ber_siso, 'r-s', 'LineWidth', 2, 'DisplayName', 'SISO');
    grid on;
    xlabel('SNR (dB)');
    ylabel('误码率 (BER)');
    title(['STBC-MIMO与SISO系统性能比较 (', modulation, ')']);
    legend('show');
end

参考代码 对2发1收的STBC-MIMO系统 www.youwenfan.com/contentcnd/99421.html

使用

  1. 运行主程序可以仿真2发1收STBC-MIMO系统的性能
  2. 可以修改调制方式、信噪比范围和帧数等参数
  3. 扩展功能包括信道估计和与SISO系统的性能比较

注意

  1. 本实现假设准静态平坦瑞利衰落信道
  2. 对于更高阶的调制方式(如16QAM、64QAM),可能需要更多的仿真帧数以获得稳定的误码率结果
  3. 信道估计部分使用了简单的线性插值,实际系统中可能需要更复杂的插值算法

这个实现提供了2发1收STBC-MIMO系统的基础框架,您可以根据具体需求进行修改和扩展,例如添加更复杂的信道模型、实现其他空时编码方案或添加更先进的接收机算法。

posted @ 2025-08-20 16:28  躲雨小伙  阅读(25)  评论(0)    收藏  举报