OFDM同步技术

news2024/12/22 4:36:33

文章目录

  • 前言
  • 一、OFDM 同步技术
  • 二、MATLAB 仿真
    • 1、STO 估计技术
      • ①、核心源码
      • ②、仿真结果
    • 2、CFO 估计技术
      • ①、核心源码
      • ②、仿真结果
  • 三、资源自取


前言

本文对 OFDM 同步技术以思维导图的形式呈现,有关仿真部分进行了讲解实现。


一、OFDM 同步技术

OFDM 同步技术思维导图如下图所示,如有需求请到文章末尾端自取。
在这里插入图片描述

二、MATLAB 仿真

1、STO 估计技术

①、核心源码

%基于CP,采用最大相关和最小距离算法完成STO的估计

clear, figure(1), clf, figure(2), clf
nSTOs = [-3 -3 2 2];                % 对应 STO 的采样数  提前、提前、滞后、滞后
CFOs = [0 0.5 0 0.5];               % CFO 向量
SNRdB = 30;                         % SNR
MaxIter = 10;                       % 迭代次数
%CFOs = [0 0 0 0];
Nfft = 128;                         % FFT 大小
Ng = Nfft/4;                        % GI 长度
Nofdm = Nfft + Ng;                  % OFDM 符号长度
Nbps = 2;                           % 2/4 对应 QPSK/16QAM 
M = 2^Nbps;                         % 符号对应的可能性数量
Es = 1; 
A = sqrt(3/2/(M-1)*Es);             % QAM 归一化因子
N = Nfft; 
com_delay = Nofdm/2;                % 公共时延
Nsym = 100;                         % 一共有一百个 OFDM 符号
rand('seed',1);                     % 设置种子
randn('seed',1);
for i = 1:length(nSTOs)             % 对于每一个不同的 \delta STO
   nSTO = nSTOs(i);  
   CFO = CFOs(i);
   x = [];                          % 初始化信号块,最后 x 就是发送出来的 OFDM 模块
   for m = 1:Nsym % 随机位生成 
      msgint=randi([0 M-1], 1, N);  % 生成传输符号,1*128 个 0-3 的数
      Xf = A .* qammod(msgint, M, 'UnitAveragePower', true);% 调制成复数
      %***********************缺少了倒置的过程***********************%
      xt = ifft(Xf, Nfft);          % 发送
      x_sym = add_CP(xt, Ng);       % 加 CP
      x = [x x_sym];
   end
   %*********************** 信道 ************************%
   %%%%%在这里根据需求添加信道,先假设是没有信道
   y = x;  % 没有信道影响
   
   sig_pow = y*y' / length(y);          % 计算能量,sig_pow= mean(mean(y.*conj(y),2))
   
   % 频率偏移 + 符号定时偏移 
   y_CFO = add_CFO(y, CFO, Nfft);       % 加 CFO
   y_CFO_STO = add_STO(y_CFO, -nSTO);   % 加STO,这是加在整个信号上的,因此头尾补零就行了;但是取-是因为:δ<0 是提前,δ>0是滞后
   v_ML = zeros(1, Ng);                 % 初始化
   v_Cl = zeros(1, Ng);
   Mag_cor = 0;                         % arg的结果
   Mag_dif = 0;
   %%添加加性高斯白噪声
   for iter = 1:MaxIter
      % 加噪声
      y_aw = awgn(y_CFO_STO, SNRdB, 'measured');
      
      %%%%%%%符号定时获取
      [STO_cor, mag_cor] = STO_by_correlation(y_aw, Nfft, Ng, com_delay);               % 书中自带
      [STO_cor_temp,mag_cor_temp] = STO_by_correlation_sim1(y_aw,Nfft,Ng,com_delay);    % 我自己编写
      %%%%%经验证,以上两者函数结果一致
      
      
      [STO_dif,mag_dif] = STO_by_difference(y_aw,Nfft,Ng,com_delay); %书中自带
      [STO_dif_temp,mag_dif_temp] = STO_by_difference_sim1(y_aw,Nfft,Ng,com_delay); %我自己编写
      %%%%%经验证,以上两者函数结果一致
      % 计数
      % 这里取反了,返回了符合"左加右减"的直觉的STO
      v_ML(-STO_cor+Ng/2)= v_ML(-STO_cor+Ng/2)+1;
      v_Cl(-STO_dif+Ng/2)= v_Cl(-STO_dif+Ng/2)+1;
      Mag_cor= Mag_cor + mag_cor;
      Mag_dif= Mag_dif + mag_dif;
   end % End of for loop of iter
   %%%%%%% Probability
   v_ML_v_Cl = [v_ML; v_Cl]*(100/MaxIter);      % 取百分数
   figure(1+i-1); 
   set(gca,'fontsize',9);   % 将当前坐标轴的字体大小设置为9
%    subplot(220+i)
    
   bar(-Ng/2+1:Ng/2,v_ML_v_Cl');
   hold on, grid on
   str = sprintf('nSTO Estimation: nSTO=%d, CQFO=%1.2f, SNR=%3d[dB]',nSTO,CFO,SNRdB);           
   title(str); 
   xlabel('Sample'), ylabel('Probability');
   legend('ML','Classen'); 
   axis([-Ng/2-1 Ng/2+1 0 100])
   %%%%%%% Time metric
   Mag_cor = Mag_cor/MaxIter; 
   [Mag_cor_max,ind_max] = max(Mag_cor);
   nc= ind_max-1-com_delay;
   Mag_dif = Mag_dif/MaxIter; 
   [Mag_dif_min,ind_min] = min(Mag_dif);
   nd= ind_min-1-com_delay
   nn= -Nofdm/2 + [0:length(Mag_cor)-1];  % -80~79
%   nt= nSTO;
%    figure(2);
%    subplot(220+i);
   figure(5+i-1); 
   plot(nn,Mag_cor,nn,1.5*Mag_dif,'r:','markersize',1);
   hold on
     
   stem(nc,Mag_cor_max,'b','markersize',5);
   stem(nSTO,Mag_cor(nSTO+com_delay+1),'k.','markersize',5); % Estimated/True Maximum value
   str1 = sprintf('STO Estimation - ML(b-)/Classen(r:) for nSTO=%d, CFO=%1.2f',nSTO,CFO); %,SNRdB);
   title(str1); 
   xlabel('Sample'), ylabel('Magnitude'); 
 
   %stem(n1,Mag_dif_min,'r','markersize',5)
   stem(nd,Mag_dif(nd+com_delay+1),'r','markersize',5);
   stem(nSTO,Mag_dif(nSTO+com_delay+1),'k.','markersize',5); % Estimated/True Minimum value
   set(gca,'fontsize',9, 'XLim',[-32 32], 'XTick',[-10 -3 0 2 10]); %, xlim([-50 50]),
   legend('基于相关的','基于差值最小的'); 
end % End of for loop of i

完整源码文末自取

②、仿真结果

在这里插入图片描述
在这里插入图片描述

由上两个图所示,当 STO = -3,CFO = 0时,可以看到基于差值最小的方法估计的 STO 更为准确。
在这里插入图片描述
在这里插入图片描述
由上两个图所示,当 STO = -3,CFO = 0.5时,可以看到基于差值最小的方法和基于相关估计的 STO 都很准确。
在这里插入图片描述
在这里插入图片描述
由上两个图所示,当 STO = 2,CFO = 0 时,可以看到基于差值最小的方法和基于相关估计的 STO 都很准确。
在这里插入图片描述
在这里插入图片描述
由上两个图所示,当 STO = 2,CFO = 0.5 时,可以看到基于差值最小的方法估计的 STO 更为准确。

2、CFO 估计技术

①、核心源码

%完成时域基于CP的方法和频域的Moose/Classen方法,用于后续CFO补偿
clear, clf
CFO = 0.15;                     % CFO(载波频率偏移)大小
% CFO = 0;
Nfft=128;                       % FFT采样数  
Nbps=2;                         % QPSK或QAM
M=2^Nbps;                       % 每个符号代表几比特
Es=1;                           % 能量
A=sqrt(3/2/(M-1)*Es);           % QAM归一化
N=Nfft;                         % 发送的符号长度,为了方便,和Nfft保持一致
Ng=Nfft/4;                      % GI长度
Nofdm=Nfft+Ng;                  % 一个OFDM符号的长度
Nsym=3;                         % 一共发送了3个OFDM符号,前两个是导频,最后一个是真正发送的数据符号
% h=complex(randn,randn)/sqrt(2);
% %h=[1 zeros(1,5)]; 
% channel(h,0);  
%Transmit signal
x=[];
for m=1:Nsym                    % 前两个是导频,最后一个是真正发送的数据符号
   msgint=randi([0 M-1],1,N);   % 生成要发送的符号

   if m<=2                      % 
       Xp = add_pilot(zeros(1,Nfft),Nfft,4);    % 生成导频
       Xf=Xp; % add_pilot
   else  %Xf= QAM(msgint((i-1)*N+1:i*N),Nbps);  % constellation mapping. average power=1        
       Xf = A.*qammod(msgint,M,'UnitAveragePower',true);
   end                                      
   xt = ifft(Xf,Nfft);          % ifft  
   x_sym = add_CP(xt,Ng);       % 加CP
   x= [x x_sym];                % 将三个OFDM符号依次拼接
end    

%channel 可添加所需信道
y=x; % No channel effect

%Signal power calculation
sig_pow= y*y'/length(y); % Signal power calculation

%%%%
SNRdBs= 0:3:30;  
% SNRdBs= 100; 设100是为调试程序  
MaxIter = 100;  
for i=1:length(SNRdBs)
   SNRdB = SNRdBs(i);
   MSE_CFO_CP = 0; 
   MSE_CFO_Moose = 0; 
   MSE_CFO_Classen = 0;
   rand('seed',1);              % 设置种子来保证每次仿真结果一致
   randn('seed',1);
   y_CFO= add_CFO(y,CFO,Nfft);  % 增加CFO,此处是在时域添加的,因此是×相位
   % 多次迭代取平均
   for iter=1:MaxIter
      %y_aw=add_AWGN(y_CFO,sig_pow,SNRdB,'SNR',Nbps);  % AWGN added, signal power=1
      y_aw = awgn(y_CFO,SNRdB,'measured');              % 增加高斯白噪声
      
      Est_CFO_CP = CFO_CP(y_aw,Nfft,Ng); % CP-based     % 根据CP测算CFO
      MSE_CFO_CP = MSE_CFO_CP + (Est_CFO_CP-CFO)^2;     % 平方累计
      
      Est_CFO_Moose = CFO_Moose(y_aw,Nfft);             % Moose估计
      MSE_CFO_Moose = MSE_CFO_Moose + (Est_CFO_Moose-CFO)^2;% 平方累计
      
      Est_CFO_Classen = CFO_Classen(y_aw,Nfft,Ng,Xp); % Classen (Pilot-based)
      MSE_CFO_Classen = MSE_CFO_Classen + (Est_CFO_Classen-CFO)^2;
      
   end % the end of for (iter) loop
   MSE_CP(i) = MSE_CFO_CP/MaxIter; 
   MSE_Moose(i) = MSE_CFO_Moose/MaxIter;  
   MSE_Classen(i) = MSE_CFO_Classen/MaxIter;
end%ebn0 end    
semilogy(SNRdBs, MSE_CP,'-+');
grid on, hold on
semilogy(SNRdBs, MSE_Moose,'-x'); semilogy(SNRdBs, MSE_Classen,'-*');
xlabel('SNR[dB]'), ylabel('MSE'); title('CFO Estimation'); %axis([0 30 10e-8 10e-2])
% str=sprintf('CFO = %1.2f',CFO);
legend('CP-based technique','Moose (Preamble-based)','Classen (Pilot-based)');
% legend(str);

完整源码文末自取

②、仿真结果

在这里插入图片描述
可以观察到,随着接收信号的 SNR 增大,CFO 估计的 MSE 减小。估计技术的性能取决于用于 CFO 估计的 CP 中的采样数、前导数和导频数。

三、资源自取

链接:OFDM同步技术

在这里插入图片描述


我的qq:2442391036,欢迎交流!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1620888.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GitHub】github学生认证,使用copilot教程

github学生认证并使用copilot教程 写在最前面一.注册github账号1.1、注册1.2、完善你的profile 二、Github 学生认证 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&a…

手机误删照片如何恢复?怎么快速有效找回照片?

现在手机的功能越来越强大&#xff0c;手机厂家不断内卷&#xff0c;拍照功能越来越强&#xff0c;我们已经习惯用手机来记录生活了&#xff0c;因此储存的照片都特别珍贵&#xff0c;一旦误删&#xff0c;就容易造成不可磨灭的损失。那么手机误删照片如何恢复&#xff1f;本文…

三招教你成为朋友圈运营高手,赶紧get起来!

朋友圈作为一个重要的营销推广渠道&#xff0c;是能够为我们带来很多收益的。今天就给大家分享朋友圈运营的三个技巧&#xff0c;快快Get起来吧&#xff01; 第一招&#xff1a;明确人设定位 要在朋友圈里脱颖而出&#xff0c;首先我们需要明确自己的人设定位。选择一个与自己…

小美打怪(动态规划)

小美在玩游戏&#xff0c;游戏中有 n 个怪物&#xff0c;怪物的血量为 h&#xff0c;攻击力为 ai​。小美的血量为 H&#xff0c;攻击力为 A&#xff0c;小美可以击败血量和攻击力都小于自己的怪物&#xff0c;并且打败后血量降为怪物的血量&#xff0c;攻击力降为怪物的攻击力…

react实现时钟翻牌效果

需求&#xff1a;随着数字的变动要求有时钟翻动动效 问题&#xff1a;只在加载时有动效 解决方案&#xff1a;通过判断数字改变&#xff08;这里通过新旧数值变动来判断&#xff0c;不贴代码啦&#xff09;&#xff0c;每次变动的时候手动把animationIterationCount设置为inf…

git 重命名文件,提交后,此文件的提交记录丢失

零、问题现象&#xff1a; 文件重命名后&#xff0c;提交到 git 仓库&#xff0c;发现重命名操作 变成 删除旧文件&#xff0c;新增一个新文件&#xff0c;原来文件的提交记录丢失&#xff0c;看不到了。 一、正确的重命名提交方法 1.1、 先执行add命令来将修改内容后的文件…

什么是行子查询(Row Subqueries)?

什么是行子查询&#xff08;Row Subqueries&#xff09;&#xff1f; 行子查询&#xff0c;也称为行构造子查询&#xff0c;是SQL中的一种子查询形式&#xff0c;它返回单个行而不仅仅是单个字段的值。这意味着&#xff0c;与标准的标量或列子查询不同&#xff0c;行子查询可以…

解构海洋缺氧:浙大 GIS 实验室融合机器学习及卫星测绘,发布全球海表溶解氧综合建模框架

多年前&#xff0c;海洋专家 Eric Prince 在进行鱼类标记追踪时发现了一个异常现象&#xff1a;蓝色马林鱼在美国东南部通常会下潜至 800 米的深海捕食&#xff0c;而在哥斯达黎加海域却只在海洋表层活动。作为潜水行家的马林鱼&#xff0c;为什么突然不潜水了呢&#xff1f; 长…

【k8s】Kubernetes 1.29.4离线安装部署(总)

&#xff08;一&#xff09;kubernetes1.29.4离线部署之-安装文件准备 &#xff08;二&#xff09;kubernetes1.29.4离线部署之-镜像文件准备 &#xff08;三&#xff09;kubernetes1.29.4离线部署之-环境初始化 &#xff08;四&#xff09;kubernetes1.29.4离线部署之-组件安装…

Educational Codeforces Round 164 (Rated for Div. 2) A-E

A. Painting the Ribbon 暴力模拟即可 #include <bits/stdc.h>using namespace std; const int N 2e5 5; typedef long long ll; typedef pair<ll, ll> pll; typedef array<ll, 3> p3; // int mod 998244353; const int maxv 4e6 5; // #define endl &…

Maven的基础使用

1 Maven概述 引入案例&#xff1a;idea创建javaWeb项目&#xff0c;如何打包并发布tomcat上去&#xff0c;以便于客户端访问&#xff1f; 方案一&#xff1a;DOS命令完成打包&#xff0c;操作性不方便&#xff0c;代码频繁修改&#xff0c;频繁使用命令打包一阶段可以打包&am…

SHELL脚本(全是干货)

一、shell是什么&#xff1f; 1. 1 shell 是一种脚本语言 脚本语言的本质是一个文件&#xff0c;文件里面存放的是特点格式的指令&#xff0c;系统可以使用脚本解析器翻译或者解析指令&#xff0c;并且执行&#xff08;它不需要编译&#xff09; shell 即是应用程序&#xff…

【Linux】Linux权限管理详解

&#x1f331;博客主页&#xff1a;青竹雾色间 &#x1f331;系列专栏&#xff1a;Linux &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 目录 1. Linux权限概念2. 文件访问者分类a) 文件和目录的访问者&#xff1a;b) 文件类型和访问权限 3. 文件权限值的表…

Linux的磁盘分区,格式化,挂载

1.需要提前添加几个磁盘&#xff0c;以做实验 2.把nvme0n2磁盘用来分区实验 3.分了一个主分区&#xff0c;和一个扩展分区&#xff08;扩展分区是不能使用的&#xff0c;所以又在扩展分区里分了一个逻辑分区&#xff09;分区的大小自己定义 4.格式化分出来的区&#xff0c;这…

xgp怎么注册阿根廷账号 微软商店xgp阿根廷账号注册教程

xgp怎么注册阿根廷账号 微软商店xgp阿根廷账号注册教程 xgp游戏平台是微软公司针对pc用户开发的一款游戏平台&#xff0c;在平台内有着知名的月包服务&#xff0c;玩家们只需每个月支付固定的费用&#xff0c;即可免费玩到不同的游戏大作&#xff0c;xgp平台也正是由月包服务…

1.C++入门(下)

目录 1.引用和指针 2.内联函数 2.1 概念&#xff1a; 2.2 特性&#xff1a; 2.3 与宏对比 3.auto关键字 3.1 简介&#xff1a; ​3.2 使用&#xff1a; 3.3 局限 4.基于范围的for循环 1.引用和指针 因为这个面试中常考&#xff0c;就接着上一篇&#xff0c;把这个放…

Linux 底软开发——对CAN的详细操作(周期发送,异常检测,过滤报文)

Linux底软开发—对CAN发送接收详细操作 文章目录 Linux底软开发—对CAN发送接收详细操作1.保证多条CAN数据发送的周期性2.解析CAN报文数据3.CAN总线异常机制应对4.对CAN报文进行过滤操作5.完整的接收报文代码&#xff08;过滤&#xff0c;心跳检测&#xff0c;解析&#xff09;…

刚刚,百度真来炸场了!

文章目录 前言再看文心智能体开发工具&#xff1a;AgentBuilderAI原生应用开发工具&#xff1a;AppBuilder各种尺寸的模型定制工具&#xff1a;ModelBuilder结语 前言 不知道大家还记得不&#xff0c;去年 ChatGPT 火遍全球的时候&#xff0c;国内率先推出 AI 大模型的是百度家…

【热门话题】AI作画算法原理解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 AI作画算法原理解析AI作画算法概述基础原理&#xff1a;机器学习与深度学习卷积…

再谈C语言——理解指针(四)

assert断⾔ assert.h 头⽂件定义了宏 assert() &#xff0c;⽤于在运⾏时确保程序符合指定条件&#xff0c;如果不符合&#xff0c;就报错终⽌运⾏。这个宏常常被称为“断⾔”。 assert(p ! NULL); 上⾯代码在程序运⾏到这⼀⾏语句时&#xff0c;验证变量 p 是否等于 NULL 。…