我正在使用带有connectionpi的硬件PWM输出。它提供了函数pwmSetClock,该函数应该可以更改频率。(https://projects.drogon.net/raspberry-pi/wiringpi/functions/)。我认为,由于默认值为200 Mhz,将除数设置为200000000可以使LED明显连接到输出闪光灯,但是事实并非如此。
可以更改吗?
我正在使用带有connectionpi的硬件PWM输出。它提供了函数pwmSetClock,该函数应该可以更改频率。(https://projects.drogon.net/raspberry-pi/wiringpi/functions/)。我认为,由于默认值为200 Mhz,将除数设置为200000000可以使LED明显连接到输出闪光灯,但是事实并非如此。
可以更改吗?
Answers:
我最近有一些理由自己开始尝试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带来可见的闪烁(实际上是更多的闪烁)。我确实用示波器确认了上述方程,它似乎成立了。如上所述,频率上限将受所需分辨率的影响。
根据这个公式:
pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange
我们可以设置pwmClock=1920
并pwmRange=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。
这是我正在使用的代码。我试图查看更改设置后会发生什么变化。
#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时会出现奇怪的行为的原因。
pwmWrite()
。我没想到会发生什么事