Answers:
我终于从bcm2835.h驱动程序头文件中获得了一个完整的理解,因此以为我会为他人发布并回答我自己的问题。
标头中的相关位:
脉宽调制
BCM2835在GPIO引脚的有限子集上支持硬件PWM。该bcm2835库提供了用于配置和控制这些引脚上的PWM输出的功能。
BCM2835包含2个独立的PWM通道(0和1),每个通道都连接到GPIO引脚的有限子集。以下GPIO引脚可以连接到以下PWM通道:
GPIO PIN RPi pin PWM Channel ALT FUN 12 0 0 13 1 0 18 1-12 0 5 19 1 5 40 0 0 41 1 0 45 1 0 52 0 1 53 1 1
为了使GPIO引脚从其PWM通道发出输出,必须将其设置为上面给出的Alt功能。请注意,当前版本的Raspberry Pi仅在IO接头连接器上暴露这些引脚之一(GPIO 18 = RPi引脚1-12),因此这是RPi上唯一可用于PWM的IO引脚。此外,必须将其设置为ALT FUN 5以获得PWM输出。
两个PWM通道均由相同的PWM时钟驱动,可使用改变其时钟分频器
bcm2835_pwm_set_clock()
。每个通道可以通过分别启用bcm2835_pwm_set_mode()
。PWM通道的平均输出由该通道的DATA / RANGE之比确定。使用bcm2835_pwm_set_range()
设置的范围内,bcm2835_pwm_set_data()
在该比率设置数据每个PWM通道均可在平衡或标记空间模式下运行。在平衡模式下,硬件发送时钟脉冲的组合,从而导致每个RANGE脉冲总的DATA脉冲。在Mark-Space模式下,硬件将DATA时钟脉冲的输出设置为高电平,然后将RANGE-DATA时钟脉冲的输出设置为低电平。
可以设置PWM时钟来控制PWM脉冲宽度。PWM时钟源自19.2MHz时钟。您可以设置任何分频器,但是一些常用的分频器由
bcm2835PWMClockDivider
例如,假设您想用大约1kHz的PWM驱动直流电动机,并以1/1024的增量控制速度,从0/1024(停止)到1024/1024(全开)。在这种情况下,您可以将时钟分频器设置为16,将RANGE设置为1024。脉冲重复频率将为1.2MHz / 1024 = 1171.875Hz。
bcm2835PWMClockDivider
指定用于从系统时钟生成PWM时钟的分频器。下图给出了分频器,时钟周期和时钟频率。时钟分频基于19.2MHz的标称PWM基本时钟速率。每个分频器显示的频率已通过测量确认typedef enum { BCM2835_PWM_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 9.375kHz */ BCM2835_PWM_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 18.75kHz */ BCM2835_PWM_CLOCK_DIVIDER_512 = 512, /*!< 512 = 37.5kHz */ BCM2835_PWM_CLOCK_DIVIDER_256 = 256, /*!< 256 = 75kHz */ BCM2835_PWM_CLOCK_DIVIDER_128 = 128, /*!< 128 = 150kHz */ BCM2835_PWM_CLOCK_DIVIDER_64 = 64, /*!< 64 = 300kHz */ BCM2835_PWM_CLOCK_DIVIDER_32 = 32, /*!< 32 = 600.0kHz */ BCM2835_PWM_CLOCK_DIVIDER_16 = 16, /*!< 16 = 1.2MHz */ BCM2835_PWM_CLOCK_DIVIDER_8 = 8, /*!< 8 = 2.4MHz */ BCM2835_PWM_CLOCK_DIVIDER_4 = 4, /*!< 4 = 4.8MHz */ BCM2835_PWM_CLOCK_DIVIDER_2 = 2, /*!< 2 = 9.6MHz, fastest you can get */ BCM2835_PWM_CLOCK_DIVIDER_1 = 1 /*!< 1 = 4.6875kHz, same as divider 4096 */ } bcm2835PWMClockDivider;
综上所述:
如果您需要硬件PWM,则必须固定在引脚12(BCM18)上,其他GPIO引脚将使用软件PWM。
如上所述,出于大多数使用情况和理智的原因,您可能需要将PWM模式设置为“标记空间”模式。
在此模式下,每个“脉冲”的持续时间为高电平与低电平的时间取决于PWM数据与PWM范围的比值,这与PWM时钟速度无关。
PWM范围实际上是每个脉冲的“分辨率”或可能的“分度”数。除法越多,分辨率越高,因此对于给定的脉冲宽度,可编码的状态越多。
“占空比”是PWM数据与PWM范围的比率,以百分比表示。PWM数据为8时,PWM范围为10,占空比为80%。
PWM时钟速度是两个除数的幂。因此,您为PWM选择的时钟速度必须为。divisor & (divisor -1) == 0
尽管上面列出了12个有效值。
将PWM时钟频率除以所需的输出频率可得出脉冲范围值。
当我编码音频并使用压电发声器时,我需要50%的占空比,以使压电振荡和音量最大化。因此,PWM数据值始终为PWM范围值的一半-高50%低50%。
要计算所需的频率,请选择适合您的应用的时钟分频器-我选择了16,等于1.2Mhz。所以:
A的音符为440Hz,F#为370Hz,C#为277Hz
PWMClock = 16; // 1.2Mhz
const A4_RANGE = 1.2e6 / 440; // 1.2Mhz/440Hz
A4Data = A4_RANGE / 2;
const F4S_RANGE = 1.2e6 / 370; // 1.2Mhz/370Hz
F4SData = F4S_RANGE / 2;
const C4S_RANGE = 1.2e6 / 277; // 1.2Mhz/277Hz
C4SData = C4S_RANGE / 2;
您可以轻松地将PWM范围的倍数上下移动八度-范围* 2将其降低八度,范围* 0.5将其降低一个八度。
如果要以50Hz的频率驱动伺服器,则相同的范围计算适用:
PWM Range = PWM frequency / Desired Output Frequency
(根据一些帖子,最大PWM范围值是4096,根据我的经验,这不是正确的,因为如上所述玩C#时,PWM范围为4332,可以正常工作。)
像大多数事情一样-当您知道如何时,这很容易。
〜N
在最新的Pis(具有40针扩展头和计算模块的Pis)上,GPIO 12/13/18/19可用于提供硬件PWM信号。
PWM时钟源不必是19.2MHz的晶体,piggio使用500MHz的PLLD。
有关设置硬件PWM频率的简单命令行方法,请参见http://abyz.me.uk/rpi/pigpio/pigs.html#HP