详解:如何在STM32中使用PCA9685控制舵机

这里写自定义目录标题

  • 一、PCA9685简介
  • 二、硬件
  • 1、电压
  • 2、i2c地址
  • 3、使能脚
  • 4. 频率
  • 5.地址定义表
  • 6. 舵机角度
  • 最近在公司实习,都说跨入职场是让人进步最快的方式,记录一下我自学加同学指点学到新知识。

    一、PCA9685简介

    PCA9685是一个基于IIC通信的16路PWM输出模块,可以在单片机资源不足的情况下进行扩展使用。
    i2c通信,只需要2根i2c线就可以控制16路pwm,周期和占空比都可控。
    可以多个模块级联。箭头部分可以更改设备id。
    可以控制16路输出端的开、关、pwm以及占空比。

    二、硬件

    1、电压

    数字电路电压范围可接受3.3和5v电平。此外还有一个v+引脚,这个引脚是给舵机供电用的,可以接稍微高一点的电压。

    2、i2c地址

    有6个地址控制脚,通过这些引脚可以控制设备的i2c地址。
    7位的I2C地址为:0x40 + A5:A0,A5到A0如果不做任何处理的话是0,想要把哪一位置1就把那个引脚焊到一起。
    另外用i2cdetect检测出还有一个0x70地址一直存在,这是一个通用地址,可以给所有从机下达指令。

    3、使能脚

    模块有一个OE反使能脚,这个引脚低电平使能,不接的话模块内部默认已经接地使能了,所以正常使用可以不接。

    在使用PCA9685的时候需要注意以下几点:

    1.PCA9685的分辨率是12位,即占空比控制时,0-4096对应的占空比为0-100,在控制舵机的时候,控制信号是0.5ms-2.5ms,周期20ms,所以控制舵机角度不会有太高的分辨率,对舵机控制精度较高的地方不建议使用。

    PCA9685地址位和很多描述的不一样,根据芯片手册,地址位的寄存器一共8位,其中最高位固定是1,A0-A5这六位是用户可更改的,而其中最关键的一位是R/W位,这一位主要是决定了读还是写,置1时为读,置0时为写,所以我们在写程序的时候,PCA9685的地址应把R/W位加上,是0x80,而不是0x40,在写的时候,发送地址位是0x80,在读的时候,发送的地址位是0x81。

    4. 频率

    16路PWM 的频率都是一样的, 由prescale PWM 波长设定. 舵机控制所需的 PWM 周期为20 ms. 在用 PCA9685 作为多舵机控制器时,需要将 其 PWM 输出周期设定为20 ms,即PWM 波的频率设定为50 Hz,PCA9685 输出频率与振荡器有关,频率的 设置值

    prescale公式

    内部时钟频率为25M ,经计算,当需要输出50 Hz 的 PWM 频率时,设定值为121. 将该值下载到频率设定寄存器就可以改变芯片 工作频率. 需要注意的是,频率的更改只能在 PCA9685 芯片处于休眠状态下进行。

    presale 地址是0xFE,可以datasheet 里查找到。下面是 开源库中设定频率的函数代码:

    void Adafruit_PWMServoDriver::setPWMFreq(float freq)
     {
      //Serial.print("Attempting to set freq ");
      //Serial.println(freq);
      freq *= 0.9;  // Correct for overshoot in the frequency setting (see issue #11).
      float prescaleval = 25000000;
      prescaleval /= 4096;
      prescaleval /= freq;
      prescaleval -= 1;
      if (ENABLE_DEBUG_OUTPUT) {
        Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
      }
      uint8_t prescale = floor(prescaleval + 0.5);
      if (ENABLE_DEBUG_OUTPUT) {
        Serial.print("Final pre-scale: "); Serial.println(prescale);
      }
      
      uint8_t oldmode = read8(PCA9685_MODE1);
      uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
      write8(PCA9685_MODE1, newmode); // go to sleep
      write8(PCA9685_PRESCALE, prescale); // set the prescaler
      write8(PCA9685_MODE1, oldmode);
      delay(5);
      write8(PCA9685_MODE1, oldmode | 0xa1);  //  This sets the MODE1 register to turn on auto increment.
                                              // This is why the beginTransmission below was not working.
      //  Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
    }
    

    5.地址定义表

    在datasheet 文件中可以看到地址定义信息表,这里剪一页到这里作为参考
    datash

    6. 舵机角度

    一个周期为20ms的脉冲里面高电平持续的时间决定了舵机转动的角度,180度舵机对应关系如下:0.5ms–0度,1ms–45度,1.5ms–90度,2ms–135度,2.5ms–180度

    总体而言,stm32中使用PCA9685控制舵机原理是通过向舵机的信号线发送PWM信号来控制舵机的输出量,而PWM的周期以及占空比,我们是可控的,我们通过PCA9685控制PWM信号输出,以此来达到控制的目的。

    占空比 = t / T 相关参数如下:

    t = 0.5ms——————-舵机会转到 0 °
    t = 1.0ms——————-舵机会转到 45°
    t = 1.5ms——————-舵机会转到 90°
    t = 2.0ms——————-舵机会转到 135°
    t = 2.5ms——————-舵机会转到 180°
    以下是我的部分原理图
    PCA9685

    物联沃分享整理
    物联沃-IOTWORD物联网 » 详解:如何在STM32中使用PCA9685控制舵机

    发表评论