首页 » 通讯 » 可控制992个舵机-PCA9685驱动分享_舵机_年夜众

可控制992个舵机-PCA9685驱动分享_舵机_年夜众

神尊大人 2024-11-07 09:40:51 0

扫一扫用手机浏览

文章目录 [+]

PCA9685

PCA9685

PCA9685是一款基于IIC总线通信的12位精度16通道PWM波输出的芯片,该芯片最初由NXP推出时紧张面向LED开关调光。

可控制992个舵机-PCA9685驱动分享_舵机_年夜众 可控制992个舵机-PCA9685驱动分享_舵机_年夜众 通讯

目前海内,Arduino在舵机掌握领域利用的更广泛,底层驱动库十分完善的,但对付单片机用户来说,则须要自行根据用户手册编写底层的驱动。

可控制992个舵机-PCA9685驱动分享_舵机_年夜众 可控制992个舵机-PCA9685驱动分享_舵机_年夜众 通讯
(图片来自网络侵删)
上风价格非常便宜,10+米。
最多可62块板子同时利用,每一块棒子可以驱动多达12个舵机,最多可驱动多达992个舵机,相称可不雅观的数量!
地址误区讲解

其地址的分配是通过模块右上方的短接焊盘来确定的,从A0-A5表示地址的最低位到最高位,也便是最多可级联2^5=32个模块,地址为: 1+A5+A4+A3+A2+A1+A0+rw。
如果不用短接的话Ax=0;短接的话Ax=1;rw为写的话rw=0;rw为读的话rw=1;以是默认地址应为1000 0000 =0x80,许多人包括淘宝商家误以为默认地址是0x40,是缺点的!

IIC通信

可以利用仿照IIC总线通讯,方便移植,摆脱硬件的限定。

驱动 PCA9685.h

#ifndef __I2C_PCA9685_H__

#define__I2C_PCA9685_H__

/ 包含头文件 ----------------------------------------------------------------/

#include \"大众stm32f4xx_hal.h\公众

/ 类型定义 ------------------------------------------------------------------/

/ 宏定义 --------------------------------------------------------------------/

#define PCA9685_adrr 0x80

#define PCA9685_SUBADR1 0x2

#define PCA9685_SUBADR2 0x3

#define PCA9685_SUBADR3 0x4

#define PCA9685_MODE1 0x0

#define PCA9685_PRESCALE 0xFE

#define LED0_ON_L 0x6

#define LED0_ON_H 0x7

#define LED0_OFF_L 0x8

#define LED0_OFF_H 0x9

#define ALLLED_ON_L 0xFA

#define ALLLED_ON_H 0xFB

#define ALLLED_OFF_L 0xFC

#define ALLLED_OFF_H 0xFD

#define FINGLEMAX 25

#define FINGLEMIN 90

/ 扩展变量 ------------------------------------------------------------------/

/ 函数声明 ------------------------------------------------------------------/

void PCA9685_write(unsigned char reg,unsigned char data);

uint8_t PCA9685_read(unsigned char reg);

void setPWMFreq(uint8_t freq);

void setPWM(uint8_t num, uint16_t on, uint16_t off);

void begin();

void Angle(uint8_t num,float angle);

#endif / __I2C_PCA9685_H__ /

/END OF FILE/

驱动PCA9685.C

/ 包含头文件 ----------------------------------------------------------------/

#include \"大众i2c/bsp_I2C.h\"大众

#include \"大众PCA9685/bsp_i2c_PCA9685.h\"大众

#include \"大众stm32f4xx_hal.h\公众

#include \公众i2c/bsp_I2C.h\"大众

#include \"大众math.h\"大众

/ 私有类型定义 --------------------------------------------------------------/

/ 私有宏定义 ----------------------------------------------------------------/

/ 私有变量 ------------------------------------------------------------------/

/ 扩展变量 ------------------------------------------------------------------/

/ 私有函数原形 --------------------------------------------------------------/

/ 函数体 --------------------------------------------------------------------/

void PCA9685_Delay(void)

{

uint8_t i;

for (i = 0; i < 30; i++);

}

void PCA9685_write(uint8_t reg,uint8_t date)

{

I2C_Start();

I2C_SendByte(PCA9685_adrr); //PCA9685

I2C_WaitAck();

I2C_SendByte(reg);

I2C_WaitAck();

I2C_SendByte(date);

I2C_WaitAck();

I2C_Stop();

}

//从PCA9685读数据有返回值

uint8_t PCA9685_read(uint8_t reg)

{

uint8_t res;

I2C_Start();

I2C_SendByte(PCA9685_adrr); //PCA9685

I2C_WaitAck();

I2C_SendByte(reg);

I2C_WaitAck();

I2C_Start();

I2C_SendByte(PCA9685_adrr|0x01);

I2C_WaitAck();

res = I2C_ReadByte();

I2C_Stop();

return res;

}

//PCA9685复位

void reset(void)

{

PCA9685_write(PCA9685_MODE1,0x0);

}

void begin(void)

{

reset();

}

//PCA9685修正频率

/

函数功能: 设置PWM频率

输入参数: 20MS设置50

返 回 值: 无

说 明:无

/

void setPWMFreq(uint8_t freq)

{

uint8_t prescale,oldmode,newmode;

double prescaleval;

freq = 0.92; // Correct for overshoot in the frequency setTIng

prescaleval = 25000000;

prescaleval /= 4096;

prescaleval /= freq;

prescaleval -= 1;

prescale = (uint8_t)floor(prescaleval + 0.5);

oldmode = PCA9685_read(PCA9685_MODE1);

newmode = (oldmode&0x7F) | 0x10; // sleep

PCA9685_write(PCA9685_MODE1,newmode); // go to sleep

PCA9685_write(PCA9685_PRESCALE,prescale); // set the prescaler

PCA9685_write(PCA9685_MODE1,oldmode);

HAL_Delay(2);

PCA9685_write(PCA9685_MODE1,oldmode|0xa1);

}

/---------------------------------------------------------------

PCA9685修正角度函数

num:舵机PWM输出引脚0~15,on:PWM上升计数值0~4096,off:PWM低落计数值0~4096

一个PWM周期分成4096份,由0开始+1计数,计到on时跳变为高电平,连续计数到off时

跳变为低电平,直到计满4096重新开始。
以是当on不即是0时可作延时,当on即是0时,

off/4096的值便是PWM的占空比。

----------------------------------------------------------------/

/

函数功能: 设置PWM占空比

输入参数: num:舵机PWM输出引脚0~15,on:PWM上升计数值0~4096,off:PWM低落计数值0~4096

一个PWM周期分成4096份,由0开始+1计数,计到on时跳变为高电平,连续计数到off时

跳变为低电平,直到计满4096重新开始。
以是当on不即是0时可作延时,当on即是0时,

off/4096的值便是PWM的占空比。

返 回 值: 无

说 明:无

/

void setPWM(uint8_t num, uint16_t on, uint16_t off)

{

PCA9685_write(LED0_ON_L+4num,on);

PCA9685_write(LED0_ON_H+4num,on>>8);

PCA9685_write(LED0_OFF_L+4num,off);

PCA9685_write(LED0_OFF_H+4num,off>>8);

}

uint16_t calculate_PWM(float angle){

return (int)(204.8(0.5+angle1.0/90));

}

/

函数功能: 舵机角度

输入参数: num:舵机通道 angle:舵机角度

返 回 值: 无

说 明:无

/

void Angle(uint8_t num,float angle)

{

uint16_t pwm = calculate_PWM(angle);

setPWM(num,0,pwm);

PCA9685_Delay();

}

/END OF FILE/

main.c

I2C_InitGPIO();

begin();

setPWMFreq(50);

标签:

相关文章