许多信号处理应用在某些特殊项目时需要正弦波。如果这个正弦波的相位或频率在设计中能被控制,那么它通常被称为数控振荡器 (NCO)。今天让我们花一些时间研究如何在FPGA中构建一个NCO。最后我们还将介绍一个 C++ 实现方案,它可以用于嵌入式应用程序。
我们是在可以生成正弦波(查找表方法、四分之一波查表方法、CORDIC的余弦波)情况下,如何通过正弦波发生器变成 NCO。
不过,在我们深入细节之前,让我们花点时间思考一下如何使用这样的 NCO。我今天提出这个的原因是双重的。首先,我知道有一个学生在努力理解如何构建这样的东西作为数字通信解调器的一部分。第二部分是构建一个比这篇 stackoverflow 文章(https://stackoverflow.com/questions/13466623/how-to-look-up-sine-of-different-frequencies-from-a-fixed-sized-lookup-table)推荐的更好的NCO。
但这几乎没有可能触及你想做一个NCO的想法。考虑一个例子......
任何线性信号处理系统都完全以其频率响应为特征。因此,我过去曾使用 NCO 以及某种类型的示波器来评估信号处理算法的数字输入是否得到正确处理。
我们之前使用 NCO作为演示的一部分, 证明改进的 PWM 发生器(http://zipcpu.com/dsp/2017/09/04/pwm-reinvention.html)在音频信号生成方面比传统 PWM工作得更好。虽然我们当时没有讨论音调发生器的细节,但我们今天将解释其中的许多细节。
还可以使用 NCO 在频率上移动信号——或者将其从某个中频 (IF)降低到可以在接收器中处理它的基带频率,或者作为传输的一部分在另一个方向上相同算法。
还可以将 NCO 用作数字通信调制器或解调器的一部分。
可以使用 NCO创建调幅 (AM) 信号甚至是调频 (FM)信号。
另一个常见用途是通过加法合成器生成音符。事实上,我们将在下面开发的NCO的相位累加器部分甚至可以用于减法合成——它非常通用。
最后,由于作为设计人员可以完全控制 NCO的频率输出,因此 甚至可以做一些更奇特的事情——例如构建跳频扩频信号——这应该是你想要做的。
事实上,NCO是数字信号处理 (DSP) 算法的基本组成部分,因此很难在此处列举它们可用于的所有内容。
什么是 NCO?

NCO 将频率输入转换为正弦波,就我们今天的目的而言,数控振荡器只是一个由数字逻辑创建的振荡器,可以完全控制数字逻辑。名义上,这种振荡器将接收希望产生的频率作为输入,并在该频率下产生数字采样的正弦波。如果选择在PLL中使用 NCO,那么还将调整此正弦波发生器的相位。然而,现在,将 NCO视为 一个简单的数字逻辑电路,它接受频率输入并产生采样的 正弦波作为输出。

基本 NCO 的组成部分.在内部, NCO 跟踪它产生的正弦波的相位,并在每个采样点增加该相位。
让我们通过三角函数来看看它是如何工作的。
我们将从我们想要产生的正弦波开始 ,如图 3 所示的正弦波:

并且由等式给出:

由于数字实现只能处理采样信号,因此我们需要每秒钟采样一次这个正弦波Ts。为了使我们的符号保持直截了当,我们现在将按样本编号索引这个正弦波输出,而不是按时间索引。