树莓派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); */

}


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


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值