PCA9685使用笔记[16路PWM拓展芯片]

PCA9685引脚图

两种封装,用起来都一样

引脚功能

A0~A5:用于IIC地址选择,上图
在这里插入图片描述
默认情况下A0~A5都接地,即地址为0x40(0b01000000),由于IIC的最低位是读写位所以需要左移一位即0x80(0b10000000)
#OE:使能位,低电平有效
extclk:外部时钟引脚
vdd:器件内部的工作电压 支持2.5 V~5.5 V
vss:公共接地端
LED0~LED15:输出引脚
SDA/SCL:IIC通信引脚

寄存器配置

MODE1寄存器(0x00)

在这里插入图片描述
需要注意的就下面这几位
bit7->RESTART:重启
bit6->EXTCLK:选择是否使用外部时钟
bit5->AI:设置是否自增,要输出PWM波形这位肯定得是1了
bit0->ALLCALL:未级联多块芯片就不管,级联多个且需要同时控制时才置1

PRE_SCALE寄存器(0xFE)

用于设置工作频率,计算公式
在这里插入图片描述
内部系统时钟为25MHz即osc_clock = 25MHz
update_rate:想要设置的频率,可设置范围为24~1526Hz对应寄存器值为(0xff-0x03)
注意:需要向上取整

LEDx_ON_L/LEDx_ON_H/LEDx_OFF_L/LEDx_OFF_H 寄存器(LED0->0x06-0x09 LED15->0x06+(154)-0x09+(154))

用于设置对应引脚的占空比,PCA9685是12位分辨率即0~4095
不需要两个一起设置,只需要设置其中一个即LEDx_ON_L/LEDx_ON_H或者LEDx_OFF_L/LEDx_OFF_H

写懵了,上代码

/******************************
	*	函数名:PCA9685_Init
	*	参数:无
	*	作用:PCA9685初始化
******************************/
void PCA9685_Init(void)
{
	DEV_IIC_Init(0x00,400000);	//初始化IIC
	delay_ms(2);						//怕出意外,休息一下
	IIC_SendData(PCA9685_adrr, PCA9685_MODE1, 0x00);//退出SLEEP模式
	delay_ms(2);
	IIC_SendData(PCA9685_adrr, PCA9685_MODE1, 0x80);//复位MODE1寄存器
	delay_ms(2);
	setPWMFreq(1000);	//设置频率
}

/******************************
	*	函数名:setPWMFreq
	*	参数:freq	频率范围->24-1526(Hz)
	*	作用:设置工作频率	prescaleval=round(25M/4096/freq)-1;
******************************/
void setPWMFreq(float freq) 
{
	uint8_t prescale;
	float prescaleval;
	
	freq *= 0.95f;	//纠正频率设置中的过冲,进行校准
	
	//prescaleval=round(25M/4096/freq)-1;	
	prescaleval = 25000000.0f;
	prescaleval /= 4096;
	prescaleval /= freq;
	prescaleval -= 1;
	prescale = (uint8_t)(prescaleval + 0.5f);//向上取整

	PCA9685_SendData(PCA9685_MODE1, 0x10);  	  //进入SLEEP模式
	delay_ms(2);
	PCA9685_SendData(PCA9685_PRESCALE, prescale);    //设置频率
	PCA9685_SendData(PCA9685_MODE1, 0x00);		  //退出SLEEP模式
	delay_ms(2);
	PCA9685_SendData(PCA9685_MODE1, 0xA0); //RESTART、AI 置1
	delay_ms(500);//一定得延时 否则修改不了
}

/******************************
	*	函数名:Set_Duty
	*	参数:channel	通道范围->1~16
	*				on	高电平时间范围->0~4095
	*	作用:设置占空比
******************************/
void Set_Duty(uint8_t channel, uint16_t on)
{
	uint8_t data[4];
	on = on > 4095 ? 4095 : on;	//设置为4096理论来说是没什么问题的,但实际测试不得行
	on = 4095 - on;							//实际设置的是低电平的时间,之前设置高电平的时间有点小问题
	data[0] = 0;								//这点是LEDx_ON_L寄存器的值
	data[1] = 0;								//这点是LEDx_ON_L寄存器的值
	data[2] = on&0xff;					//这点是LEDx_OFF_L寄存器的值
	data[3] = on>>8;						//这点是LEDx_OFF_H寄存器的值
	PCA9685_SendDatas(LED0_ON_L+4*channel, data, 4);//因为每通道的地址相差4,所以+4*channel
	delay_ms(1);								//怕出意外,休息哈
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余十三_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值