本帖最后由 fernandoJ 于 2016-5-6 22:37 编辑 相信很多朋友在求信号初相位的时候都会遇到同一个问题,那就是根据FFT得到的频谱利用angle()或者phase()函数并不能反映信号的真实初相位。有很多的网友对此进行了解答。但是,目前各种网帖中的方法,并不完全合理! 首先,看一个简单的例子: t=0:1/2048:1-1/2048; %采样点 y=sin(50*2*pi*t+pi/6)+0.5*sin(150*2*pi*t+pi/3); %信号,具有50Hz的基波以及150Hz的三次谐波 x=fft(y); %FFT phi=angle(x(1:1024)); %相位谱 那么,分别提取相位谱中对应的基波以及三次谐波的相位,即phi(51)与phi(151), >> phi(51)/pi ans = -0.3333 >> phi(151)/pi ans = -0.1667 不难发现,基波的相位为-π/3,而三次谐波的相位为-π/6,这与信号y是不同的。 再看以下一个简单的例子: t=0:1/2048:1-1/2048; %采样点 y=cos(50*2*pi*t+pi/6)+0.5*cos(150*2*pi*t+pi/3); %信号,具有50Hz的基波以及150Hz的三次谐波 x=fft(y); %FFT phi=angle(x(1:1024)); %相位谱 >> phi(51)/pi ans = 0.1667 >> phi(151)/pi ans = 0.3333 在本例中,信号y中的基波以及三次谐波的函数由“sin”变成了“cos”。而根据该程序计算的结果也恰好如实地反映了基波以及谐波的初相位。 所以,从以上两个例子可以看出,事实上,利用FFT计算信号的初相位是可以实现的。但是,能否精确地反映信号的初相位却与信号有关。而其中原因就必须从傅立叶变换的原理以及angle()(phase())函数的原理说起: 所以,当信号y为正弦函数时,无法利用angle()函数直接求出其初相位。但是,只需要对程序进行一下小的改动便能够如愿以偿,请注意代码中红色部分: t=0:1/2048:1-1/2048; y=sin(50*2*pi*t+pi/6)+0.5*sin(150*2*pi*t+pi/3); x=fft(y); for i=1:1024 x1=angle(x(i)); phi(i)=(pi/2+x1)/pi; end >> phi(51) ans = 0.1667 >> phi(151) ans = 0.3333 计算结果显然与实际情况相符合。再来看一个更为复杂的例子: t=0:1/2048:1-1/2048; y=sin(50*2*pi*t+pi/6)+0.8*sin(100*2*pi*t+pi/4)+0.5*sin(150*2*pi*t+pi/3)+sin(200*2*pi*t+pi/2); x=fft(y); for i=1:1024 x1=angle(x(i)); phi(i)=(pi/2+x1)/pi; end >> phi(51) ans = 0.1667 >> phi(101) ans = 0.2500 >> phi(151) ans = 0.3333 >> phi(201) ans = 0.5000 显然,根据该方法计算结果与实际相符合。因此,在使用angle()函数计算信号初相位之前,必须要对信号的正余弦类型进行判断。根据不同的信号编写相应的代码,利用FFT完全可以求出信号各次谐波的初相位。 |
|