控制硬件PWM频率


21

我正在使用带有connectionpi的硬件PWM输出。它提供了函数pwmSetClock,该函数应该可以更改频率。(https://projects.drogon.net/raspberry-pi/wiringpi/functions/)。我认为,由于默认值为200 Mhz,将除数设置为200000000可以使LED明显连接到输出闪光灯,但是事实并非如此。

可以更改吗?


1
我正在使用硬件PWM进行一些测试,它似乎没有固定的频率。它根据中设置的脉冲宽度而变化pwmWrite()。我没想到会发生什么事
TheMeaningfulEngineer

Answers:


25

我最近有一些理由自己开始尝试PWM,并发现(如其中一项评论所指出),频率似乎随占空比而变化-奇怪,对吗?事实证明,Broadcom实现了“平衡” PWM,以便使开和关PWM脉冲尽可能均匀地分布。他们在其数据表的第139页上提供了对该算法的描述和更多讨论:http : //www.element14.com/community/servlet/JiveServlet/downloadBody/43016-102-1-231518/Broadcom.Datasheet.pdf

因此,您真正想要的是将PWM置于标记空间模式,这将为您提供您正在寻找的传统(且易于预测)的PWM:

pwmSetMode(PWM_MODE_MS);

其余答案假定我们处于标记空间模式。

我还对pwmSetClock()和的值的允许范围做了一些试验pwmSetRange()。正如在其他答案之一中所述,的有效范围pwmSetClock()似乎从2到4095,而的有效范围pwmSetRange()最大为4096(我没有尝试找到下限)。

范围和时钟(更好的名称可能是除数)都会影响频率。该范围也会影响分辨率,因此虽然可以使用非常低的值,但实际上可能会限制为低值。例如,如果使用4的范围,则可以实现更高的频率,但是只能将占空比设置为0 / 4、1 / 4、2 / 4、3 / 4或4/4。

Raspberry Pi PWM时钟的基本频率为19.2 MHz。该频率除以参数pwmSetClock(),是PWM计数器递增的频率。当计数器达到等于指定范围的值时,它将重置为零。当计数器小于指定的占空比时,输出为高,否则输出为低。

这意味着,如果要将PWM设置为具有特定频率,则可以使用以下关系:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.

如果你使用的最大允许值pwmSetClock()pwmSetRange(),你将最终〜1.14赫兹的最小可实现硬件PWM频率。这肯定会给LED带来可见的闪烁(实际上是更多的闪烁)。我确实用示波器确认了上述方程,它似乎成立了。如上所述,频率上限将受所需分辨率的影响。


关于pwmRange的下限:我成功地将其设置为2(以获得50%的占空比)。
Ted Pudlik 2014年

您从什么来源知道pwm时钟的频率为19.2 MHz?
th gg 2014年

10

根据这个公式:

pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange

我们可以设置pwmClock=1920pwmRange=200得到pwmFrequency=50Hz

50 Hz = 19.2e6 Hz / 1920 / 200

我在alarmpi上对其进行测试:

$ pacman -S wiringpi
$ gpio mode 1 pwm
$ gpio pwm-ms
$ gpio pwmc 1920
$ gpio pwmr 200     # 0.1 ms per unit
$ gpio pwm 1 15     # 1.5 ms (0º)
$ gpio pwm 1 20     # 2.0 ms (+90º)
$ gpio pwm 1 10     # 1.0 ms (-90º)

注意:我的伺服系统预期信号为50Hz


您怎么来:“ gpio pwmr 200#每单位0.1毫秒”
mxlian

50Hz->每周期20ms 20毫秒/ 200单位=每单位
0.1

5

这是我正在使用的代码。我试图查看更改设置后会发生什么变化。

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main (void)
{
  printf ("Raspberry Pi wiringPi test program\n") ;

  if (wiringPiSetupGpio() == -1)
    exit (1) ;

  pinMode(18,PWM_OUTPUT);
  pwmSetClock(2);
  pwmSetRange (10) ;
  pwmWrite (18, 5);

for (;;) delay (1000) ;
}

pwmSetClock(1); -> 2.342kHz

pwmSetClock(2); -> 4.81兆赫

pwmSetClock(3); -> 3.19MHz

pwmSetClock(4); -> 2.398兆赫

pwmSetClock(5); -> 1.919兆赫

pwmSetClock(6); -> 1.6兆赫

pwmSetClock(7); -> 1.3兆赫

pwmSetClock(8); -> 1.2兆赫

pwmSetClock(9); -> 1.067MHz

pwmSetClock(10); -> 959kHz

pwmSetClock(11); -> 871kHz

pwmSetClock(20); -> 480kHz

pwmSetClock(200); -> 48kHz的

pwmSetClock(500); -> 19kHz

pwmSetClock(1000); -> 9.59kHz

pwmSetClock(2000); -> 4.802kHz

pwmSetClock(4000); -> 2.401kHz

pwmSetClock(5000); -> 10.58kHz

根据我的测试,似乎除数从2到小于5000的某个数字。我想这与直接在寄存器中设置的那些数字的二进制表示有关。一旦数字二进制表示的位数超过寄存器可容纳的位数,它就只获取第一位并以这种方式解释数字。这就是为什么从4000到5000时会出现奇怪的行为的原因。


1
我将如何更改占空比?
2013年

您如何测量频率?
Seanny123 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.