OFDM仿真程序,可直接运行,注释详细(没人注释比我还详细了)

OFDM仿真程序

clc
clear allIFFT_bin_length=128; %IFFT点数128个
carrier_count=50;  %子信道(子载波)数目
bits_per_symbol=2; %4进制符号
symbols_per_carrier=200;%每个子信道或者说子载波有200个符号
SNR=0:1:40;
for num=1:41baseband_out_length=carrier_count*symbols_per_carrier*bits_per_symbol; %总bit数
%下面是载波位置,为了满足得到的是实数信号,载波的位置要满足共轭对称
carriers=(1:carrier_count)+(floor(IFFT_bin_length/4)-floor(carrier_count/2)); %floor函数是朝负无穷大四舍五入
conjugate_carriers=IFFT_bin_length-carriers+2;%baseband_out=round(rand(1,baseband_out_length));%200000-1信源符号,round函数为四舍五入为最近的小数
baseband_out=randi(2,1,baseband_out_length)-1;   %返回一个介于12之间的1*20000的数组
%将一行20000的数据交叉转换为210000的数据
convert_matrix=reshape(baseband_out,bits_per_symbol,length(baseband_out)/bits_per_symbol);
%不如写个函数将值映射成0-3,如00-001-110-211-3
for k=1:(length(baseband_out)/bits_per_symbol)modulo_baseband(k)=0;for i=1:bits_per_symbolmodulo_baseband(k)=modulo_baseband(k)+convert_matrix(i,k)*2^(bits_per_symbol-i);end
end%串并转换
%将本次的模4的串行数据流转换为并行数据流,其中,每行整体是一个OFDM符号,每一个OFDM符号由所有载波在该采样点叠加产生,每列代表一个子载波
carrier_matrix=reshape(modulo_baseband,symbols_per_carrier,carrier_count);%采用了差分相移键控调制
carrier_matrix=[zeros(1,carrier_count);carrier_matrix];%补了一行全0,作为编码的参考起点
for i=2:(symbols_per_carrier+1)carrier_matrix(i,:)=rem(carrier_matrix(i,:)+carrier_matrix(i-1,:),2^bits_per_symbol); %rem函数是除后的余数
end%将差分编码转换为相位变化
carrier_matrix=carrier_matrix*((2*pi)/(2^bits_per_symbol));%将相位转换为一个复数
%这句代码保证幅值都是1
[X,Y]=pol2cart(carrier_matrix,ones(size(carrier_matrix,1),size(carrier_matrix,2)));
%构造映射,将相位的值转换为极坐标上的一个复数点0-1,pi/2-j.pi--1,3pi/2--j
complex_carrier_matrix=complex(X,Y);%将每个子载波分配到之前定义好的IFFT输入端,根据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);%画出未经过IFFT的离散幅度谱,总共有50+50个输入端有数据,所以频谱图显示为两个矩形形状
% 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]);xlabel('IFFT BIN');ylabel('Magnitude');
% title('OFDM Carrier Frequency Magnitude');
%画出未经过IFFT的离散相位谱
% figure(2)
%所有128个点的相位图
% plot(0:IFFT_bin_length-1,(180/pi)*angle(IFFT_modulation(2,1:IFFT_bin_length)),'go');
% hold on;
%带数据的100个点的相位图
% 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');xlabel('IFFT Bin');
% title('OFDM Carrier Phase');%IFFT变换
time_wave_matrix=ifft(IFFT_modulation,[],2);%对列进行离散傅里叶反变换
%time_wave_matrix=time_wave_matrix;%作图
figure(3)
plot(0:IFFT_bin_length-1,time_wave_matrix(2,:));
grid on;
ylabel('幅度');xlabel('时间');
title('一个OFDM符号时域信号波形图');%colors=['r' 'g' 'b' 'k']
%for f=1:4%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,colors(f));%hold on;
%end
%grid on;ylabel('幅度');xlabel('时间');title('分离出的时域波形');% 添加一个窗函数,就是滤波器,减弱信号的不连续点
% 每一个时间波形表示所有载波的一个符号周期
% 因为时域矩阵中所有虚部都等于0,所以利用Hamming窗时,只保留实部用于加窗
for i=1:symbols_per_carrier+1windowed_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(time_wave_matrix,1,IFFT_bin_length*(symbols_per_carrier+1));%作图
% temp_time=IFFT_bin_length*(symbols_per_carrier+1);
% figure(5)
% plot(0:temp_time-1,ofdm_modulation);
% grid on;
% ylabel('幅度');xlabel('时间(采样)');title('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('幅度(dB)');xlabel('标准化频率(0.5=fs/2)');
% title('OFDM 信号频谱');
Tx_data=ofdm_modulation;%上变频,不一定用得到%经过信道
Rx_data=awgn(Tx_data,SNR(num));
% Rx_data=Tx_data;%%%%%%%%%%%%%%%%%%接收端%%%%%%%%%%%%%%%%%%%%%%%%%串并转换
Rx_data_matrix=reshape(Rx_data,symbols_per_carrier+1,IFFT_bin_length);%FFT变换
Rx_spectrum=fft(Rx_data_matrix,[],2);%经过FFT的频域相应图
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('幅度');xlabel('FFT Bin');
title('OFDM 接收频谱,幅度');
% figure(8)
% plot(0:IFFT_bin_length-1,(180/pi)*angle(Rx_spectrum(1:IFFT_bin_length)),'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('相位谱');xlabel('FFT Bin');
% title('OFDM 接受信号相位谱');%128中真正含有数据的50个载波提取出来
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,'rd');%对每个FFT点,解映射出对应的相位值
Rx_phase=angle(Rx_carriers)*(180/pi);
phase_negative=find(Rx_phase<0);
Rx_phase(phase_negative)=rem(Rx_phase(phase_negative)+360,360);%将负的相位对应为0-2pi内的值%从差分相移编码中,提取相位差值,这里利用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);%解映射,将不同的相位转换为0-3的信源符号,0的相位范围为-45451的相位范围为45-135,依此类推
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
%Rx_decoded_symbols=Rx_decoded_symbols';
%并串转换
Rx_serial_symbols=reshape(Rx_decoded_symbols,1,size(Rx_decoded_symbols,1)*size(Rx_decoded_symbols,2));%4进制的符号解码为二进制符号
for i=bits_per_symbol:-1:1if i~=1Rx_binary_matrix(i,:)=rem(Rx_serial_symbols,2);Rx_serial_symbols=floor(Rx_serial_symbols/2);elseRx_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(num)=size(bit_errors,2);
BER(num)=bit_error_count(num)/baseband_out_length;
end
figure(10)
semilogy(SNR,BER,'-ob','MarkerFaceColor','b','MarkerSize',5,'LineWidth',2);hold on;grid on;
title('DPSK-OFDM信噪比与误码率曲线');xlabel('SNR(dB)');ylabel('BER');
plot([0 35],[3.8e-3,3.8e-3],'r','LineWidth',1);hold on;
legend('DPSK-OFDM','FEC(3.8x10^-^3)');

在这里插入图片描述

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

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

相关文章

Delta-Sigma调制(DSM)技术

前言 数字信号处理和通信系统的性能很大程度上受到了模拟信号到数字信号转换接口——ADC的精度和分辨率的限制。而传统的线性脉冲编码调制&#xff08;PCM&#xff09;ADC受到了制造工艺的限制&#xff0c;无法达到很高的分辨率。但基于Delta-Sigma调制技术的ADC可以在现有工艺…

无载波幅度和相位调制(CAP)与QAM调制的详细解析(可见光通信应用场景),以及CAP matlab程序下载链接

文章目录前言一、QAM调制&#xff1f;二、无载波幅度和相位调制&#xff08;CAP)三、CAP调制与QAM调制之间的联系&#xff08;异同点&#xff09;四、CAP调制相比于QAM调制的优缺点4.1、优点4.2、缺点五、无载波幅度和相位调制matlab程序五、Reference前言 目前的通信系统中&a…

jpa 事务嵌套事务_JPA 2 | EntityManagers,事务及其周围的一切

jpa 事务嵌套事务介绍 对我来说&#xff0c;最令人困惑和不清楚的事情之一是&#xff0c;作为Java开发人员&#xff0c;一直是围绕事务管理的谜团&#xff0c;尤其是JPA如何处理事务管理。 事务什么时候开始&#xff0c;什么时候结束&#xff0c;实体的持久化方式&#xff0c;持…

Matlab中装载和存储实验数据的操作

一、装载实验数据 例如&#xff0c;以下程序&#xff0c;其中path是路径&#xff0c;strcat函数将后面的参数组合成一个字符串。load函数将由twoband_CAP4_400MBd_2000MSa_float_字符串与Tx.txt构成的: twoband_CAP4_400MBd_2000MSa_float_Tx.txt文件读取至matlab中。 numSam…

无服务器革命:好,坏和丑

“这是愚蠢的。 比愚蠢还糟&#xff1a;这是一场营销炒作。” ‐ 理查德斯托曼 &#xff08; Richard Stallman&#xff09;对云计算的评论&#xff0c;2008年9月 而且&#xff0c;十年后&#xff0c;当有人提到这个词时&#xff0c;您开始三思而后行&#xff1a;是到天上掉的…

MATLAB中,信号的频谱图该怎么绘制?横坐标如何标注出频率值?

一、什么是频谱&#xff1f; 频谱的全称是频率谱密度。在对时域信号进行认识和研究的过程中非常不便&#xff0c;那我们该如何更直观地认识信号&#xff0c;更清楚地了解信号的特点呢&#xff1f; 利用傅里叶变换将时域信号变换到频域。 我们知道&#xff0c;在通信领域里傅…

Verilog HDL中模块参数传递的方法

文章目录前言一、参数传递二、参数传递方法1.方法一2.方法二3.方法三总结前言 “parameter”是Verilog HDL中的一个关键字&#xff0c;代表着参数型常量&#xff0c;即用parameter来定义一个标识符代表一个常量&#xff0c;这样可以提高程序的可读性与可维护性。 例如&#xf…

仔细看看_仔细看看,您会发现需要改进的地方

仔细看看我建议您做一个练习&#xff1a;明天早上返回工作时&#xff0c;浏览项目的源代码&#xff0c;并尝试寻找重构的机会。 即使老板没有要求也要这样做。 这样做是因为您想要一些激动人心的工作时间。 重构是改变已经可以正常工作的艺术 。 但是要进行重构&#xff0c;您…

Verilog HDL中位运算符、逻辑运算符和缩减运算符的区别

文章目录前言一、单目运算符、双目运算符和三目运算符二、位运算符三、逻辑运算符四、缩减运算符五、总结前言 我们在学习和理解Verilog HDL中的一些运算符的意义时&#xff0c;可能会对一些运算符的使用产生混乱&#xff0c;因此本文整理了Verilog HDL中&与&&、|…

Verilog HDL中容易生成锁存器的两种情况

在Verilog HDL的程序设计中&#xff0c;有两种情况会生成锁存器。 第一种情况 在always块中使用if语句&#xff0c;但是没有else&#xff0c;这会导致当条件不成立时&#xff0c;没有其他语句可执行&#xff0c;使得被赋值的寄存器一直保持不变&#xff0c;”锁存“住。 第二…

Spring Security与Maven教程

1.简介 在这篇文章中&#xff0c;我们将演示如何针对非常特定的用例将Maven依赖项用于Spring Security。 我们使用的所有库的最新版本都可以在Maven Central上找到。 在项目中&#xff0c;了解Maven依赖项的工作方式和管理方式对于有效的构建周期非常重要&#xff0c;并且对于…

EbN0、SNR、0.1nmOSNR的区别与联系

文章目录前言一、SNR与EbN0二、0.1nmOSNR1、波长宽度与带宽的换算2、0.1nmOSNR2.1、单极化信号2.2、双极化信号总结前言 无论是无线通信、光通信或者可见光通信系统中&#xff0c;我们经常会遇到信噪比的概念&#xff0c;但大多数&#xff0c;我们用的都是信号与噪声功率比&am…

利用Verilog HDL实现序列检测器,附上仿真程序。

文章目录一、序列检测器二、状态转移图三、序列检测器Verilog HDL程序1、源程序2、测试平台程序四、仿真结果五、总结一、序列检测器 序列检测器的逻辑功能就是将一个指定的比特序列从一串较长的比特流中识别出来。 例如&#xff1a;针对一个较长的比特流01001001001111010101…

在Java中使用Google的协议缓冲区

最近发布了 有效的Java第三版 &#xff0c;我一直对确定此类Java开发书籍的更新感兴趣&#xff0c;该书籍的最新版本仅通过Java 6进行了介绍 。 在此版本中&#xff0c;显然有与Java 7 &#xff0c; Java 8和Java 9密切相关的全新项目&#xff0c;例如第7章&#xff08;“ Lamb…

不同阶QAM调制星座图中,符号能量的归一化计算原理

文章目录前言一、归一化能量计算原理二、Matlab中如何得到归一化能量符号总结前言 在基于QAM调制的matlab仿真程序中&#xff0c;我们通常会产生二进制比特流&#xff0c;并最终映射成QAM符号&#xff0c;该符号大都是格雷编码的。在坐标系中&#xff0c;相邻符号之间的横纵坐…

4qam、16qam、64qam、256qam理论仿真曲线

本博文给出了4qam、16qam、64qam、256qam理论仿真曲线&#xff0c;画出了EbN0 vs BER的曲线图&#xff0c;可以作为大家学习的一个参考。 仿真结果: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Theoretical ber curves of different orde…

建立时间、保持时间与亚稳态

文章目录一、建立时间与保持时间二、亚稳态现象总结一、建立时间与保持时间 建立时间&#xff08;set up time&#xff09;是指在触发器的时钟信号上升沿到来以前&#xff0c;数据从不稳定到稳定所需要的时间&#xff0c;一般用TsuT_{su}Tsu​表示。 保持时间是指在触发器的时…

java ee空指针_Java EE 7是最终版本。 思想,见解和进一步的指针。

java ee空指针我们花了不到三年的时间才推出了下一个Java EE版本 。 今年4月16日&#xff0c; JCP EC对JSR 342进行了投票并获得批准。 这是一个成功的故事&#xff0c;因为在去年八月下旬的最后时刻撤消了拥有云就绪平台的最初想法。 作为EG的成员&#xff0c;撰写即将发布的功…

Java的原始字符串文字

似乎“ 原始字符串文字 ”即将出现在Java中。 JEP 326开始的&#xff08;“原始字符串字面量”&#xff09; 发行JDK-8196004 &#xff0c;并宣布为“新JEP候选人” 3月2日的JEP和相关问题的人指出&#xff0c;“Java的仍然是一小群现代编程语言中的一个不为原始字符串提供语言…

Java可能使用UTF-8作为其默认字符集

由于基于Java的应用程序通常用于各种各样的操作系统和环境中&#xff0c;因此Java开发人员经常会遇到与基于字符的输入和输出有关的问题 。 涉及这些问题的博客文章包括《警察的恐怖&#xff1a;默认语言环境&#xff0c;默认字符集和默认时区》 &#xff1b; 注释JDK默认数据 …