本文考虑OFDM系统在多径信道下的误码性能

代码

clc;close all;clear

%% Seting parameters
EbN0_list = 20:2:40;
Q_order_list = 2:2:10;
loopNumber = 10000;
fprintf('Qm\t EbN0 \t \t EsN0 \t \t SNR_Cal \t \t ser \t\t ser_theory\t\t\t ber\t\t nloop \t\t \n');
for iQorder = 1 : length(Q_order_list)
for iEbN0 = 1 : length(EbN0_list) %% Frame structure
N_Frame = 1;
N_Symbol = 1;
N_RB = 106;
N_SC_perRB = 12;
N_SC = N_RB * N_SC_perRB;
N_Ant = 1;
N_fft_order = floor(log2(N_RB * N_SC_perRB));
N_fft = 2^(N_fft_order+1);
N_cp = N_fft/8;
EbN0 = EbN0_list(iEbN0); %% Modulation
Q_order = Q_order_list(iQorder);
Qm = 2^Q_order;
N_bit = N_Frame * N_Symbol * N_RB * N_SC_perRB * Q_order; %% Noise Calculation
SNR = EbN0 + 10 * log10(Q_order); %% Loop
for iloop = 1 :loopNumber
data_bit_in = randi([0 1], 1, N_bit);
dataSymbolsIn = bi2de(reshape(data_bit_in, Q_order, N_bit/Q_order).', 'left-msb');
dataMod = qammod(dataSymbolsIn, Qm,'UnitAveragePower', true); %% Show Constellation
%scatterplotme(dataMod) %% Resource Mapping
RE_Grid = zeros(N_RB * N_SC_perRB,N_Symbol * N_Frame);
dataMod_tmp = reshape(dataMod,N_RB * N_SC_perRB,[]); %only data
Power_Scale = 1;
RE_Grid_all = Power_Scale * dataMod_tmp; %% IFFT add CP
frame_mod_shift = ifftshift(RE_Grid_all);
ifft_data = ifft(frame_mod_shift,N_fft)*sqrt(N_fft);
%ifft_data = ifft(frame_mod_shift)*sqrt(1272);
Tx_cd = [ifft_data(N_fft-N_cp+1:end,:);ifft_data];
time_signal = reshape(Tx_cd,[],1); %% Channel
power_RE = sum(sum(abs(RE_Grid_all).^2)) / N_RB / N_SC_perRB / N_Symbol / N_Frame;
power_tp = sum(sum(abs(ifft_data).^2)) / N_RB / N_SC_perRB / N_Symbol / N_Frame; %IFFT zero padding averages the true RE Power
N0 = power_RE .* 10.^(-SNR / 10);
white_noise_starand = 1/sqrt(2)*(randn(size(time_signal)) + 1j * randn(size(time_signal)));
nTap = 2;
taps = RayleighChanTaps(nTap);
% taps = [0.9,0.1];
time_signal_path = Multipath_channel(time_signal,taps);
TransmittedSignal = time_signal_path + sqrt(N0) * white_noise_starand; %% Receive and Sys
ReceivedSignal = TransmittedSignal;
hF = fftshift(fft(taps,N_fft)); %% FFT and Frame
frame_recieved_parallel = reshape(ReceivedSignal, N_fft + N_cp, []);
frame_Received = frame_recieved_parallel(N_cp + 1:end,:);
frame_Grid_fft = fft(frame_Received,N_fft) / sqrt(N_fft);
RE_Grid_all_fftshift = fftshift(frame_Grid_fft);
RE_Grid_all_fftshift_eq = fftshift(diag(1./hF)*RE_Grid_all_fftshift);
RE_Grid_all_Received = fftshift(RE_Grid_all_fftshift_eq(1:N_SC,:));
% figure(1)
% plot(abs(RE_Grid_all_fftshift(:,1)))
% figure(2)
% plot(abs(RE_Grid_all_fftshift_eq(:,1)))
% figure(3)
% plot(abs(abs(hF)))
% figure(4)
% plot(abs(abs(1./hF))) %% Demodulation
RE_PreDeMod = reshape(RE_Grid_all_Received,[],1);
dataSymbolsOut = qamdemod(RE_PreDeMod, Qm,'UnitAveragePower', true);
data_bit_out = reshape((de2bi(dataSymbolsOut, 'left-msb')).',1,[]);
power_RE_receid = sum(sum(abs(RE_PreDeMod).^2)) / N_RB / N_SC_perRB / N_Symbol / N_Frame;
snr_all(iQorder,iEbN0,iloop) = 10*log10(power_RE/(power_RE_receid - power_RE)); %% Result: Ser and Ber
%Ser
sym_err = length(find(dataSymbolsOut - dataSymbolsIn));
ser_all(iQorder,iEbN0,iloop) = sym_err / length(dataSymbolsOut);
%Ber
bit_error = sum(abs(data_bit_out - data_bit_in));
ber_all(iQorder,iEbN0,iloop) = bit_error / length(data_bit_out);
end
sers = mean(ser_all,3);
snrs = mean(snr_all,3);
bers = mean(ber_all,3);
sers_theory(iQorder,iEbN0) = QAM_SER_Theory(Qm,EbN0); fprintf('%dQAM\t%f\t %f\t %f\t %e\t\t%e\t\t%e\t\t%d\t\n', Qm, EbN0, SNR,snrs(iQorder,iEbN0),sers(iQorder,iEbN0),sers_theory(iQorder,iEbN0),bers(iQorder,iEbN0),loopNumber);
end
end figure(1)
semilogy(EbN0_list, bers(1,:), 'k--+');
hold on
grid on
semilogy(EbN0_list, bers(2,:), 'r--o');
semilogy(EbN0_list, bers(3,:), 'b--x');
semilogy(EbN0_list, bers(4,:), 'g--s');
xlabel('Eb/N0,dB');
ylabel('BER');
title('BER VERS SNR');
legend('QPSK','16QAM','256QAM','1024QAM'); figure(2)
semilogy(EbN0_list, sers(1,:), 'k--+');
hold on
grid on
semilogy(EbN0_list, sers(2,:), 'r--o');
semilogy(EbN0_list, sers(3,:), 'b--x');
semilogy(EbN0_list, sers(4,:), 'g--s');
xlabel('Eb/N0,dB');
ylabel('SER');
title('SER VERS SNR');
%SML = simulation, THR = theory
legend('QPSK','16QAM','256QAML','1024QAM');

用到的信道与过信道代码

function taps = RayleighChanTaps(nTap)
taps= 1/sqrt(2)*1/sqrt(nTap)*(randn(nTap,1) + 1j*randn(nTap,1));
taps = taps./sum(abs(taps));
end
function taps = ExponentialChanTaps(SampRateMHz, delaySprdNsec)
sampTimeNsec = 1000 / SampRateMHz; if delaySprdNsec == 0
Kmax = 0;
vark = 1;
else
Kmax = ceil(10 * delaySprdNsec/sampTimeNsec);
var0 = 1 - exp(- sampTimeNsec /delaySprdNsec);
k = (0:Kmax)';
vark = var0 * exp( -k *sampTimeNsec/delaySprdNsec);
end
stdDevReOrIm = sqrt(vark/2);
taps = stdDevReOrIm .*(randn(Kmax +1,1) + 1j*randn(Kmax+1,1));
end
function yt = Multipath_channel(xt,taps)
ht = taps;
xht = conv(ht,xt);
%yt = xht(end - length(xt)+1:end);
yt = xht(1:length(xt));
end

仿真结果

瑞利信道下的仿真结果,设置抽头系数为2,仿真次数设置1000次曲线才会平滑。

在瑞利信道和白噪声下的仿真结果对比

结果略

一个感兴趣的点是固定信噪比时误码性能随多径的数量是如何变化的,先保证最大时延扩展没有超过CP的长度。

结论分析

瑞利信道下的误码率曲线近似为直线,(很奇怪,难以理解)

反思

OFDM系统各种QAM调制阶数在多径信道下的误码性能仿真(暂存版本)的更多相关文章

  1. DVB-C系统中QAM调制与解调仿真

    本文简单记录一下自己学习<通信原理>的时候调试的一个仿真DVB-C(Cable,数字有线电视)系统中QAM调制和解调的程序.自己一直是研究"信源"方面的东西,所以对&q ...

  2. 对正交频分复用OFDM系统的理解

    OFDM系统 正交频分复用OFDM(Orthogonal Frenquency Division Multiplexing)是一种多载波调制技术. 基本思想:在发送端,它将高速串行数据经过串并变换形成 ...

  3. 多用户OFDM系统资源分配研究

    首先,OFDMA 是什么? OFDM 技术的基本原理是将无线信道划分为若干互相正交的子信道,把高速串行数据流转化为低速并行子数据流,低速并行子数据流在子信道上独立传输. OFDMA 是LTE的下行多址 ...

  4. 小小知识点(八)——星座图与PSK、QAM调制的关系

    星座图是对PSK和QAM调制相位和幅度的一种表示,让我们只关注被调制参量本身,而不管已调信号波形及其频率. 在信号传输仿真时也一样,我们只关注携带信息的幅值和相位,而不管信号的传输波形和频率.这就是为 ...

  5. 系统吞吐量、TPS(QPS)、用户并发量、性能測试概念和公式

    PS:以下是性能測试的主要概念和计算公式,记录下: 一.系统吞度量要素: 一个系统的吞度量(承压能力)与request对CPU的消耗.外部接口.IO等等紧密关联.单个reqeust 对CPU消耗越高, ...

  6. 痞子衡嵌入式:系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败问题. 我们知道,i.MXRT1xxx家族早期型号(RT1050/ ...

  7. Django(博客系统):基于pycharm如何一个django工程下创建多个app

    背景:通常我们创建一个django系统时,为了把业务模块划分清楚往往会把一个独立的业务模块放到一个app中,如果多个独立的业务模块就会创建多个app,一般情况下为了更好的管理这些app,会把他们都存放 ...

  8. linux系统centOS7下搭建redis集群中ruby版本过低问题的解决方法

    问题描述: 在Centos7中,通过yum安装ruby的版本是2.0.0,但是如果有些应用需要高版本的ruby环境,比如2.2,2.3,2.4... 那就有点麻烦了,譬如:我准备使用redis官方给的 ...

  9. [漏洞分析]phpyun系统重装安全隐患#影响从phpyun4.2部分,4.3到4.5全版本

    0x00 之前在t00ls上看到的,漏洞原理很简单,但是都是细节问题,很值得去学习. 感谢bypass师傅. 也发了邮件给官方,但没有任何回复,估计是漏洞作者bypass师傅报备了吧.   0x01 ...

  10. 牛客网Java刷题知识点之File对象常用功能:获取文件名称、获取文件路径、获取文件大小、获取文件修改时间、创建与删除、判断、重命名、查看系统根目录、容量获取、获取某个目录下内容、过滤器

    不多说,直接上干货! 获取文件名称.获取文件路径.获取文件大小.获取文件修改时间 FileMethodDemo.java package zhouls.bigdata.DataFeatureSelec ...

随机推荐

  1. [转帖]使用 Crash 工具分析 Linux dump 文件

    前言 Linux 内核(以下简称内核)是一个不与特定进程相关的功能集合,内核的代码很难轻易的在调试器中执行和跟踪.开发者认为,内核如果发生了错误,就不应该继续运行.因此内核发生错误时,它的行为通常被设 ...

  2. CLion搭建Qt开发环境,并解决目录重构问题(最新版)

    序言 Qt版本不断更新,QtCreator也不断更新.在Qt4和Qt5时代,我一直认为开发Qt最好的IDE就是自带的QtCreator,可是时至今日,到了Qt6时代,QtCreator已经都12.0. ...

  3. 在Unity中使用SQLite保存配置表数据(For Lua)

    在Lua中使用sqlite Lua版本Sqlite文档:http://lua.sqlite.org/index.cgi/doc/tip/doc/lsqlite3.wiki sqlite官网:https ...

  4. 【二】AI Studio 项目详解【VisualDL工具、(二)环境使用说明、(二)脚本任务、图形化任务、在线部署及预测】PARL

    相关文章 [一]-环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简介 [五]-Sarsa&Qlear ...

  5. C/C++ 通过Socket 传输结构体

    本质上socket无法传输结构体,我们只有将结构体装换为字节数组,或者是字符串格式来传输,到了服务端在强制类型转换一下即可,下面的代码分别提供原生写法与通过boost的实现两种,直接改改,可用于收集目 ...

  6. 戴尔全球首款6K IPS Black显示器上市:配4K摄像头

    戴尔的全球首款6K IPS Black显示器--U3224KB,目前已经上架,价格为3199.99美元(约合人民币22186元). 据介绍,这款显示器采用IPS Black面板,刷新率为60Hz,对比 ...

  7. js转化文章发布于几天几小时几分钟前

    alert(dateFormat('2020-07-08 11:32:44')); function dateFormat(d1) { var dateEnd = new Date();//获取当前时 ...

  8. XmlDocument 解决 Clone、CloneNode、ImportNode 等节点克隆后的标签自闭合问题

    前言: 这两天在对 Taurus.Mvc 做 html 加载性能优化时,发现存在这个问题. 具体优化的是 CYQ.Data 组件的 XHtmlAction 相关类. 问题过程: 之前 XmlDocum ...

  9. Python 爬虫方法总结

    实现爬虫的套路 准备URL 准备start_url url地址规律不明显,总数不确定 通过代码提取下一页的url 通过xpath提取 寻找url地址,部分参数在当前的响应中(比如当前页码数和总页码数在 ...

  10. Apache HTTP Server、IIS反向代理设置

    Apache HTTP Server 在 Apache 中设置反向代理,需要使用 mod_proxy 和相关的模块,如 mod_proxy_http.以下是一个基本的配置示例: 确保已经安装并启用了  ...