相位与角频率引发的惨案
最近在项目过程中被一个问题困扰很久,在用FPGA进行正弦波相位的计算过程中,由于频率是时刻改变的,所以要实时计算f,并与2pi*t相乘得到相位信息,也即 θ = 2 p i ∗ f ∗ t , θ=2pi*f*t, θ=2pi∗f∗t,写成离散形式就是 θ = 2 p i ∗ f / f s ∗ n . θ=2pi*f/fs*n. θ=2pi∗f/fs∗n.可是在仿真过程中发现最后得出的正弦波频率并不是我想要的频率,开始频率相同,后来频率有很大偏差,导致我一级级查找问题所在浪费了很长时间。可是到最后实在没有找到问题所在,于是用Matlab来帮助分析问题。
MATLAB验证
下图为用matlab生成的图片,我本想生成一频率从1000000~200000的正弦波,可是到最后正弦波的频率已经低于200000了,说明并不是FPGA计算过程中产生的问题。
于是我从公式本身入手寻找问题,生成正弦波所用的代码为:
for n=1:N
s(n)=sin(2*pi*f(n)*n/fs);
end
在写这个公式的过程中我并没有进行什么思考,只是下意识的觉得相位就是由w和t乘积生成的,即
θ
=
w
∗
t
θ=w*t
θ=w∗t,可是后来我才发现,我错就错在了这个最不起眼的地方。
θ确实等于w*t,但是这并不是任何时候都成立的,这个公式的前提条件是w恒定。为什么要强调w,w是什么?下文为百科中对w的定义。
角频率,也称圆频率,表示单位时间内变化的相角弧度值。角频率是描述物体振动快慢的物理量,与振动系统的固有属性有关,常用符号ω表示。在国际单位制中,角频率的单位是弧度/秒(rad/s)。
由此可见,w是描述一个量变化快慢的数值,类似于速度。那么对于速度,我们知道路程等于速度乘以时间,即
s
=
v
∗
t
s=v*t
s=v∗t,当然前提是匀速直线运动。那么当速度变化的情况下,路程就不能单纯的用乘法来计算了,此时路程等于速度对时间的积分,当然v是关于t的函数v(t)。
s
=
∫
0
T
v
(
t
)
d
t
s=\int_0^T {v(t)} \,{\rm d}t
s=∫0Tv(t)dt
对于角频率来说也是一样,若想要求得正确的相位,需要对t进行积分,
θ
=
w
∗
t
θ=w*t
θ=w∗t只是在w恒定的情况下才成立的一种特殊情况,因为
∫
0
T
w
d
t
=
w
T
\int_0^T {w} \,{\rm d}t=wT
∫0Twdt=wT。当w随着时间变化时,需要将w(t)对t进行积分,
θ
=
∫
0
T
w
(
t
)
d
t
θ=\int_0^T {w(t)} \,{\rm d}t
θ=∫0Tw(t)dt这样得出的相位输入给sin函数才是有意义的,此时得出的正弦波才是我们想要的频率。