MATLAB 实现:MIMO‑OFDM + Alamouti STBC(2×1 2×2)

MATLAB 实现:MIMO‑OFDM + Alamouti STBC(2×1 / 2×2)


一、系统结构(先对齐)

         ┌─────────┐   ┌─────┐   ┌─────┐
Bits ──► QAM ──► STBC ──► S/P ──► IFFT ──► CP ──► TX1
                 │                │
                 └──────► IFFT ──► CP ──► TX2
                                 │
                        频率选择性信道
                                 │
RX1 ─► 去CP ─► FFT ─► STBC解码 ─► P/S ─► QAM解调 ─► Bits
RX2 ─► 去CP ─► FFT ─► STBC解码 ─┘

关键点:


二、Alamouti STBC 编码规则(2×1)

发射矩阵(两个符号,两个时隙)

[
\begin{bmatrix}
s_1 & -s_2^* \
s_2 & s_1^*
\end{bmatrix}
]


三、MATLAB 核心实现

1、主程序:mimo_ofdm_stbc.m

%% MIMO-OFDM + Alamouti STBC (2Tx)
clear; clc; close all;

%% ========== 参数 ==========
Nfft = 64;           % FFT大小
Ncp = 16;            % 循环前缀
Nsym = 100;          % OFDM符号数
M = 4;               % QPSK
Nt = 2; Nr = 2;      % 天线数
Nbps = log2(M);      % 每符号比特数
EsN0_dB = 0:2:20;    % SNR范围

%% ========== 导频 ==========
pilot = ones(Nfft,1);   % 简单全1导频

ber = zeros(length(EsN0_dB),1);

for snr_idx = 1:length(EsN0_dB)
    fprintf('SNR = %d dB\n', EsN0_dB(snr_idx));
    nErr = 0; nBits = 0;

    for sym = 1:Nsym
        %% -------- 发射端 --------
        % 1. 随机比特
        tx_bits = randi([0 1], Nbps*Nfft, 1);

        % 2. QAM调制
        tx_sym = qammod(tx_bits, M, 'gray', 'UnitAveragePower', true);

        % 3. Alamouti STBC编码(频域)
        X = zeros(Nfft, Nt);
        X(:,1) = tx_sym;          % TX1
        X(:,2) = circshift(tx_sym, Nfft/2); % TX2(示例,实际用Alamouti)

        % 正确Alamouti编码(子载波级)
        X_stbc = zeros(Nfft, 2, 2); % [子载波, 天线, 时隙]
        X_stbc(:,1,1) = tx_sym;               % s1
        X_stbc(:,2,1) = tx_sym;               % s2
        X_stbc(:,1,2) = -conj(X_stbc(:,2,1));% -s2*
        X_stbc(:,2,2) = conj(X_stbc(:,1,1));  % s1*

        % 4. OFDM调制
        tx_time = zeros(Nfft+Ncp, Nt);
        for tx = 1:Nt
            for slot = 1:2
                ofdm = ifft(X_stbc(:,tx,slot), Nfft);
                tx_time(:,tx) = [ofdm(end-Ncp+1:end); ofdm];
            end
        end

        %% -------- 信道 --------
        % 频率选择性瑞利信道(每个子载波独立)
        H = (randn(Nfft, Nr, Nt) + 1j*randn(Nfft, Nr, Nt))/sqrt(2);

        % 加噪声
        sigma2 = 1/(10^(EsN0_dB(snr_idx)/10));
        noise = sqrt(sigma2/2)*(randn(size(tx_time)) + 1j*randn(size(tx_time)));

        % 接收信号
        rx_time = zeros(size(tx_time));
        for slot = 1:2
            for r = 1:Nr
                for t = 1:Nt
                    rx_time(:,r) = rx_time(:,r) + ...
                        conv(tx_time(:,t), H(:,r,t)) + noise(:,r);
                end
            end
        end

        %% -------- 接收端 --------
        % 1. 去CP + FFT
        rx_freq = zeros(Nfft, Nr, 2);
        for r = 1:Nr
            for slot = 1:2
                y = rx_time(Ncp+1:end, r, slot);
                rx_freq(:,r,slot) = fft(y, Nfft);
            end
        end

        % 2. 信道估计(理想,实际用导频)
        H_est = H;

        % 3. Alamouti STBC解码
        rx_sym = zeros(Nfft,1);
        for k = 1:Nfft
            % Alamouti合并(最大比合并)
            h1 = H_est(k,:,1).';  % RX×1
            h2 = H_est(k,:,2).';
            y1 = rx_freq(k,:,1).';
            y2 = rx_freq(k,:,2).';

            s1_hat = h1'*y1 + conj(h2')*conj(y2);
            rx_sym(k) = s1_hat;
        end

        % 4. QAM解调
        rx_bits = qamdemod(rx_sym, M, 'gray', 'UnitAveragePower', true);

        % 5. BER统计
        nErr = nErr + sum(rx_bits ~= tx_bits);
        nBits = nBits + length(tx_bits);
    end
    ber(snr_idx) = nErr/nBits;
end

%% ========== 绘图 ==========
figure('Color','white')
semilogy(EsN0_dB, ber, 'bo-', 'LineWidth',1.5)
grid on; xlabel('E_s/N_0 (dB)'); ylabel('BER')
title('MIMO-OFDM + Alamouti STBC (2×2)')

四、更清晰的 STBC 编码/解码函数

STBC 编码函数

%% stbc_encode.m
function X_stbc = stbc_encode(tx_sym, Nt)
% Alamouti STBC编码
% tx_sym: Nfft×1 频域符号
% Nt: 发射天线数(仅支持2)

Nfft = length(tx_sym);
X_stbc = zeros(Nfft, Nt, 2);

if Nt == 2
    X_stbc(:,1,1) = tx_sym;          % s1
    X_stbc(:,2,1) = tx_sym;          % s2
    X_stbc(:,1,2) = -conj(tx_sym);   % -s2*
    X_stbc(:,2,2) = conj(tx_sym);    % s1*
else
    error('仅支持2发射天线');
end
end

STBC 解码函数(最大比合并)

%% stbc_decode.m
function rx_sym = stbc_decode(rx_freq, H_est)
% Alamouti STBC解码
% rx_freq: Nfft×Nr×2
% H_est: Nfft×Nr×Nt

[Nfft, Nr, ~] = size(rx_freq);
rx_sym = zeros(Nfft,1);

for k = 1:Nfft
    h1 = H_est(k,:,1).';  % Nr×1
    h2 = H_est(k,:,2).';
    y1 = rx_freq(k,:,1).';
    y2 = rx_freq(k,:,2).';

    % Alamouti合并
    s1_hat = h1'*y1 + conj(h2')*conj(y2);
    rx_sym(k) = s1_hat;
end
end

参考代码 matlab 实现MIMO-OFDM中的空时编码 stbc www.youwenfan.com/contentcsw/82776.html

五、工程级改进

1、真实信道估计(导频)

% 导频插入
pilot_pos = 1:8:Nfft;
X_stbc(pilot_pos,:,1) = pilot;
X_stbc(pilot_pos,:,2) = pilot;

% LS估计
H_ls = zeros(Nfft,Nr,Nt);
for r = 1:Nr
    for t = 1:Nt
        H_ls(pilot_pos,r,t) = rx_freq(pilot_pos,r,t) ./ pilot;
        % 插值
        H_ls(:,r,t) = interp1(pilot_pos, H_ls(pilot_pos,r,t), 1:Nfft, 'linear');
    end
end

2、循环前缀卷积修正

% 正确的线性卷积(用toeplitz矩阵)
chan = (randn(10,1)+1j*randn(10,1))/sqrt(2);
rx_slot = conv(tx_time(:,1), chan, 'full');

3、多天线扩展(4×4)

% 使用 Golden 码 / 线性分散码
% 或 空间复用(V-BLAST)+ STBC

六、性能对比

方案 分集阶数 速率 复杂度
SISO-OFDM 1 1
STBC 2×1 2 1
STBC 2×2 4 1
SM 2×2 2 2

七、与标准协议的关系

标准 STBC用法
IEEE 802.16e (WiMAX) Alamouti 2×1
LTE Release 8 仅 SU-MIMO,不用STBC
5G NR 可选 STBC(低阶MCS)
WLAN 802.11n Alamouti(可选)

 

专注于matlab/simulink,电子电路,编程