概述
最近看到网上很多人在做基本的数字信号调制解调仿真时候用到了T2F/F2T/lpf.m这三个流传甚广的函数,这三个函数在信号解调部分组成了一个抽样判决前的低通滤波器,以前我也直接调用过,但是今天打开函数一看,还是发现了点问题,先看看T2F函数:
1. T2F.m
function [f,sf]= T2F(t,st)
%Input is the time and the signal vectors,the length of time must greater
%than 2
%Output is the frequency and the signal spectrum
dt = t(2)-t(1);
T=t(end);
df = 1/T;
N = length(st);
f=-N/2*df : df : N/2*df-df;
sf = fft(st);
sf = T/N*fftshift(sf);
T2F.m其实就是计算输入序列的FFT,输入参数为时间序列t和信号序列st,返回值为频率序列f和对应的幅值sf。函数先计算了时间采样间隔dt,然后将时间序列t的最后一位(截至时刻)赋值给了T,接着定义频率采样间隔df=1/T,采样点数N,然后进行N点的fft变换→定义频率序列→调用fftshift。
正常来说,大部分人编写信号,时间序列的起始为0时刻,这样的话T=t(end)=(N-1)dt。这种情况下该函数在定义频率采样间隔时:df=1/T=1/(N-1)/dt.很明显该结果是错误的,因为采样频率fs=1/dt,df=fs/N=1/N/dt。
这样会使得当设计的信号采样点数减小的情况下,计算的频谱产生很大的偏差。(但是如果输入信号时间序列的起始为dt时刻的话,调用该函数是正确的,但这种情况应该比较少吧)
将该函数稍作修改就能用啦,如下(fftshift前面的系数没什么用我就删了):
function [f,sf]= T2F1(t,st)
%需满足时刻起始点为0
%Input is the time and the signal vectors,the length of time must greater
%than 2
%Output is the frequency and the signal spectrum
dt = t(2)-t(1);
T=t(end);
df = 1/(T+dt);
N = length(st);
f=-N/2*df : df : N/2*df-df;
sf = fft(st);
sf = fftshift(sf);
2. lpf.m
function [t,st]=lpf(f,sf,B)
%This function filter an input data using a lowpass filter
%Inputs: f: frequency samples
% sf: input data spectrum samples
% B: lowpass bandwidth with a rectangle lowpass
%Outputs: t: time samples
% st: output data time samples
df = f(2)-f(1);
T = 1/df;
hf = zeros(1,length(f));
bf = [-floor( B/df ): floor( B/df )] + floor( length(f)/2 );
hf(bf)=1;
yf=hf.*sf;
[t,st]=F2T(f,yf);
st = real(st);
接着看lpf.m函数,调用这个函数要输入参数为频率序列f,对应的幅值sf,矩形低通滤波器截至频率B。采样频率间隔df,然后计算T(显然也有问题,但是该赋值后续并没有使用,因此不管它),hf为长度与f相同的全零序列,而bf显然是想计算f中对应低通频段的位置。我们知道f中第位表示的是直流(f=0),那么bf的表达式里少加了一个1。而且floor是向下取整,我们应该改为fix,即向0取整。最后一行取实部也应该不必要,如果原始的时间序列是实的,那么st也是实序列。
修改后的函数如下:
function [t,st]=lpf1(f,sf,B)
%This function filter an input data using a lowpass filter
%Inputs: f: frequency samples
% sf: input data spectrum samples
% B: lowpass bandwidth with a rectangle lowpass
%Outputs: t: time samples
% st: output data time samples
df = f(2)-f(1);
T = 1/df;
hf = zeros(1,length(f));
bf = [-fix( B/df ): fix( B/df )] + floor( length(f)/2 )+1;
hf(bf)=1;
yf=hf.*sf;
[t,st]=F2T1(f,yf);
st = real(st);
3.F2T
function [t,st]=F2T(f,sf)
%This function calculate the time signal using ifft function for the input
df = f(2)-f(1);
Fmx = ( f(end)-f(1) +df);
dt = 1/Fmx;
N = length(sf);
T = dt*N;
t = 0:dt:T-dt;
sff = fftshift(sf);
st = Fmx*ifft(sff);
F2T.m函数就是计算信号的IFFT,基本没什么问题,Fmx算的就是采样频率,写得这么奇怪应该是别人修改后的版本,而且时间序列的表达式在这又是明显正确的,也稍微改一下,一样把ifft前面的系数删去,如下:
function [t,st]=F2T1(f,sf)
%This function calculate the time signal using ifft function for the input
df = f(2)-f(1);
N = length(sf);
Fmx = N*df;%采样频率
dt = 1/Fmx;%采样间隔
T = dt*N;
t = 0:dt:T-dt;
sff = fftshift(sf);
st = ifft(sff);
原始的三个函数在信号序列采样点数较大时对解调影响较小,亲测PSK和FSK能正确解调,但是当采样点数只有几十个时,解调误码率很高,因为组成的低通滤波器的频带完全错位和扩宽了,以上修改后的函数亲测能运行且正确解调。
最后再补充一句,调用现成的函数时一定一定一定要注意适用条件,能瞅一眼就都瞅一眼,以免后续产生各种问题。
最后
以上就是失眠流沙为你收集整理的Matlab里关于T2F/F2T/lpf.m函数调用应注意的问题及函数修改的全部内容,希望文章能够帮你解决Matlab里关于T2F/F2T/lpf.m函数调用应注意的问题及函数修改所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复