当前位置:网站首页>PWM输出模块PCA9685
PWM输出模块PCA9685
2022-08-09 05:02:00 【lilei668】
1.该模块是由NXP公司研发的PWM输出模块
中文简介:
这是一个采用i2c通信 ,内置了PWM驱动器和一个时钟。这意味着,这将和TLC5940系列有很大不同。你不需要不断发送信号占用你的单片机!
它是5V的兼容,这意味着你还可以用3.3V单片机控制并且安全地驱动到6V输出(当你想控制白色或蓝色指示灯用3.4+正电压也是可以的)
6地址选择引脚使你可以把62个驱动板挂在单个i2c总线上,总共有992路PWM输出。那将是非常庞大的资源。
约1.6Khz可调频PWM输出
为步进电机准备输出12位分辨率,这意味着在60Hz的更新率能够达到4us分辨率
可配置的推拉输出或开路输出
输出使能引脚能够快速禁用所有输出
OE引脚一定要至低使能,或者直接接地。
特性:
(1)PCA9685芯片被包裹在小板的中央
(2)电源输入端子
(3) 绿色电源指示灯
(4) 在4组3针连接器中方便你一次插入16个伺服电机(伺服电机的插头稍宽于0.1",所以你可以放4对0.1"的接头)
(5) 接线板上输入的反向极性保护
(6)级联设计
(7)V+线上放置一个大电容(在某些场合你会需要) 外围输入最大电压取决于这个10V1000uf的电容
(8)所有PWM输出线上都放一个220欧姆系列电阻器来保护他们,并能轻易的驱动LED。
电路原理图如下:
从中文简介可知,该模块输出能力足够,完全能达到控制舵机的信号强度要求。
模块程序如下:
#include “pca9685.h”
#include “myiic.h”
#include “delay.h”
#include “math.h”
void pca_write(u8 adrr,u8 data)//向PCA写数据,adrrd地址,data数据
{
IIC_Start_Duoji();
IIC_Send_Byte_Duoji(pca_adrr);
IIC_Wait_Ack_Duoji();
IIC_Send_Byte_Duoji(adrr);
IIC_Wait_Ack_Duoji();
IIC_Send_Byte_Duoji(data);
IIC_Wait_Ack_Duoji();
IIC_Stop_Duoji();
}
u8 pca_read(u8 adrr)//从PCA读数据
{
u8 data;
IIC_Start_Duoji();
IIC_Send_Byte_Duoji(pca_adrr);
IIC_Wait_Ack_Duoji();
IIC_Send_Byte_Duoji(adrr);
IIC_Wait_Ack_Duoji();
IIC_Start_Duoji();
IIC_Send_Byte_Duoji(pca_adrr|0x01);
IIC_Wait_Ack_Duoji();
data=IIC_Read_Byte_Duoji(0);
IIC_Stop_Duoji();
return data;
}
void pca_setfreq(float freq)//设置PWM频率
{
u8 prescale,oldmode,newmode;
double prescaleval;
freq *= 0.92;
prescaleval = 25000000;
prescaleval /= 4096;
prescaleval /= freq;
prescaleval -= 1;
prescale =floor(prescaleval + 0.5f);
oldmode = pca_read(pca_mode1);
newmode = (oldmode&0x7F) | 0x10; // sleep
pca_write(pca_mode1, newmode); // go to sleep
pca_write(pca_pre, prescale); // set the prescaler
pca_write(pca_mode1, oldmode);
delay_ms(2);
pca_write(pca_mode1, oldmode | 0xa1);
}
void pca_setpwm(u8 num, u32 on, u32 off)
{
pca_write(LED0_ON_L+4num,on);
pca_write(LED0_ON_H+4num,on>>8);
pca_write(LED0_OFF_L+4num,off);
pca_write(LED0_OFF_H+4num,off>>8);
}
/num:舵机PWM输出引脚015,on:PWM上升计数值04096,off:PWM下降计数值0~4096
一个PWM周期分成4096份,由0开始+1计数,计到on时跳变为高电平,继续计数到off时
跳变为低电平,直到计满4096重新开始。所以当on不等于0时可作延时,当on等于0时,
off/4096的值就是PWM的占空比。/
/*
函数作用:初始化舵机驱动板
参数:1.PWM频率
2.初始化舵机角度
/
void PCA_MG9XX_Init(float hz,u8 angle)
{
u32 off=0;
IIC_Init_Duoji();
pca_write(pca_mode1,0x0);
pca_setfreq(hz);//设置PWM频率
off=(u32)(145+angle2.4);
pca_setpwm(0,0,off);pca_setpwm(1,0,off);pca_setpwm(2,0,off);pca_setpwm(3,0,off);
pca_setpwm(4,0,off);pca_setpwm(5,0,off);pca_setpwm(6,0,off);pca_setpwm(7,0,off);
pca_setpwm(8,0,off);pca_setpwm(9,0,off);pca_setpwm(10,0,off);pca_setpwm(11,0,off);
pca_setpwm(12,0,off);pca_setpwm(13,0,off);pca_setpwm(14,0,off);pca_setpwm(15,0,off);
delay_ms(500);
}
/*
函数作用:控制舵机转动;
参数:1.输出端口,可选0~15;
2.起始角度,可选0~180;
3.结束角度,可选0~180;
4.模式选择,0 表示函数内无延时,调用时需要在函数后另外加延时函数,且不可调速,第五个参数可填任意值;
1 表示函数内有延时,调用时不需要在函数后另外加延时函数,且不可调速,第五个参数可填任意值;
2 表示速度可调,第五个参数表示速度值;
5.速度,可填大于 0 的任意值,填 1 时速度最快,数值越大,速度越小;
注意事项:模式 0和1 的速度比模式 2 的最大速度大;
/
void PCA_MG9XX(u8 num,u8 start_angle,u8 end_angle,u8 mode,u8 speed)
{
u8 i;
u32 off=0;
switch(mode)
{
case 0:
off=(u32)(158+end_angle2.2);
pca_setpwm(num,0,off);
break;
case 1:
off=(u32)(158+end_angle2.2);
pca_setpwm(num,0,off);
if(end_angle>start_angle){delay_ms((u16)((end_angle-start_angle)2.7));}
else{delay_ms((u16)((start_angle-end_angle)2.7));}
break;
case 2:
if(end_angle>start_angle)
{
for(i=start_angle;i<=end_angle;i++)
{
off=(u32)(158+i2.2);
pca_setpwm(num,0,off);
delay_ms(2);
delay_us(speed250);
}
}
else if(start_angle>end_angle)
{
for(i=start_angle;i>=end_angle;i–)
{
off=(u32)(158+i2.2);
pca_setpwm(num,0,off);
delay_ms(2);
delay_us(speed*250);
}
}
break;
}
}
因为这次需要挂载多个IIC模块,所有对IIC程序进行了修改,myiic.c:
#include “myiic.h”
#include “delay.h”
#include “main.h”
#include “stm32f1xx_hal.h”
#include “dma.h”
#include “tim.h”
#include “usart.h”
#include “gpio.h”
//初始化IIC
void IIC_Init_Duoji(void)
{
GPIO_SetBits(GPIOC,GPIO_PIN_11|GPIO_PIN_12); //PB6,PB7 输出高
}
//产生IIC起始信号
void IIC_Start_Duoji(void)
{
SDA_OUT_Duoji(); //sda线输出
IIC_SDA_Duoji=1;
IIC_SCL_Duoji=1;
delay_us(4);
IIC_SDA_Duoji=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL_Duoji=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop_Duoji(void)
{
SDA_OUT_Duoji();//sda线输出
IIC_SCL_Duoji=0;
IIC_SDA_Duoji=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL_Duoji=1;
IIC_SDA_Duoji=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack_Duoji(void)
{
u8 ucErrTime=0;
SDA_IN_Duoji(); //SDA设置为输入
IIC_SDA_Duoji=1;delay_us(1);
IIC_SCL_Duoji=1;delay_us(1);
while(READ_SDA_Duoji)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop_Duoji();
return 1;
}
}
IIC_SCL_Duoji=0;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack_Duoji(void)
{
IIC_SCL_Duoji=0;
SDA_OUT_Duoji();
IIC_SDA_Duoji=0;
delay_us(2);
IIC_SCL_Duoji=1;
delay_us(2);
IIC_SCL_Duoji=0;
}
//不产生ACK应答
void IIC_NAck_Duoji(void)
{
IIC_SCL_Duoji=0;
SDA_OUT_Duoji();
IIC_SDA_Duoji=1;
delay_us(2);
IIC_SCL_Duoji=1;
delay_us(2);
IIC_SCL_Duoji=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte_Duoji(u8 txd)
{
u8 t;
SDA_OUT_Duoji();
IIC_SCL_Duoji=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA_Duoji=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL_Duoji=1;
delay_us(2);
IIC_SCL_Duoji=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte_Duoji(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN_Duoji();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL_Duoji=0;
delay_us(2);
IIC_SCL_Duoji=1;
receive<<=1;
if(READ_SDA_Duoji)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck_Duoji();//发送nACK
else
IIC_Ack_Duoji(); //发送ACK
return receive;
}
myiic.h程序如下:
#ifndef __MYIIC_H
#define __MYIIC_H
#include “sys.h”
/以下是舵机控制板的IIC驱动底层代码/
//IO方向设置
#define SDA_IN_Duoji() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
#define SDA_OUT_Duoji() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}
//IO操作函数
#define IIC_SCL_Duoji PCout(12) //SCL
#define IIC_SDA_Duoji PCout(11) //SDA
#define READ_SDA_Duoji PCin(11) //输入SDA
//IIC所有操作函数
void IIC_Init_Duoji(void); //初始化IIC的IO口
void IIC_Start_Duoji(void); //发送IIC开始信号
void IIC_Stop_Duoji(void); //发送IIC停止信号
void IIC_Send_Byte_Duoji(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte_Duoji(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack_Duoji(void); //IIC等待ACK信号
void IIC_Ack_Duoji(void); //IIC发送ACK信号
void IIC_NAck_Duoji(void); //IIC不发送ACK信号
/以下是测距1模块的底层驱动代码/
/以下是测距2模块的底层驱动代码/
#endif
边栏推荐
- 【暑期每日一题】洛谷 P1048 [NOIP2005 普及组] 采药
- Openresty执行lua脚本
- uboot中board_init bi_arch_number在哪
- Eureka-Server------单节和集群的搭建
- 剑指Offer-二维动态规划问题题目总结
- Address Book (File Version) (C Language) (VS)
- mysql content does not exist error
- 2022年8月深圳产品经理认证招生简章(NPDP)
- 降压模块的使用
- Parameters in dynamic libraries cannot be modified through macro definitions or global variables in header files
猜你喜欢
软件测试的方法详细介绍
【MLT】MLT多媒体框架生产消费架构解析(二)
STM32的Cube学习笔记(ADC)
数字化时代,企业为什么需要商业智能BI
保存Simulink仿真模型为图片或者PDF的方法
【Harmony OS】【ArkUI】ets开发 图形与动画绘制
【Harmony OS】【ARK UI】Date 基本操作
Masked AutoEncoder论文及实现
降压模块的使用
【HMS core】【Ads Kit】Huawei Advertising——Overseas applications are tested in China. Official advertisements cannot be displayed
随机推荐
Quantitative Genetics Heritability Calculation 2: Half Siblings and Full Siblings
【Harmony OS】【ARK UI】Date Basic Operation
dsafasfdasfasf
数据库事务&锁机制
php uses phpoffice/phpspreadsheet to import and export excel tables
STM32的Cube学习笔记(ADC)
`数学` 极限, 渐进分析, 近似阶, 线性化, 线性近似, 线性函数
如何剪裁svg并压缩
perl基础语法归纳
leetcode:315. 计算右侧小于当前元素的个数
uboot中board_init bi_arch_number在哪
JS-DOM-全局、局部、隐式变量,数组()\函数、 prompt输入对话框、confirm(确定用户的决定-弹出对话框)
FastDFS快速使用及介绍
【Harmony OS】【ARK UI】Date 基本操作
【Harmony OS】【ARK UI】ETS 上下文基本操作
Software testing method is introduced in detail
通讯录(文件版)(C语言)(VS)
2022年8月深圳产品经理认证招生简章(NPDP)
【LeetCode】169. 多数元素
【学习笔记】AGC044