本驱动程序专为基于51单片机的16路PWM舵机模块设计,支持多个舵机同步或异步控制。适合机器人、无人机等项目应用。
以下是淘宝上售卖的16路PWM舵机驱动模块用51单片机编写的部分程序代码:
```c
#include
#include
#include
#include
typedef unsigned char uchar;
typedef unsigned int uint;
sbit scl = P1^3; // 时钟输入线
sbit sda = P1^4; // 数据输入/输出端
sbit KEY1 = P2^0;
sbit KEY2 = P2^1;
#define PCA9685_adrr 0x80 // 片选地址,将焊接点置1可改变地址
// 定义PCA9685寄存器和常量
#define PCA9685_MODE1 0x0
#define PCA9685_PRESCALE 0xFE
#define LED0_ON_L 0x6
#define LED0_OFF_L 0x8
#define SERVOMIN 115 // 舵机最小脉冲长度计数值(4096分之一)
#define SERVOMAX 590 // 舵机最大脉冲长度计数值(4096分之一)
// 定义舵机角度对应的脉宽值
#define SERVO000 130 // 对应于舵机的0度位置,根据具体型号调整此参数
#define SERVO180 520 // 对应于舵机的180度位置,同样需要按实际情况进行修改
// 函数声明部分
void delayms(uint z);
void delayus();
void init(void);
void start(void);
void stop(void);
void ACK(void);
void write_byte(uchar byte);
uchar read_byte();
void PCA9685_write(uchar address, uchar date);
uchar PCA9685_read(uchar address);
// 毫秒级延时函数
void delayms(uint z) {
uint x,y;
for(x = z; x > 0 ;x--)
for(y=148;y>0;y--);
}
// 微妙级别延时函数(大于4.7us)
void delayus() {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
// IIC总线初始化
void init(void) {
sda = 1; // 初始化数据端口为高电平
scl = 1;
delayus();
}
// 发送IIC启动信号函数
void start() {
sda=1;
delayus();
scl=1;
delayus();
sda=0;
delayus();
scl=0;
delayus();
}
// IIC总线停止信号发送函数
void stop() {
sda = 0;
delayus();
scl = 1;
delayus();
sda = 1;
}
// 发送ACK应答信号
void ACK(void) {
uchar i;
scl=1;
delayus();
while((sda==1)&&(i<255))
i++;
scl=0;
delayus();
}
// 写入一个字节的函数,无返回值
void write_byte(uchar byte) {
uchar i,temp;
temp = byte;
for(i = 0 ;i <8;i++) {
temp <<=1;
scl=0;
delayus();
sda=CY;
delayus();
scl=1;
}
scl=0;
delayus();
sda=1;
}
// 从PCA9685读取数据的函数,有返回值
uchar read_byte() {
uchar date;
start();
write_byte(PCA9685_adrr);
ACK();
start();
write_byte((PCA9685_adrr|0x01));
ACK();
date = read_byte();
stop();
return(date);
}
// 向PCA9685写入数据
void PCA9685_write(uchar address, uchar data) {
start();
write_byte(PCA9685_adrr);
ACK();
write_byte(address);
ACK();
write_byte(data);
stop();
}
// 向PCA9685读取数据
uchar PCA9685_read(uchar address) {
uchar data;
start();
write_byte(PCA9685_adrr);
ACK();
start();
write_byte(address);
ACK();
start();
write