首页 > 编程知识 正文

舵机控制程序,51单片机控制舵机程序

时间:2023-05-04 22:14:45 阅读:274166 作者:1917

本文介绍通过写入寄存器的方法实现对PCA9685 的控制。

 PCA9685 模块

制作机器人,舵机就是让它动起来的关键器件。而又由于通常设计中为了不影响处理器供电或者主控功率不够,都会另外制作一块板子用作舵机驱动,也叫舵机控制板。
PCA9685是一款用于产生16路PWM信号的LED控制芯片, 采用I2C总线与主控芯片进行通信。PCA9685具有可以产生16路PWM脉冲、控制独立精准、编程简单灵活等特点, 以其为基础实现的舵机控制能够有限减少硬件和软件设计的复杂度, 具有高可靠性
PCA9685的用途

PCA9685是一款基于I2C总线控制的16路LED背光调节控制芯片。每一路LED输出端均可自由调节PWM波的频率 (40~1000Hz) 和占空比 (0%~100%) 。这款芯片主要通过输出不同占空比的PWM脉冲信号来控制舵机转动的角度。
PCA9685的特点

PCA9685可编程调节16路PMW脉冲的占空比以及高电平到来的时刻, 分辨率为12位 (4096) 。

地址问题

PCA9685 是一个I2C 从设备,有个设备ID,或者叫从 地址。从地址是如下确定的:

A5-A0 缺省是开放的, 地址是0x40

 

I2C 时钟最高可以1M 

频率

16路PWM 的频率都是一样的, 由prescale 

 

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

内部时钟频率为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);} 占空比或者脉冲宽度的设定

下图是设定脉冲宽度的示意图。整个周期为4095, LED_ON 和 LED_OFF 2个的设定值确定脉宽,我的设定中LED_ON 设为0, LED_OFF就是脉宽了。 这里都用2位字节来表示。

比如6,7 是LED0_ON,而8,9是 LEN0_OFF ,接下来都是4个字节控制一路pwm的占空比。

地址定义表

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

实际例子

我的实现是在zynq 7000上完成的,zynq 7000 的 iic 外设编程

本文并没介绍I2C 的编程,各种情况都可以完成,强调的是写哪些寄存器,如何控制。

下面是我控制的序列,(左边是寄存器地址,右边是写入值)

//测试配置列表u8 configList[11][2]={{0x00,0x10},{0xfe,120},{0x00,0x00},{6,0x0},{7,0x0},{8,200},{9,0},{0x0A,0},{0x0B,0},{0x0c,150},{0x0d,1}};

那我解说一下是,控制休眠,设定频率,取消休眠,pwm0 的LED0_ON 为 (0x00_00) ,LED0_OFF 为(0x00_d8或者200)  pwm1 的LED1_ON 为 (0x00_00) ,LED1_OFF 为(0x01_96或者406) 

0xd8 =200, 0x96=150 算得不一定对。

Arduino Uno 系统可以参看 http://wiki.sunfounder.cc/index.php?title=PCA9685_16_Channel_12_Bit_PWM_Servo_Driver 都有程序库。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。