【问题标题】:In Raspberry Pi 2, how to configure PWM1 channel?在树莓派 2 中,如何配置 PWM1 通道?
【发布时间】:2016-01-05 14:57:16
【问题描述】:

我可以使用 Raspberry Pi 的 GPIO 18 上的 PWM0 通道使用以下 c 代码来驱动伺服:

#define BCM2708_PERI_BASE       0x3F000000
#define PWM_BASE                (BCM2708_PERI_BASE + 0x20C000)
#define CLOCK_BASE              (BCM2708_PERI_BASE + 0x101000)
#define GPIO_BASE               (BCM2708_PERI_BASE + 0x200000)

#define PWM_CTL 0
#define PWM0_RNG 4
#define PWM0_DAT 5

#define PWM0_MS_MODE    0x0080  // Run in MS mode
#define PWM0_USEFIFO    0x0020  // Data from FIFO
#define PWM0_REVPOLAR   0x0010  // Reverse polarity
#define PWM0_OFFSTATE   0x0008  // Ouput Off state
#define PWM0_REPEATFF   0x0004  // Repeat last value if FIFO empty
#define PWM0_SERIAL     0x0002  // Run in serial mode
#define PWM0_ENABLE     0x0001  // Channel Enable

#define PWMCLK_CNTL 40
#define PWMCLK_DIV 41

// stop clock and waiting for busy flag doesn't work, so kill clock
*(clk + PWMCLK_CNTL) = 0x5A000000 | (1 << 5); usleep(10);

// wait until busy flag is set
while ( (*(clk + PWMCLK_CNTL)) & 0x00000080){}

*(clk + PWMCLK_DIV) = 0x5A000000 | (Divisor << 12);
*(clk + PWMCLK_CNTL) = 0x5A000011;
*(pwm + PWM_CTL) = 0; usleep(10);

*(pwm + PWM0_RNG) = Counts; usleep(10);
*(pwm + PWM0_DAT) = (int) (DutyCycle * Counts / 100); usleep(10);
*(pwm + PWM_CTL) |= ( (1 << 7) | (1 << 0) );

但是,当我尝试在 PWM1 通道上的另一个 GPIO 上驱动另一个伺服时,它根本不起作用。 PWM1通道有以下值:

#define PWM1_RNG 8
#define PWM1_DAT 9

#define PWM1_MS_MODE    0x8000  // Run in MS mode
#define PWM1_USEFIFO    0x2000  // Data from FIFO
#define PWM1_REVPOLAR   0x1000  // Reverse polarity
#define PWM1_OFFSTATE   0x0800  // Ouput Off state
#define PWM1_REPEATFF   0x0400  // Repeat last value if FIFO empty
#define PWM1_SERIAL     0x0200  // Run in serial mode
#define PWM1_ENABLE     0x0100  // Channel Enable

谁能告诉我PWM0和PWM1的寄存器在哪里修改?

【问题讨论】:

  • 您向我们展示了一些您认为有效的代码,然后告诉我们您有一些其他代码不起作用,但您没有展示。那么您希望我们告诉您您未显示的代码有什么问题!代码的正确操作似乎依赖于pwmclk 的适当值,您在任何情况下都没有显示。使用pigpio library 可能会为您省去一些麻烦,它允许在任何 GPIO 引脚上进行 PWM,并巧妙地使用 DMA、PWM 和 PCM 外设,以实现最小的软件开销和良好的精度。
  • ... 或 ServoBlaster,pigpio PWM 控制方法由此派生。
  • @Clifford:我不想在任何 GPIO 上使用软件 PWM。我需要做的只是在提供硬件 PWM 的 GPIO 19 特定引脚上使用硬件 PWM。但是,我不知道要更改哪些值,因为原始代码不是我的。我真正关心的只是操纵 RPI 的寄存器
  • 阅读指向 pigpio 的 PWM 实现所基于的 ServoBlaster 库的链接 - 它不是“软件 PWM”,适用于驱动伺服。然而,我的观点仍然存在;您没有发布适当的代码。您告诉我们您已经定义了宏 PWM1_MS_MODE 等,但没有向我们展示这些宏的使用位置。简单地定义它们当然是不够的。 “它根本不起作用”也不是很有帮助;在这一点上,我将在调试器中单步执行代码以查看 实际 发生了什么。

标签: linux embedded raspberry-pi2 gpio pwm


【解决方案1】:

通过可用的documentation,您必须将 GPIO45 设置为其 Alternate Function 0

PWM 外设寄存器在Broadcom peripheral documentation 中进行了描述(这指的是 RPi1 的 BCM2835,但在外设集方面与 RPi 的 BCM2836 基本相同。请注意,PWM 通道被称为 PWM1/2 而不是然后是寄存器表中的 PWM0/1。

【讨论】:

  • 感谢 Clifford 先生的回复,您能告诉我在Boardcom BCM2835 Peripherals 哪里可以找到所需的寄存器吗?我的意思是如何区分该文档中的两个 PWM?我试图找到它们但失败了。
  • @mohasalah : 有一个 PWM 控制器有两个通道。 9.6 中的表总结了寄存器映射。每个 PWM 都有单独的 RNG 和 DAT 寄存器。 FIFO 寄存器可以交替为两个通道提供服务,也可以为其中一个提供服务。 CTL 寄存器由两个通道共享,每个通道在适当的情况下具有单独的子字段。我只阅读可用的文档。 Broadcom 文档相当简洁,而且质量不及您对普遍可用的设备所期望的质量。如果您遇到困难,请按照建议使用该库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 2023-03-25
  • 2017-09-29
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多