我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制

PWM 是一种调节输出功率的技术(俗称调压),其原理在于改变输出方波的占空比,具体输出见下图:

我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制

输出信号为电压值,当负载为恒阻时,上图中的输出功率分别为 25%、50%、75%。

实现方法如下:

  • 设置一个计数器,上图中的第一行就是个 4 位的计数器,每满 15 自动变为 0。那么可以得到输出频率等于时钟的 1/16。
  • 当计数器的值小于某个值的时候输出 0,高于或者等于某个值的时候输出 1。

假设控制的是一个小灯为 1/8 功率输出,那么我们需要的值就是 13 (4'hD),当计数器小于等于 13 输出 0,否则输出 1。

具体代码如下:

我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制

如果时钟为 50MHz,一个时钟周期为 2ns,根据推算可以得出上述的 PWM 输出信号的周期为 32 ns,频率大约 1.5MHz。由于 1.5MHz 的频率远远的超过了人眼 100Hz 的分辨极限,所以在人看来 LED 会一直发光但亮度较低。

然而并不是所有的外设都能承受 1.5MHz 这么高的频率。很多器件内包含有三极管,但三极管是存在截止频率上限问题,当输出管脚通过三极管来放大输出电流时,过高的频率会导致输出失效,所以绝大多数情况下我们需要降低 PWM 的输出频率。

使用环形计数器可以得到任意整数分频的电路,这在电子钟篇中已经试用过了。我们可以把分频模块的输出作为另一个电路的时钟输入,可是这种方法生成的时钟信号不够稳定。锁相环可以对时钟信号进行任意比例分频,倍频和移相等操作。锁相环分为数字式(DLL)和模拟式(PLL)两种,Altera 公司在 FPGA 里集成了模拟式锁相环,Xilinx 公司的器件集成的既有模拟的也有用数字式的。

与 ASICS 的*布线相比,FPGA 内部可用的时钟就显得十分有限了。FPGA 可用的时钟牵扯到全局时钟网络的问题。由于这里不涉及画板子的问题,对于时钟网络就不多做赘述了。

锁相环的使用方法: 首先在 tools 菜单栏找到并打开 MegaWizard Plug-In Manager,按照下面的步骤配置使用 PLL IP 核

我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制

这个 IP 核输出多达 5 个 信号,由于我们只需要用到一个输出 c0,所以 c1 ~ c4 设置为默认(不开启)即可。

我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制

我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制

这样的话 PLL 核就配置好了,原理图连接方法:

我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制

本文中时钟为 50MHz,可以计算得到输出频率

50M = 50_000_000 –> 50_000_000 / 25_000 = 2000 –> 2000/16 = 125

125Hz 的一个周期为 0.008s = 0ms = 8_000 us,使用图形仿真输入来验证显然不太现实,此外我们在工程中使用了 IP 核,出于效率的考虑应当选用 Modelsim。但我在使用 Modelsim 仿真时出现了问题,Modelsim 总是报告分频系数不正确,然而当我把分频系数降为 10 ,仿真器却可以正常工作。我猜测可能是因为 Modelsim 在仿真 Cyclone IV E 系列 PLL 的时候调用的是 Cyclone III 的仿真文件,而 Cyclone IV 的 PLL 与 Cyclone III 也许并不完全一致,也有可能是仿真库文件出现了问题。

觉得效果不够明显可以在 pwm 代码中添加一个全亮的灯作为参照也可以把 duty 改为 4'hE(1/16 功率),此外还可以尝试增大锁相环中的分频系数让小灯闪动(只要锁相环配置时出现 able to implement the requested PLL 就表示配置可行)。

上一篇:【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)


下一篇:php连接oracle数据库转载