树莓派3B PWM

树莓派3 调试pwm:

1.用指令控制硬件pwm

pwm输出频率为4.8Mhz/1024 = 4.6875kHz:

gpio mode 1 pwm #设置pwm引脚功能为pwm

gpio pwm-ms #设置pwm的模式为pwm-ms Mark-Space 模式

gpio pwmr 1024 #设置pwm的范围 1024

gpio pwmc 4 #设置pwm的频率 4 :4.8MHz

gpio pwm 1 512 #设置pwm的占空比 512/1024

其中pwmc的范围是

    /*!< 2048 = 9.375kHz */

    /*!< 1024 = 18.75kHz */

    /*!< 512 = 37.5kHz */

    /*!< 256 = 75kHz */

    /*!< 128 = 150kHz */

    /*!< 64 = 300kHz */

    /*!< 32 = 600.0kHz */

    /*!< 16 = 1.2MHz */

    /*!< 8 = 2.4MHz */

    /*!< 4 = 4.8MHz */

    /*!< 2 = 9.6MHz, fastest you can get */

    /*!< 1 = 4.6875kHz, same as divider 4096 */

2.程序控制硬件pwm

a) 采用bcm2835 C library

b) 下载 wgethttp://www.airspayce.com/mikem/bcm2835/bcm2835-1.50.tar.gz

c) 解压 tar -zxvf bcm2835-1.50.tar.gz

d) cd bcm2835-1.50/examples/pwm

e) gcc -o pwm -I ../../src ../../src/bcm2835.c pwm.c

f) sudo ./pwm

 

发现问题:

执行pwm命令后执行该程序有pwm波形输出,重启直接运行该程序没有pwm波形输出。

查看官网关于pwm的函数http://www.airspayce.com/mikem/bcm2835/group__pwm.html

例程中也都用到了这四个函数,接下来查看源码:

$ vi bcm2835-1.50/src/bcm2835.c

其中函数

void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled)

中有读取PWM寄存器中的值,将读取的值打印出来,然后将修改后的值再次打印出来。

printf("control = 0x%02x\n", control);

打印的值分别为 

0x2121

0x21a1

查看BCM2835 ARM Peripherals文档,因为BCM2835与BCM2837通用。

PWM中CTL寄存器,其中a1表示10100001 代表启用M/S传送模式、数据传送到FIFO中、启用PWM。

用手册中USEFi bit is used to enable/disable FIFO transfer. When this bit is high data stored in the FIFO is used for transmission. When it is low, data written to PWM_DATi is transferred. This bit is 0 as default.

意思也就是置位启用FIFO传输,清零将数据写入PWM_DAT寄存器中,关键是默认为0。读取出来的是1,所以没有pwm波形输出。

修改代码该源码。将USEFi位清零。

$ vi bcm2835-1.50/src/bcm2835.c

修改bcm2835_pwm_set_mode函数如下:

void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled)
{
  if (   bcm2835_clk == MAP_FAILED
       || bcm2835_pwm == MAP_FAILED)
    return; /* bcm2835_init() failed or not root */

  uint32_t control = bcm2835_peri_read(bcm2835_pwm + BCM2835_PWM_CONTROL);

  if (channel == 0)
    {
      if (markspace)
	control |= BCM2835_PWM0_MS_MODE;
      else
	control &= ~BCM2835_PWM0_MS_MODE;
      if (enabled)
	control |= BCM2835_PWM0_ENABLE;
      else
	control &= ~BCM2835_PWM0_ENABLE;
	  if(markspace && enabled)
	control &= ~BCM2835_PWM0_USEFIFO;
    }
  else if (channel == 1)
    {
      if (markspace)
	control |= BCM2835_PWM1_MS_MODE;
      else
	control &= ~BCM2835_PWM1_MS_MODE;
      if (enabled)
	control |= BCM2835_PWM1_ENABLE;
      else
	control &= ~BCM2835_PWM1_ENABLE;
	  if(markspace && enabled)
	control &= ~BCM2835_PWM1_USEFIFO;
    }

  /* If you use the barrier here, wierd things happen, and the commands dont work */
  bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, control);
  /*  bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, BCM2835_PWM0_ENABLE | BCM2835_PWM1_ENABLE | BCM2835_PWM0_MS_MODE | BCM2835_PWM1_MS_MODE); */

}


编译,重启再次执行该函数,有波形输出。


树莓派可以通过GPIO口控制PWM信号,实现对外设的调节。树莓派上有多个GPIO口,其中有些GPIO口可以输出PWM信号,可以用来控制电机、灯光等设备。 树莓派3B+和4B板型上有两个硬件PWM通道,可以直接输出PWM信号。另外,树莓派上的软件PWM也可以输出PWM信号,但是精度较低,不适合一些高精度的应用场合。 下面是使用Python代码控制树莓派三路PWM的示例: ```python import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) # 设置GPIO口 GPIO.setup(12, GPIO.OUT) GPIO.setup(32, GPIO.OUT) GPIO.setup(33, GPIO.OUT) # 创建PWM实例 pwm1 = GPIO.PWM(12, 100) pwm2 = GPIO.PWM(32, 100) pwm3 = GPIO.PWM(33, 100) # 启动PWM pwm1.start(0) pwm2.start(0) pwm3.start(0) try: while True: # 控制PWM占空比 for dc in range(0, 101, 5): pwm1.ChangeDutyCycle(dc) pwm2.ChangeDutyCycle(dc) pwm3.ChangeDutyCycle(dc) time.sleep(0.1) for dc in range(100, -1, -5): pwm1.ChangeDutyCycle(dc) pwm2.ChangeDutyCycle(dc) pwm3.ChangeDutyCycle(dc) time.sleep(0.1) except KeyboardInterrupt: pass pwm1.stop() pwm2.stop() pwm3.stop() GPIO.cleanup() ``` 上述代码中,使用了树莓派的GPIO.BOARD模式,指定了GPIO口的编号。其中,12、32、33分别对应GPIO口的12、32、33号,通过GPIO.setup()方法设置为输出模式。然后,使用GPIO.PWM()方法创建PWM实例,并设置PWM频率为100Hz。最后,使用ChangeDutyCycle()方法控制PWM占空比。 这样,就可以控制树莓派上的三路PWM信号了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值