OFDM系统仿真与分析(附代码)

关键词: 正交频分复用、仿真、循环前缀、信道估计

1. 简单认识OFDM

正交频分复用(OFDM) 是第四代移动通信的核心技术。

在高速通信(宽带通信)中,我们认为传输带宽是1/2倍的传输速率,那么就有一个问题,如何实现高速通信?无线扩大带宽吗?众所周知,带宽贵如油。因此我们选取了这样一种方法:将一串高速传输的数字信号变成多路并行的低速数据,最后再由不同的载波发送。OFDM技术就是采用这样一种技术。
OFDM系统仿真与分析(附代码)_第1张图片

2. 概述

随着移动通信和无线因特网需求的不断增长,越来越需要高速无线系统设计,而这其中的一个最直接的挑战就是克服无线信道带来的严重的频率选择性衰落。正交频分复用(OFDM)技术可以很好地克服无线信道的频率选择性衰落,由于其简单高效,OFDM已成为实现未来无线高速通信系统中最核心的技术之一。现代移动通信发展至今,已经经历了三代,而3G 的后续技术也在加速研究中。目前,国际标准化组织正在推动无线传输技术从2Mb/s 的传输速率向100Mb/s 和1000Mb/s 的目标发展,对4G 的定义也已经逐渐清晰起来。基本上可以确定,OFDM/OFDMA、MIMO和智能天线等技术将成为4G 的主流技术。OFDM 相关的技术很多, 实际应用中的OFDM 复杂度很高。因此, 建立适合自己研究方向的OFDM 模型, 无论是为了理解OFDM 技术的理论,还是对后续的OFDM 与其他技术相结合的研究工作,都有着非常重要意义。

3. OFDM的优缺点

OFDM技术的优点主要有:

  1. OFDM调制方式适用于多径和衰落信道中的高速数据传输。当信道因为多径的影响出现频率选择性衰落时,只有落在频率凹陷处的载波及其携带的信息受到影响,其它子载波未受损害。
  2. 在OFDM调制方式中,通过插入保护间隔,可以很好地克服符号间干扰(ISI)和载波间干扰(ICI)。
  3. 由于OFDM各子载波相互正交,允许各子载波有1/2重叠,因此可以大大提高频谱利用率。
  4. 由于深度衰落而丢失的一些子载波可通过编码、交织等措施来很好的恢复,提高系统抗误码性能,且通过各子载波的联合编码,具有很强的抗衰落能力。
  5. OFDM技术抗脉冲及窄带干扰的能力很强,因为这些干扰仅仅影响到很小一部分的子信道。
  6. 与单载波系统相比,对采样定时偏移不敏感。

OFDM技术的缺点主要有

  1. 由于要求各子载波正交,所以对频率偏移和相位噪声很敏感;
  2. 由于各子载波相互独立,峰值功率与均值功率比相对较大,且随子载波数目的增加而增加。高峰均比信号通过功放时,为了避免信号的非线性失真和带外频谱再生,功放需要具有较大的线性范围,导致射频放大器的功率效率降低。

4. OFDM基本原理

在宽带无线通信系统中,影响高速信息传输的最主要一类干扰是频率选择性干扰。它表现为对信号的某些频率成分衰减严重,而对另外一些频率成分有较高的增益。为克服这类衰落,一个很自然的想法是在信道上划分多个子信道,使每一个子信道的频率特性都近似于平坦,使用这些独立的子信道传输信号并在接收机中予以合并,以实现信号的频率分集,这就是多载波调制的基本思想。在无线通信中应用最广的是OFDM多载波调制技术,它的每一个子载波都是正交的,提高了频谱的利用率。还可以在OFDM符号之间插入保护间隔,令保护间隔大于无线信道的最大时延扩展,最大限度的消除由于多径带来的符号间干扰。
基于IFFT/FFT 的OFDM 系统模型
OFDM系统仿真与分析(附代码)_第2张图片
串行输入数据为经过信道编码后的序列(如Turbo码),将该序列转换成包含R个比特的块,每块再分成N个组,每个组对应一个子载波。根据所采用调制方式的不同,每个组包含的比特数可以不同,设第K 组的比特数为, 则有采用ASK、PSK、QAM等调制方式将这个比特映射成复值符号。
由于对每个连续OFDM 码元采样N 个样本,正好满足Nyquist 采样定理,所以可以通过这些样值重构原始的连续信号。这样样值可以通过IDFT 来得到,这就是用IDFT 和DFT 可以实现OFDM 系统的根源。下面给出OFDM载波的幅度谱和相位谱。
OFDM系统仿真与分析(附代码)_第3张图片
OFDM系统仿真与分析(附代码)_第4张图片

clear all;
close all;
IFFT_bin_length = 1024;   % FFT的点数
carrier_count = 200;       % 载波的数量 
bits_per_symbol = 2;      % 每个符号代表的比特数
symbols_per_carrier = 50;  % 每个载波使用的符号数
SNR = 10;              % 信道中的信噪比(dB)                           
baseband_out_length=carrier_count*symbols_per_carrier*bits_per_symbol;%总比特数
carriers = (1:carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2));
conjugate_carriers = IFFT_bin_length - carriers + 2;
%发送端>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
%产生随机二进制数据:
baseband_out = round(rand(1,baseband_out_length));
convert_matrix=reshape(baseband_out,bits_per_symbol,length(baseband_out)/bits_per_symbol);
for k = 1:(length(baseband_out)/bits_per_symbol)
    modulo_baseband(k) = 0;
    for i = 1:bits_per_symbol
modulo_baseband(k)=modulo_baseband(k)+convert_matrix(i,k)*2^(bits_per_symbol-i);
end
end
% 串并转换
carrier_matrix = reshape(modulo_baseband, carrier_count, symbols_per_carrier)';
% 对每一个载波的符号进行差分编码
carrier_matrix = [zeros(1,carrier_count);carrier_matrix];
for i = 2:(symbols_per_carrier + 1)
 carrier_matrix(i,:)=rem(carrier_matrix(i,:)+carrier_matrix(i-1,:),2^bits_per_symbol);
end
% 把差分符号代码转换成相位
carrier_matrix = carrier_matrix * ((2*pi)/(2^bits_per_symbol));
% 把相位转换成复数
[X,Y] = pol2cart(carrier_matrix, ones(size(carrier_matrix,1),size(carrier_matrix,2)));
complex_carrier_matrix = complex(X,Y);
% 分配载波到指定的IFFT位置
IFFT_modulation = zeros(symbols_per_carrier + 1, IFFT_bin_length);
IFFT_modulation(:,carriers) = complex_carrier_matrix;
IFFT_modulation(:,conjugate_carriers) = conj(complex_carrier_matrix);
% 画出频域中的OFDM信号代表
figure (1)
stem(0:IFFT_bin_length-1, abs(IFFT_modulation(2,1:IFFT_bin_length)),'b*-')
grid on
axis ([0 IFFT_bin_length -0.5 1.5])
ylabel('Magnitude')
xlabel('IFFT Bin')
title('OFDM Carrier Frequency Magnitude')
% 
figure (2)
plot(0:IFFT_bin_length-1, (180/pi)*angle(IFFT_modulation(2,1:IFFT_bin_length)), 'go')
hold on
stem(carriers-1, (180/pi)*angle(IFFT_modulation(2,carriers)),'b*-')
stem(conjugate_carriers-1, (180/pi)*angle(IFFT_modulation(2,conjugate_carriers)),'b*-')
axis ([0 IFFT_bin_length -200 +200])
grid on
ylabel('Phase (degrees)')
xlabel('IFFT Bin')
title('OFDM Carrier Phase')
% 通过IFFT将频域转化为时域,得到时域信号
time_wave_matrix = ifft(IFFT_modulation');
time_wave_matrix = time_wave_matrix';
%画出一个符号周期的时域OFDM信号
figure (3)
plot(0:IFFT_bin_length-1,time_wave_matrix(2,:))
grid on
ylabel('Amplitude')
xlabel('Time')
title('OFDM Time Signal, One Symbol Period')
%画出每一个载波对应的时域信号(分离的OFDM信号)
for f = 1:carrier_count
    temp_bins(1:IFFT_bin_length)=0+0j;
    temp_bins(carriers(f))=IFFT_modulation(2,carriers(f));
    temp_bins(conjugate_carriers(f))=IFFT_modulation(2,conjugate_carriers(f));
    temp_time = ifft(temp_bins');
    figure(4)
    plot(0:IFFT_bin_length-1, temp_time)
   hold on
end
grid on
ylabel('Amplitude')
xlabel('Time')
title('Separated Time Waveforms Carriers')
for i = 1:symbols_per_carrier + 1
windowed_time_wave_matrix(i,:)=real(time_wave_matrix(i,:)).*hamming(IFFT_bin_length)';
windowed_time_wave_matrix(i,:) = real(time_wave_matrix(i,:));
end
%串并转换
ofdm_modulation=reshape(windowed_time_wave_matrix',1,IFFT_bin_length*(symbols_per_carrier+1));
% 画出整个时域OFDM
temp_time = IFFT_bin_length*(symbols_per_carrier+1);
figure (5)
plot(0:temp_time-1,ofdm_modulation)
grid on
ylabel('Amplitude (volts)')
xlabel('Time (samples)')
title('OFDM Time Signal')
% 画出频域OFDM信号
symbols_per_average = ceil(symbols_per_carrier/5);
avg_temp_time = IFFT_bin_length*symbols_per_average;
averages = floor(temp_time/avg_temp_time);
average_fft(1:avg_temp_time) = 0;
for a = 0:(averages-1)
subset_ofdm=ofdm_modulation(((a*avg_temp_time)+1):((a+1)*avg_temp_time));
    subset_ofdm_f = abs(fft(subset_ofdm));
    average_fft = average_fft + (subset_ofdm_f/averages);
end
average_fft_log = 20*log10(average_fft);
figure (6)
plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)
hold on
plot(0:1/IFFT_bin_length:1, -35, 'rd')
grid on
axis([0 0.5 -40 max(average_fft_log)])
ylabel('Magnitude (dB)')
xlabel('Normalized Frequency (0.5 = fs/2)')
title('OFDM Signal Spectrum')

% 上变频,这个模型中我们把经过IFFT运算后OFDM直接发送
Tx_data = ofdm_modulation;
%信道=======================================================
% The channel model is Gaussian (AWGN) +Multipath(时延为1) 
Tx_signal_power = var(Tx_data);
linear_SNR = 10^(SNR/10);
noise_sigma = Tx_signal_power/linear_SNR;
noise_scale_factor = sqrt(noise_sigma);
noise = randn(1, length(Tx_data))*noise_scale_factor;
copy1=zeros(1,length(ofdm_modulation));
for i=2:length(ofdm_modulation)
    copy1(i)=ofdm_modulation(i-1);
end
Rx_Data = Tx_data + noise;
%RECEIVE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
% 根据符号长度和符号数将串行的符号转换为并行的
%   - 每一列是符号周期
Rx_Data_matrix = reshape(Rx_Data, IFFT_bin_length, symbols_per_carrier + 1);
%对每一列信号做FFT得到频域信号
Rx_spectrum = fft(Rx_Data_matrix);
% 画出接收到的OFDM信号频域代表
%--------1---------2---------3---------4---------5---------6---------7---------8
figure (7)
stem(0:IFFT_bin_length-1, abs(Rx_spectrum(1:IFFT_bin_length,2)),'b*-')
grid on
axis ([0 IFFT_bin_length -0.5 1.5])
ylabel('Magnitude')
xlabel('FFT Bin')
title('OFDM Receive Spectrum, Magnitude')
figure (8)
plot(0:IFFT_bin_length-1, (180/pi)*angle(Rx_spectrum(1:IFFT_bin_length,2)), 'go')
hold on
stem(carriers-1, (180/pi)*angle(Rx_spectrum(carriers,2)),'b*-')
stem(conjugate_carriers-1, (180/pi)*angle(Rx_spectrum(conjugate_carriers,2)),'b*-')
axis ([0 IFFT_bin_length -200 +200])
grid on
ylabel('Phase (degrees)')
xlabel('FFT Bin')
title('OFDM Receive Spectrum,  Phase')
% 抽取接收信号中有载波的点

Rx_carriers = Rx_spectrum(carriers,:)';
%画出每个接收符号分布图
figure (9)
Rx_phase_P = angle(Rx_carriers);
Rx_mag_P = abs(Rx_carriers);
polar(Rx_phase_P, Rx_mag_P,'bd');
%   计算载波的相位
%   - 弧度转换为角度
%   - 归一化相位(0-360)
Rx_phase = angle(Rx_carriers)*(180/pi);
phase_negative = find(Rx_phase < 0);
Rx_phase(phase_negative) = rem(Rx_phase(phase_negative)+360,360);
%diff()计算相位差
Rx_decoded_phase = diff(Rx_phase);
phase_negative = find(Rx_decoded_phase < 0);
Rx_decoded_phase(phase_negative) = rem(Rx_decoded_phase(phase_negative)+360,360);

0FDM 系统调制与解调解析
假设FFT的点数是2048,载波数量是200,每个符号代表2bit,每个载波使用100个符号,则OFDM的时域和频域图形如下:
OFDM一个符号周期的时域OFDM信号OFDM系统仿真与分析(附代码)_第5张图片
OFDM每一个载波对应的时域信号
OFDM系统仿真与分析(附代码)_第6张图片

5. 加窗

为了加快OFDM信号功率谱带外衰减部分的下降速度,可以对每个OFDM时域符号进行加窗,使符号周期边缘的幅度值逐渐过渡到零,这与成型滤波的原理相当的类似。成型滤波是在频域加平方根升余弦窗,降低时域信号的拖尾振荡;而OFDM符号在时域加升余弦窗,降低频域信号拖尾振荡,使带外衰减速度加快。
载波数为256的信号频谱信号仿真图
OFDM系统仿真与分析(附代码)_第7张图片
载波数128的信号频谱信号功率谱带外衰减仿真图
OFDM系统仿真与分析(附代码)_第8张图片
通过对OFDM信号加窗前后的信号频谱进行仿真比较,得到加窗后信号的带外衰减大副减小,但是对信号的误码率也有一定的影响。

未加窗OFDM功率频谱带外衰减仿真
OFDM系统仿真与分析(附代码)_第9张图片

加升余弦窗后OFDM功率谱带外衰减仿真
OFDM系统仿真与分析(附代码)_第10张图片

clear all;
close all;
IFFT_bin_length = 1024;   % FFT的点数
carrier_count = 200;       % 载波的数量 
bits_per_symbol = 2;      % 每个符号代表的比特数
symbols_per_carrier = 50;  % 每个载波使用的符号数
SNR = 10;              % 信道中的信噪比(dB)                           
baseband_out_length=carrier_count*symbols_per_carrier*bits_per_symbol;%总比特数
carriers = (1:carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2));
conjugate_carriers = IFFT_bin_length - carriers + 2;
%发送端>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
%产生随机二进制数据:
baseband_out = round(rand(1,baseband_out_length));
convert_matrix=reshape(baseband_out,bits_per_symbol,length(baseband_out)/bits_per_symbol);
for k = 1:(length(baseband_out)/bits_per_symbol)
    modulo_baseband(k) = 0;
    for i = 1:bits_per_symbol
modulo_baseband(k)=modulo_baseband(k)+convert_matrix(i,k)*2^(bits_per_symbol-i);
end
end
% 串并转换
carrier_matrix = reshape(modulo_baseband, carrier_count, symbols_per_carrier)';
% 对每一个载波的符号进行差分编码
carrier_matrix = [zeros(1,carrier_count);carrier_matrix];
for i = 2:(symbols_per_carrier + 1)
 carrier_matrix(i,:)=rem(carrier_matrix(i,:)+carrier_matrix(i-1,:),2^bits_per_symbol);
end
% 把差分符号代码转换成相位
carrier_matrix = carrier_matrix * ((2*pi)/(2^bits_per_symbol));
% 把相位转换成复数
[X,Y] = pol2cart(carrier_matrix, ones(size(carrier_matrix,1),size(carrier_matrix,2)));
complex_carrier_matrix = complex(X,Y);
% 分配载波到指定的IFFT位置
IFFT_modulation = zeros(symbols_per_carrier + 1, IFFT_bin_length);
IFFT_modulation(:,carriers) = complex_carrier_matrix;
IFFT_modulation(:,conjugate_carriers) = conj(complex_carrier_matrix);
% 画出频域中的OFDM信号代表
figure (1)
stem(0:IFFT_bin_length-1, abs(IFFT_modulation(2,1:IFFT_bin_length)),'b*-')
grid on
axis ([0 IFFT_bin_length -0.5 1.5])
ylabel('Magnitude')
xlabel('IFFT Bin')
title('OFDM Carrier Frequency Magnitude')
% 
figure (2)
plot(0:IFFT_bin_length-1, (180/pi)*angle(IFFT_modulation(2,1:IFFT_bin_length)), 'go')
hold on
stem(carriers-1, (180/pi)*angle(IFFT_modulation(2,carriers)),'b*-')
stem(conjugate_carriers-1, (180/pi)*angle(IFFT_modulation(2,conjugate_carriers)),'b*-')
axis ([0 IFFT_bin_length -200 +200])
grid on
ylabel('Phase (degrees)')
xlabel('IFFT Bin')
title('OFDM Carrier Phase')
% 通过IFFT将频域转化为时域,得到时域信号
time_wave_matrix = ifft(IFFT_modulation');
time_wave_matrix = time_wave_matrix';
%画出一个符号周期的时域OFDM信号
figure (3)
plot(0:IFFT_bin_length-1,time_wave_matrix(2,:))
grid on
ylabel('Amplitude')
xlabel('Time')
title('OFDM Time Signal, One Symbol Period')
%画出每一个载波对应的时域信号(分离的OFDM信号)
for f = 1:carrier_count
    temp_bins(1:IFFT_bin_length)=0+0j;
    temp_bins(carriers(f))=IFFT_modulation(2,carriers(f));
    temp_bins(conjugate_carriers(f))=IFFT_modulation(2,conjugate_carriers(f));
    temp_time = ifft(temp_bins');
    figure(4)
    plot(0:IFFT_bin_length-1, temp_time)
   hold on
end
grid on
ylabel('Amplitude')
xlabel('Time')
title('Separated Time Waveforms Carriers')
for i = 1:symbols_per_carrier + 1
windowed_time_wave_matrix(i,:)=real(time_wave_matrix(i,:)).*hamming(IFFT_bin_length)';
windowed_time_wave_matrix(i,:) = real(time_wave_matrix(i,:));
end
%串并转换
ofdm_modulation=reshape(windowed_time_wave_matrix',1,IFFT_bin_length*(symbols_per_carrier+1));
% 画出整个时域OFDM
temp_time = IFFT_bin_length*(symbols_per_carrier+1);
figure (5)
plot(0:temp_time-1,ofdm_modulation)
grid on
ylabel('Amplitude (volts)')
xlabel('Time (samples)')
title('OFDM Time Signal')
% 画出频域OFDM信号
symbols_per_average = ceil(symbols_per_carrier/5);
avg_temp_time = IFFT_bin_length*symbols_per_average;
averages = floor(temp_time/avg_temp_time);
average_fft(1:avg_temp_time) = 0;
for a = 0:(averages-1)
subset_ofdm=ofdm_modulation(((a*avg_temp_time)+1):((a+1)*avg_temp_time));
    subset_ofdm_f = abs(fft(subset_ofdm));
    average_fft = average_fft + (subset_ofdm_f/averages);
end
average_fft_log = 20*log10(average_fft);
figure (6)
plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)
hold on
plot(0:1/IFFT_bin_length:1, -35, 'rd')
grid on
axis([0 0.5 -40 max(average_fft_log)])
ylabel('Magnitude (dB)')
xlabel('Normalized Frequency (0.5 = fs/2)')
title('OFDM Signal Spectrum')

% 上变频,这个模型中我们把经过IFFT运算后OFDM直接发送
Tx_data = ofdm_modulation;
%信道=======================================================
% The channel model is Gaussian (AWGN) +Multipath(时延为1) 
Tx_signal_power = var(Tx_data);
linear_SNR = 10^(SNR/10);
noise_sigma = Tx_signal_power/linear_SNR;
noise_scale_factor = sqrt(noise_sigma);
noise = randn(1, length(Tx_data))*noise_scale_factor;
copy1=zeros(1,length(ofdm_modulation));
for i=2:length(ofdm_modulation)
    copy1(i)=ofdm_modulation(i-1);
end
Rx_Data = Tx_data + noise;
%RECEIVE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
% 根据符号长度和符号数将串行的符号转换为并行的
%   - 每一列是符号周期
Rx_Data_matrix = reshape(Rx_Data, IFFT_bin_length, symbols_per_carrier + 1);
%对每一列信号做FFT得到频域信号
Rx_spectrum = fft(Rx_Data_matrix);
% 画出接收到的OFDM信号频域代表
%--------1---------2---------3---------4---------5---------6---------7---------8
figure (7)
stem(0:IFFT_bin_length-1, abs(Rx_spectrum(1:IFFT_bin_length,2)),'b*-')
grid on
axis ([0 IFFT_bin_length -0.5 1.5])
ylabel('Magnitude')
xlabel('FFT Bin')
title('OFDM Receive Spectrum, Magnitude')
figure (8)
plot(0:IFFT_bin_length-1, (180/pi)*angle(Rx_spectrum(1:IFFT_bin_length,2)), 'go')
hold on
stem(carriers-1, (180/pi)*angle(Rx_spectrum(carriers,2)),'b*-')
stem(conjugate_carriers-1, (180/pi)*angle(Rx_spectrum(conjugate_carriers,2)),'b*-')
axis ([0 IFFT_bin_length -200 +200])
grid on
ylabel('Phase (degrees)')
xlabel('FFT Bin')
title('OFDM Receive Spectrum,  Phase')
% 抽取接收信号中有载波的点

Rx_carriers = Rx_spectrum(carriers,:)';
%画出每个接收符号分布图
figure (9)
Rx_phase_P = angle(Rx_carriers);
Rx_mag_P = abs(Rx_carriers);
polar(Rx_phase_P, Rx_mag_P,'bd');
%   计算载波的相位
%   - 弧度转换为角度
%   - 归一化相位(0-360)
Rx_phase = angle(Rx_carriers)*(180/pi);
phase_negative = find(Rx_phase < 0);
Rx_phase(phase_negative) = rem(Rx_phase(phase_negative)+360,360);
% 用diff()计算相位差
Rx_decoded_phase = diff(Rx_phase);
phase_negative = find(Rx_decoded_phase < 0);
Rx_decoded_phase(phase_negative) = rem(Rx_decoded_phase(phase_negative)+360,360);
%--------1---------2---------3---------4---------5---------6---------7---------8
% 相位转化为符号
base_phase = 360/2^bits_per_symbol;
delta_phase = base_phase/2;
Rx_decoded_symbols= zeros(size(Rx_decoded_phase,1),size(Rx_decoded_phase,2));
for i = 1:(2^bits_per_symbol - 1)  
    center_phase = base_phase*i;
    plus_delta = center_phase+delta_phase;
    minus_delta = center_phase-delta_phase;
decoded=find((Rx_decoded_phase<=plus_delta)&(Rx_decoded_phase>minus_delta));
Rx_decoded_symbols(decoded)=i;
end
% Convert the matrix into a serial symbol stream
Rx_serial_symbols=reshape(Rx_decoded_symbols',1,size(Rx_decoded_symbols,1)*size(Rx_decoded_symbols,2));
% Convert the symbols to binary
for i = bits_per_symbol: -1: 1
    if i ~= 1
        Rx_binary_matrix(i,:) = rem(Rx_serial_symbols,2);
        Rx_serial_symbols = floor(Rx_serial_symbols/2);
    else
        Rx_binary_matrix(i,:) = Rx_serial_symbols;
    end
end
baseband_in=reshape(Rx_binary_matrix,1,size(Rx_binary_matrix,1)*size(Rx_binary_matrix,2));
% 查找错位比特
bit_errors = find(baseband_in ~= baseband_out);
bit_error_count = size(bit_errors,2);


d_out,bits_per_symbol,length(baseband_out)/bits_per_symbol);
for k = 1:(length(baseband_out)/bits_per_symbol)
    modulo_baseband(k) = 0;
    for i = 1:bits_per_symbol
modulo_baseband(k)=modulo_baseband(k)+convert_matrix(i,k)*2^(bits_per_symbol-i);
end
end
% 串并转换
carrier_matrix = reshape(modulo_baseband, carrier_count, symbols_per_carrier)';
% 对每一个载波的符号进行差分编码
carrier_matrix = [zeros(1,carrier_count);carrier_matrix];
for i = 2:(symbols_per_carrier + 1)
 carrier_matrix(i,:)=rem(carrier_matrix(i,:)+carrier_matrix(i-1,:),2^bits_per_symbol);
end
% 把差分符号代码转换成相位
carrier_matrix = carrier_matrix * ((2*pi)/(2^bits_per_symbol));
% 把相位转换成复数
[X,Y] = pol2cart(carrier_matrix, ones(size(carrier_matrix,1),size(carrier_matrix,2)));
complex_carrier_matrix = complex(X,Y);
% 分配载波到指定的IFFT位置
IFFT_modulation = zeros(symbols_per_carrier + 1, IFFT_bin_length);
IFFT_modulation(:,carriers) = complex_carrier_matrix;
IFFT_modulation(:,conjugate_carriers) = conj(complex_carrier_matrix);
% 画出频域中的OFDM信号代表
figure (1)
stem(0:IFFT_bin_length-1, abs(IFFT_modulation(2,1:IFFT_bin_length)),'b*-')
grid on
axis ([0 IFFT_bin_length -0.5 1.5])
ylabel('Magnitude')
xlabel('IFFT Bin')
title('OFDM Carrier Frequency Magnitude')
figure (2)
plot(0:IFFT_bin_length-1, (180/pi)*angle(IFFT_modulation(2,1:IFFT_bin_length)), 'go')
hold on
stem(carriers-1, (180/pi)*angle(IFFT_modulation(2,carriers)),'b*-')
stem(conjugate_carriers-1, (180/pi)*angle(IFFT_modulation(2,conjugate_carriers)),'b*-')
axis ([0 IFFT_bin_length -200 +200])
grid on
ylabel('Phase (degrees)')
xlabel('IFFT Bin')
title('OFDM Carrier Phase')
% 通过IFFT将频域转化为时域,得到时域信号
time_wave_matrix = ifft(IFFT_modulation');
time_wave_matrix = time_wave_matrix';
%画出一个符号周期的时域OFDM信号
figure (3)
plot(0:IFFT_bin_length-1,time_wave_matrix(2,:))
grid on
ylabel('Amplitude')
xlabel('Time')
title('OFDM Time Signal, One Symbol Period')
%画出每一个载波对应的时域信号(分离的OFDM信号)
for f = 1:carrier_count
    temp_bins(1:IFFT_bin_length)=0+0j;
    temp_bins(carriers(f))=IFFT_modulation(2,carriers(f));
    temp_bins(conjugate_carriers(f))=IFFT_modulation(2,conjugate_carriers(f));
    temp_time = ifft(temp_bins');
    figure(4)
    plot(0:IFFT_bin_length-1, temp_time)
   hold on
end
grid on
ylabel('Amplitude')
xlabel('Time')
title('Separated Time Waveforms Carriers')
for i = 1:symbols_per_carrier + 1
windowed_time_wave_matrix(i,:)=real(time_wave_matrix(i,:)).*hamming(IFFT_bin_length)';
windowed_time_wave_matrix(i,:) = real(time_wave_matrix(i,:));
end
%串并转换
ofdm_modulation=reshape(windowed_time_wave_matrix',1,IFFT_bin_length*(symbols_per_carrier+1));
% 画出整个时域OFDM
temp_time = IFFT_bin_length*(symbols_per_carrier+1);
figure (5)
plot(0:temp_time-1,ofdm_modulation)
grid on
ylabel('Amplitude (volts)')
xlabel('Time (samples)')
title('OFDM Time Signal')
% 画出频域OFDM信号
symbols_per_average = ceil(symbols_per_carrier/5);
avg_temp_time = IFFT_bin_length*symbols_per_average;
averages = floor(temp_time/avg_temp_time);
average_fft(1:avg_temp_time) = 0;
for a = 0:(averages-1)
subset_ofdm=ofdm_modulation(((a*avg_temp_time)+1):((a+1)*avg_temp_time));
    subset_ofdm_f = abs(fft(subset_ofdm));
    average_fft = average_fft + (subset_ofdm_f/averages);
end
average_fft_log = 20*log10(average_fft);
figure (6)
plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log)
hold on
plot(0:1/IFFT_bin_length:1, -35, 'rd')
grid on
axis([0 0.5 -40 max(average_fft_log)])
ylabel('Magnitude (dB)')
xlabel('Normalized Frequency (0.5 = fs/2)')
title('OFDM Signal Spectrum')

% 上变频,这个模型中我们把经过IFFT运算后OFDM直接发送
Tx_data = ofdm_modulation;
%信道=======================================================
% The channel model is Gaussian (AWGN) +Multipath(时延为1) 
Tx_signal_power = var(Tx_data);
linear_SNR = 10^(SNR/10);
noise_sigma = Tx_signal_power/linear_SNR;
noise_scale_factor = sqrt(noise_sigma);
noise = randn(1, length(Tx_data))*noise_scale_factor;
copy1=zeros(1,length(ofdm_modulation));
for i=2:length(ofdm_modulation)
    copy1(i)=ofdm_modulation(i-1);
end
Rx_Data = Tx_data + noise;
%RECEIVE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
% 根据符号长度和符号数将串行的符号转换为并行的
%   - 每一列是符号周期
Rx_Data_matrix = reshape(Rx_Data, IFFT_bin_length, symbols_per_carrier + 1);
%对每一列信号做FFT得到频域信号
Rx_spectrum = fft(Rx_Data_matrix);
% 画出接收到的OFDM信号频域代表
%--------1---------2---------3---------4---------5---------6---------7---------8
figure (7)
stem(0:IFFT_bin_length-1, abs(Rx_spectrum(1:IFFT_bin_length,2)),'b*-')
grid on
axis ([0 IFFT_bin_length -0.5 1.5])
ylabel('Magnitude')
xlabel('FFT Bin')
title('OFDM Receive Spectrum, Magnitude')
figure (8)
plot(0:IFFT_bin_length-1, (180/pi)*angle(Rx_spectrum(1:IFFT_bin_length,2)), 'go')
hold on
stem(carriers-1, (180/pi)*angle(Rx_spectrum(carriers,2)),'b*-')
stem(conjugate_carriers-1, (180/pi)*angle(Rx_spectrum(conjugate_carriers,2)),'b*-')
axis ([0 IFFT_bin_length -200 +200])
grid on
ylabel('Phase (degrees)')
xlabel('FFT Bin')
title('OFDM Receive Spectrum,  Phase')
% 抽取接收信号中有载波的点

Rx_carriers = Rx_spectrum(carriers,:)';
%画出每个接收符号分布图
figure (9)
Rx_phase_P = angle(Rx_carriers);
Rx_mag_P = abs(Rx_carriers);
polar(Rx_phase_P, Rx_mag_P,'bd');
%   计算载波的相位
%   - 弧度转换为角度
%   - 归一化相位(0-360)
Rx_phase = angle(Rx_carriers)*(180/pi);
phase_negative = find(Rx_phase < 0);
Rx_phase(phase_negative) = rem(Rx_phase(phase_negative)+360,360);
% 用diff()计算相位差
Rx_decoded_phase = diff(Rx_phase);
phase_negative = find(Rx_decoded_phase < 0);
Rx_decoded_phase(phase_negative) = rem(Rx_decoded_phase(phase_negative)+360,360);
%--------1---------2---------3---------4---------5---------6---------7---------8
% 相位转化为符号
base_phase = 360/2^bits_per_symbol;
delta_phase = base_phase/2;
Rx_decoded_symbols= zeros(size(Rx_decoded_phase,1),size(Rx_decoded_phase,2));
for i = 1:(2^bits_per_symbol - 1)  
    center_phase = base_phase*i;
    plus_delta = center_phase+delta_phase;
    minus_delta = center_phase-delta_phase;
decoded=find((Rx_decoded_phase<=plus_delta)&(Rx_decoded_phase>minus_delta));
Rx_decoded_symbols(decoded)=i;
end
% Convert the matrix into a serial symbol stream
Rx_serial_symbols=reshape(Rx_decoded_symbols',1,size(Rx_decoded_symbols,1)*size(Rx_decoded_symbols,2));
% Convert the symbols to binary
for i = bits_per_symbol: -1: 1
    if i ~= 1
        Rx_binary_matrix(i,:) = rem(Rx_serial_symbols,2);
        Rx_serial_symbols = floor(Rx_serial_symbols/2);
    else
        Rx_binary_matrix(i,:) = Rx_serial_symbols;
    end
end
baseband_in=reshape(Rx_binary_matrix,1,size(Rx_binary_matrix,1)*size(Rx_binary_matrix,2));
% 查找错位比特
bit_errors = find(baseband_in ~= baseband_out);
bit_error_count = size(bit_errors,2);



你可能感兴趣的:(水声通信,数字通信)