硬件 - PCA9685

目录

一、物理特性

二、寄存器表

三、驱动部分


一、物理特性

简介

16通道 12位分辨率 24~1526Hz的PWM输出;
PWM开漏输出;
工作电压2.3V~5.5V 25mA;
输出电流10mA;
SDA最大驱动电流30mA;

内部晶振25MHz;
外部最大晶振50MHz;
-40~85℃工作;

从机地址为 0x80;

框图

二、寄存器表

  • 寄存器表

  • MODE1 (00h)

  • MODE2(01h)
  • Restart Mode
    暂时不使用,具体看DATASHEET

三、驱动部分

数据包

最后一位1读0写

驱动地址
6个硬件引脚
2^6 = 64个软件地址
其中2个(软件复位、LED全呼不可使用)
也就是62个地址可用​

计数器分辨率

简单介绍

在 《1.物理特性》 中,我们有提到计数器分辨率为12;

这里计数器分辨率 的高低,表达可以提供不同的 步长 —— 如12位,可以提供 2^12 = 4,096 的步长,

而 8 位的只能提供 2^8 = 256 的步长;

计数器分辨率与PWM周期

PWM 周期主要受三个参数的影响:Presclaer 、Resolution 、Clock Frequency ;

即为 分频系数、计数器分辨率 、时钟频率;

下面 我们简称为 PRE 、 RES 、CLK;

那么 PWM Period(周期) = CLK /(PRE*RES);

很简单地可以看到,PCA9685 的时钟频率是确定25Mhz,12位(2^12 = 4096);

那么PWM 的周期就可以由 PRE 控制;

PWM的输出和控制

配置PWM

方法:
使用寄存器LEDn_ON和LEDn_OFF来实现,
LEDn_ON是开启高电平的时间点,LEDn_OFF是开启低电平的时间点;

4096为一个周期,//
比如延时10%,占空比为20%
那么Delay = 4096/10 = 409.6 ~ 410 ,
​又因为是从0~4095,所以使用409(199h)
此时LEDn_ON_H 为 0001
LEDn_ON_L 为 1001 1001;

上述过程是开启高电平,下面是在经过20%占空比时间后关闭
占空比20% = 819.2
所以,关闭时间 = 延时 + 占空比 = 410 + 819 - 1 = 1228 = 4CCh(0~4095所以-1)
所以,LEDn_OFF_H 为 0100
LEDn_OFF_L 为 1100 1100

代码
void PCA9685_setPWM(u8 num,u32 on,u32 off)
{
IIC_Start();
IIC_Send_Byte(PCA_Addr); //访问PCA的从机地址
IIC_Wait_Ack();
IIC_Send_Byte(LED0_ON_L+4*num); //根据num来确定LED_ON地址

IIC_Wait_Ack();
IIC_Send_Byte(on&0xFF);
IIC_Wait_Ack();
IIC_Send_Byte(on>>8); //分高低位发送

IIC_Wait_Ack();
IIC_Send_Byte(off&0xFF);
IIC_Wait_Ack();
IIC_Send_Byte(off>>8);
IIC_Wait_Ack();
IIC_Stop();
}

设置频率

方法:
更改PRE_SCALE 寄存器(FEh)实现;
​osc_clock为系统时钟,
​prescale value为写入的值,
​update_rate为我们需要的频率;

​比如,我们要一个50Hz频率的PWM
​则
​prescale value = round( 2500 0000 / ( 4096 * 50) ) - 1 = 121 = 79h
​这里的round是取整的意思
​也可以使用 floor(x+0.5f) (floor向下取整)
​比如prescaleval = 2500 0000;
​prescaleval /= 4096;
​prescaleval /= freq;
​prescaleval -= 1;
​就可以算出值了;

​之后把值给到PRE_SCALE寄存器里去,
​但是有一点要注意,根据官方手册中,在改频率时,MODE1的SLEEP位要置1;

代码
void PCA9685_setFreq(float freq)
{
u8 prescale,oldmode,newmode;
double prescaleval;
prescaleval = 25000000;
prescaleval /= 4096;
prescaleval /= freq;
prescaleval -= 1;
prescale = floor(prescaleval+0.5f);

oldmode = PCA9685_Read(PCA_Model);
newmode = (oldmode&0x7F)|0x10; //复位位置0,再把SLEEP位置1

PCA9685_Write(PCA_Model,newmode);
PCA9685_Write(PCA_Pre,prescale);
PCA9685_Write(PCA_Model,oldmode);
delay_ms(5);
PCA9685_Write(PCA_Model,oldmode|0xa1);//开启自增
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值