快充芯片IP5328P的寄存器数据读写[用于DIY数显快充充电宝]

news/2024/10/30 17:26:19/

【本帖DIY因为有一定的危险性,非专业人员请勿自行尝试】 【如有侵权   联系删除】

IP5328P是一款最大18W的快充芯片,主要用于快充充电宝的产品,基本支持市面上绝大部分主流的快充协议。

因为能看到本帖的想必都是对这个芯片很了解了,所以就不过多赘述了,接下详细介绍此贴的由来、过程及结果。[后面我会附加此芯片的中文手册,不了解的可以看手册]

★缘起:

在某宝捡电子垃圾时偶然发现一款快充充电板的尾料在低价售卖,虽是18年的产品,但是相比同参数新品快充板的几十块钱来说,这个板子的3.8元那可简直是太香了。又因本人有几个普通充电宝,充电速度相对于快充充电器实在是缓慢至极,故平时极少使用,如果拿来改装为快充充电宝岂不快哉!

★过程及改装方法:

对于DIY,如果是仅仅将电路板连接到电池上,那就太拉跨了。电路板自带4个led灯做为电量显示,显然对这一设计我并不满足,于是乎有了改为数显的想法。在看数据手册的过程中发现IP5328P自带IIC功能,可以读取其内部的各种参数,官方经典的电路(led灯显示模式)如下。在改为IIC时有两种接法,我选择的是IIC模式1,在原来的电路上,将R2和R7去掉,将LED1引脚和LED2引脚分别通过3.3K电阻用芯片的VREG进行上拉。VREG是IP5328P芯片自带的一个3.3V 30ma的LDO输出,在使用IIC模式时,为了保证稳定请尽量使用VREG作为上拉电源,因为在芯片激活时,会首先检测LED1和LED2的电平,如果为高则进入IIC模式。需要注意的是,手册上写着LED3引脚可以接单片机作为唤醒引脚或用来指示是否正在工作,但是此引脚又是设置电池电压的引脚,接入不同的电阻下拉会设置不同的电池电压,实测中如果直接接单片机引脚,会导致电压设置改变,在对4.2V电池进行充电时终止电压并不是4.2V,而是大大高于4.2V,这样是非常危险的,很容易过冲发生爆炸!如果没有万分把握、经过实际测试或其他方式连接,请勿使用此引脚!

重要的事情说3遍:

这样是非常危险的,很容易过冲发生爆炸!

这样是非常危险的,很容易过冲发生爆炸!

这样是非常危险的,很容易过冲发生爆炸!

作为IIC模式使用时,LED1引脚即为IIC的时钟引脚SLK,LED2引脚即为IIC的数据引脚SDA,芯片的IIC读写时序在数据手册可以找的到,很容易看懂,我就不赘述了,直接上代码吧。使用的单片机是大家常用的stm32f103c8t6,SDA连接到PB8,SLK连接到PB9。主要的几个文件如下。

i2c.c[iic的时序驱动文件]

#include "i2c.h"/** I2C 总线接口 */
#define I2C_PORT GPIOB
#define SDA_Pin	GPIO_Pin_8
#define SCL_Pin GPIO_Pin_9#define FAILURE 0
#define SUCCESS 1//配置SDA信号线为输入模式
void SDA_Input_Mode()
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SDA_Pin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	 GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}//配置SDA信号线为输出模式
void SDA_Output_Mode()
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SDA_Pin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}//
void SDA_Output( uint16_t val )
{if ( val ) {GPIO_SetBits(I2C_PORT,SDA_Pin);} else {GPIO_ResetBits(I2C_PORT,SDA_Pin);}
}//
void SCL_Output( uint16_t val )
{if ( val ) {GPIO_SetBits(I2C_PORT,SCL_Pin);} else {GPIO_ResetBits(I2C_PORT,SCL_Pin);}
}//
uint8_t SDA_Input()
{return GPIO_ReadInputDataBit( I2C_PORT, SDA_Pin);
}//延时程序
void delay1(unsigned int n)
{unsigned int i;for ( i=0;i<n;++i);
}//I2C总线启动
void I2CStart(void)
{SCL_Output(0);delay1(500);SDA_Output(1);delay1(500);SCL_Output(1);delay1(500);SDA_Output(0);delay1(500);SCL_Output(0);delay1(500);
}//I2C总线停止
void I2CStop(void)
{SCL_Output(0); delay1(500);SDA_Output(0); delay1(500);SCL_Output(1); delay1(500);SDA_Output(1); delay1(500);}//等待应答
unsigned char I2CWaitAck(void)
{unsigned short cErrTime = 5;SDA_Input_Mode(); delay1(500);SCL_Output(1);delay1(500);while(SDA_Input()){cErrTime--;delay1(500);if (0 == cErrTime){SDA_Output_Mode();
//			I2CStop();return FAILURE;}}SDA_Output_Mode();SCL_Output(0);delay1(500); return SUCCESS;
}//发送应答位
void I2CSendAck(void)
{SDA_Output(0);delay1(500);delay1(500);SCL_Output(1); delay1(500);SCL_Output(0); delay1(500);}//
void I2CSendNotAck(void)
{SDA_Output(1);delay1(500);SCL_Output(1); delay1(500);SCL_Output(0); delay1(500);}//通过I2C总线发送一个字节数据
void I2CSendByte(unsigned char cSendByte)
{unsigned char  i = 8;while (i--){SCL_Output(0);delay1(500); SDA_Output(cSendByte & 0x80); delay1(500);cSendByte += cSendByte;delay1(500); SCL_Output(1);delay1(500); }SCL_Output(0);delay1(500); 
}//从I2C总线接收一个字节数据
unsigned char I2CReceiveByte(void)
{unsigned char i = 8;unsigned char cR_Byte = 0;SDA_Input_Mode(); while (i--){cR_Byte += cR_Byte;SCL_Output(0);delay1(500); delay1(500); SCL_Output(1);delay1(500); cR_Byte |=  SDA_Input(); }SCL_Output(0);delay1(500); SDA_Output_Mode();return cR_Byte;
}//I2C总线初始化
void i2c_init()
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = SDA_Pin | SCL_Pin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 // **GPIO_Init(I2C_PORT, &GPIO_InitStructure);}

i2c.h

#ifndef  __I2C_H__
#define  __I2C_H__#include "stm32f10x.h"void i2c_init(void);
void delay1(unsigned int n);void SCL_Output( uint16_t val );
void SDA_Output( uint16_t val );void I2CStart(void);
void I2CStop(void);
void I2CSendAck(void);
void I2CSendNotAck(void);
unsigned char I2CWaitAck(void);void I2CSendByte(unsigned char cSendByte);
unsigned char I2CReceiveByte(void);#endif

ip5328p.c[IP5328P芯片的读写实现和常用参数获取]

/****                                                              ****/
/****  说明:  根据IP5328P (with reg) V1.0编写                       ****/
/****          寄存器手册来自51黑电子论坛 ID:没有你                   ****/
/****          程序功能并不完全,仅写自认常用功能函数,可自行扩展         ****/
/****  作者:  超级网吧                                               ****/
/****  时间:  2020-10-04                                            ****/
/****                                                               ****/#include "i2c.h"
#include "ip5328p.h"//写寄存器(8bit)
//reg:寄存器地址
//data:待写入数据
void IP5328P_Write(unsigned char reg,unsigned char data)
{I2CStart();		    	//起始信号I2CSendByte(0xEA);		//写从机地址I2CWaitAck();			//等待应答I2CSendByte(reg);	   	//待写入数据寄存器地址I2CWaitAck();			//等待应答I2CSendByte(data);	   	//写入数据I2CWaitAck();			//等待应答I2CStop();				//停止信号
}//读寄存器(8bit)
//reg:寄存器地址
//data:待写入数据
unsigned char IP5328P_Read(unsigned char reg)
{unsigned char R_dat;I2CStart();		    			//起始信号I2CSendByte(0xEA);				//写从机地址I2CWaitAck();					//等待应答(在未收到应答时 未做处理 可自行添加)I2CSendByte(reg);	   			//待写入数据寄存器地址I2CWaitAck();					//等待应答(在未收到应答时 未做处理 可自行添加)I2CStart();						//当作重启信号	I2CSendByte(0xEB);	   			//写入从机地址 开启读操作I2CWaitAck();					//等待应答 (在未收到应答时 未做处理 可自行添加)R_dat=I2CReceiveByte();			//接收8bit数据I2CSendNotAck();				//发送mNACK信号 停止接收I2CStop();						//停止信号return R_dat;
}//读取电池电量显示级别(只能读到对应电量的LED个数)
//返回:0001 1111:4课灯亮  0000 1111:3课灯亮  0000 0111:2课灯亮	0000 0011:1课灯亮
//		0000 0001:放电时低电闪灯 0000 0000:关机
unsigned char IP5328P_Electricity(void)
{int dat;dat=IP5328P_Read(0xDB);	  				//获取电量指示级别return dat;
}/**************************************************读取芯片参数功能函数********************************************************///读取电池两端的真实电压值
//返回float型的电压值(小数)
float IP5328P_BatVoltage(void)
{int dat;float BatVoltage=0.0f;dat=IP5328P_Read(0x64);	  				//获取电池电压低8位BatVoltage += dat;dat=IP5328P_Read(0x65);			 		//获取电池电压高8位BatVoltage = (dat<<8)+BatVoltage;		//高低位合并if(BatVoltage==0xffff) return 0;		//如果读到0xffff,此时芯片未激活 读取值错误BatVoltage = BatVoltage*0.00026855+2.6;	//计算为实际电压值return BatVoltage;
}//读取电池输入或输出电流
//返回float型的电流值(小数)	 单位ma
float IP5328P_BatCurrent(void)
{int dat;float Current=0.0f;dat=IP5328P_Read(0x66);	  				//获取电池电流低8位Current += dat;dat=IP5328P_Read(0x67);			 		//获取电池电流高8位Current = (dat<<8)+Current;				//高低位合并if(Current>32767)Current=65535-Current;	//将负值电流转为正值Current = Current*0.00127883;			//计算为实际电流值return Current;
}//读取电池电压经过电芯内阻和电芯电流进行补偿后的电压
//返回float型的电压值(小数)
float IP5328P_BatOCV(void)
{int dat;float BatVoltage=0.0f;dat=IP5328P_Read(0x7A);	  				//获取电池电压低8位BatVoltage += dat;dat=IP5328P_Read(0x7B);			 		//获取电池电压高8位BatVoltage = (dat<<8)+BatVoltage;		//高低位合并if(BatVoltage==0xffff) return 0;		//如果读到0xffff,此时芯片未激活 读取值错误BatVoltage = BatVoltage*0.00026855+2.6;	//计算为实际电压值return BatVoltage;
}//获取Type-C接口连接状态
//返回:0x00未连接
//		0x01连接手机等需供电设备(充电宝在放电)
//		0x02连接电源适配器(充电宝在充电)
unsigned char IP5328P_TypeC_Flag(void)
{unsigned char flag=0,dat=0;dat=IP5328P_Read(0xB8);if(dat==0xff)return 0;					//如果读到0xff,芯片未激活if(dat>>1&0x01)flag=0x01;if(dat>>5&0x01)flag=0x02;return flag;
}//获取Type-C连接的适配器输出能力
//返回:0x00 芯片未激活
//		0x01标准USB
//		0x02输出能力1.5A
//		0x03输出能力3.0A
unsigned char IP5328P_TypeC_Ability(void)
{unsigned char flag=0,dat=0;dat=IP5328P_Read(0xFF);if(dat==0xff)return 0;					//如果读到0xff,芯片未激活if(dat>>5&0x01)flag=0x01;if(dat>>6&0x01)flag=0x02;if(dat>>7&0x01)flag=0x03;return flag;
}/********************以下电流读取有条件限制*********************************/
/*********大体可以理解为当有多个接口同时开启时才可以读取********************/
/***************其中,VBUS是TYPE-C口,VIN是安卓口***************************///读取Type-C输入或输出电流
//返回float型的电流值(小数)	 单位ma
//条件:需要在充电状态 VINOK 和 VBUSOK 同时有效且 VBUS MOS开启时;
//      或者VBUS MOS开启的同时有其他MOS也开启时,该ADC才会启动
//		(以上符号状态都可用寄存器读取)
float IP5328P_TypeC_Current(void)
{int dat;float Current=0.0f;dat=IP5328P_Read(0x6E);	  				//获取电流低8位Current += dat;dat=IP5328P_Read(0x6F);			 		//获取电流高8位Current = (dat<<8)+Current;				//高低位合并if(Current>32767)Current=65535-Current;	//将负值电流转为正值Current = Current*0.0006394;			//计算为实际电流值return Current;
}//读取安卓口输入电流
//返回float型的电流值(小数)	 单位ma
//条件:需要在充电状态 VINOK 和VBUSOK 同时有效且 VIN MOS开启时该 ADC才会启动
//		(以上符号状态都可用寄存器读取)
float IP5328P_VIN_Current(void)
{int dat;float Current=0.0f;dat=IP5328P_Read(0x6D);	  				//获取电流低8位Current += dat;dat=IP5328P_Read(0x6C);			 		//获取电流高8位Current = (dat<<8)+Current;				//高低位合并if(Current>32767)Current=65535-Current;	//将负值电流转为正值Current = Current*0.0006394;			//计算为实际电流值return Current;
}//读取OUT1输出电流
//返回float型的电流值(小数)	 单位ma
//条件:需要在 OUT1 MOS 开启的同时有其他 MOS 也开启时,该 ADC 才会启动;
//		(以上符号状态都可用寄存器读取)
float IP5328P_OUT1_Current(void)
{int dat;float Current=0.0f;dat=IP5328P_Read(0x70);	  				//获取电流低8位Current += dat;dat=IP5328P_Read(0x71);			 		//获取电流高8位Current = (dat<<8)+Current;				//高低位合并if(Current>32767)Current=65535-Current;	//将负值电流转为正值Current = Current*0.0006394;			//计算为实际电流值return Current;
}//读取OUT2输出电流
//返回float型的电流值(小数)	 单位ma
//条件:需要在 OUT1 MOS 开启的同时有其他 MOS 也开启时,该 ADC 才会启动;
//		(以上符号状态都可用寄存器读取)
float IP5328P_OUT2_Current(void)
{int dat;float Current=0.0f;dat=IP5328P_Read(0x72);	  				//获取电流低8位Current += dat;dat=IP5328P_Read(0x73);			 		//获取电流高8位Current = (dat<<8)+Current;				//高低位合并if(Current>32767)Current=65535-Current;	//将负值电流转为正值Current = Current*0.0006394;			//计算为实际电流值return Current;
}/********************以上电流读取有条件限制*********************************///获取当前电源功率
//返回float型的功率值(小数)
float IP5328P_Power(void)
{int dat;float Power=0.0f;dat=IP5328P_Read(0x7C);	  				//获取功率低8位Power += dat;dat=IP5328P_Read(0x7D);			 		//获取功率高8位Power = (dat<<8)+Power;					//高低位合并if(Power==0xffff) return 0;				//如果读到0xffff,此时芯片未激活 读取值错误Power = Power*0.00844;					//计算为实际功率值return Power;
}//获取芯片当前电源状态
//第四位:0:放电 1:充电
//2:0位 :000:待机 001:5V充电 010:单口同充同放 011:多口同充同放
//		  100:高压快充充电 101:5V放电 110:多口5V放电 111:高压快充放电
//其他位:无效位
unsigned char IP5328P_SYS_Status(void)
{unsigned char flag=0;flag=IP5328P_Read(0xD1);if(flag==0xff)return 0;return flag;
}//获取输入电压有效状态以及按键是否被按下
//返回:7:6无效位
//		5 VBUSOK: 1 TYPE-C接口电压有效(充放电都会有效) 0 接口电压无效
//		4 VINOK : 1 安卓口接口电压有效	                 0 安卓口接口电压无效
//		3:1无效位
//		0 key_in: 0按键按下    1按键未按下
unsigned char IP5328P_KEY_IN(void)
{unsigned char flag=0;flag=IP5328P_Read(0xD2);if(flag==0xff)return 0;return flag;
}//获取安卓口和TYPE-C的输入电压
//返回:7:6无效位
//		5:3  TYPE-C_STATE:000-5V,001-7V,011-9V,111-12V 
//		2:0  VIN_STATE   :000-5V,001-7V,011-9V,111-12V
unsigned char IP5328P_VinTypeC_State(void)
{unsigned char flag=0;flag=IP5328P_Read(0xD5);if(flag==0xff)return 0;return flag;
}//获取充电状态
//返回:7:	0可能刚好是在停充检测,也可能是充满了,也可能是异常保护了	 1 正在充电
//		6:  0未充满  1充满 
//		5:  0恒压恒流总计时未超时   1恒压恒流总计时超时
//		4:  0恒压计时未超时         1恒压计时超时
//		3:  0涓流计时未超时         1涓流计时超时
//		2:0 000空闲  001涓流充电  010恒流充电  011恒压充电 100停充检测 101电池充满结束 110超时
unsigned char IP5328P_GHG_State(void)
{unsigned char flag=0;flag=IP5328P_Read(0xD7);return flag;
}//获取MOS状态
//返回:7:	0当前安卓口在充电	      1当前TYPE-C在充电
//		6:  0安卓口电压无效           1安卓口电压有效  
//		5:  0TYPE-C电压无效           1TYPE-C电压有效 
//		4:  0VIN MOS(安卓)未开启      1VIN MOS(安卓)开启
//		3:  无效位
//		2:  0VBUS MOS(TYPE-C)未开启   1VBUS MOS(TYPE-C)开启
//		1:  0VOUT2 MOS未开启          1VOUT2 MOS开启
//		0:  0VOUT1 MOS未开启          1VOUT1 MOS开启
unsigned char IP5328P_MOS_ON(void)
{unsigned char flag=0;flag=IP5328P_Read(0xE5);if(flag==0xff)return 0;return flag;
}//获取升压输出电压值范围
//返回:7:4	无效位 
//		3:  0无效      1输出电压10-12V
//		2:  0无效      1输出电压8-10V
//		1:  0无效      1输出电压6-8V
//		0:  0非快充    1快充
unsigned char IP5328P_BOOST(void)
{unsigned char flag=0;flag=IP5328P_Read(0xFB);if(flag==0xff)return 0;return flag;
}//获取QC快充是否使能(不是是否正在使用,而是说这个功能可以用)
//返回:7:4	无效位 
//		3:  0非快充      1TYPE-C快充使能
//		2:  0非快充      1安卓口快充使能
//		1:  0非快充      1OUT2快充开使能
//		0:  0非快充      1OUT1快充开使能
unsigned char IP5328P_QC_State(void)
{unsigned char flag=0;flag=IP5328P_Read(0x3E);if(flag==0xff)return 0;return flag;
}//获取快充是否可以被使用(不是是否正在使用,而是说这个功能可以用)
//返回:7:	MTK PE 1.1 RX 支持的最大电压设置       0 12V	       1 9V
//		6:  MTK PE2.0 RX  使能                     0 失能       1 使能 
//		5:  MTK PE1.1 RX  使能                     0 失能       1 使能 
//		4:  SFCP SRC(展讯)使能                     0 失能       1 使能
//		3:  AFC SRC(三星) 使能                     0 失能       1 使能
//		2:  FCP SRC(华为) 使能                     0 失能       1 使能
//		1:  QC3.0 SRC     使能                     0 失能       1 使能
//		0:  QC2.0 SRC     使能                     0 失能       1 使能
unsigned char IP5328P_DCP_DIG(void)
{unsigned char flag=0;flag=IP5328P_Read(0xA2);if(flag==0xff)return 0;return flag;
}/*----------------------------------------------读取芯片参数功能函数-end-----------------------------------------------------*//**************************************************写芯片参数功能函数********************************************************///设置电池低电关机电压(关机后需重新充电才可启动)
//输入:0x30 3.00V-3.10V
//      0x20 2.90V-3.00V
//      0x10 2.81V-2.89V
//      0x00 2.73V-2.81V
void IP5328P_BAT_LOW(unsigned char dat)
{if(dat==0x30||dat==0x20||dat==0x10||dat==0x00)//为保证器件不出错,确认指令正确后在写入IP5328P_Write(0x10,dat);
}//设置SYS4
//输入:chg2bst:拔出充电自动开启升压输出                0不开启  1开启
//      swclk2 :使能I2C2待机时钟(使能后待机可读数据)  0不开启  1开启
//      swclk1 :使能I2C1待机时钟(使能后待机可读数据)  0不开启  1开启
void IP5328P_SYS_CTL14(unsigned char chg2bst,unsigned char swclk2,unsigned char swclk1)
{unsigned char dat=0x00;if(chg2bst)dat|=0x40;if(swclk2)dat|=0x08;if(swclk1)dat|=0x04;IP5328P_Write(0x0E,dat);
}/*------------------------------------------------写芯片参数功能函数-end----------------------------------------------------*//*---------------------------------------------------获取常用参数-----------------------------------------------------------*/float power;															  //总功率
Interface mos_state;	                  //各接口开启状态结构体
Interface current;		          //各接口电流结构体
Interface voltage;			  //各接口电压结构体//获取常用参数
//包括:总功率、各接口电压、各接口电流、各接口开启状态
void read_Parameters(void)
{unsigned char mos,Sys_status,Bat_Grade,GHG_State,TypeC_VIN_voltage,boost;	
/*----------------------------------------------获取参数----------------------------------------------------------*/	mos=IP5328P_MOS_ON();				 									//获取接口状态power=IP5328P_Power();			     									//获取功率TypeC_VIN_voltage=IP5328P_VinTypeC_State();	 							//获取安卓口和TYPE-C电压current.TypeC=IP5328P_TypeC_Current();									//获取Type-C电流值current.VIN=IP5328P_VIN_Current();										//获取VIN电流值current.OUT1=IP5328P_OUT1_Current();									//获取VOUT1电流值current.OUT2=IP5328P_OUT2_Current();									//获取VOUT2电流值boost=IP5328P_BOOST();													//获取升压值
//	Sys_status=IP5328P_SYS_Status();										//获取系统状态
//	Bat_Grade=IP5328P_Electricity();										//获取电量等级
//	GHG_State=IP5328P_GHG_State();											//获取充电状态
/*--------------------------------------------处理接口状态--------------------------------------------------------*/mos_state.OUT1=mos&0x01;												//获得OUT1开启状态 [因为按下按键激活时,OUT1会开启输出,但可能并没有连接]mos_state.OUT2=mos>>1&0x01;												//获得OUT2开启状态mos_state.TypeC=mos>>2&0x01;											//获得TypeC开启状态mos_state.VIN=mos>>4&0x01;												//获得VIN开启状态if(mos_state.OUT1)														//纠正OUT1开启状态 [因为按下按键激活时,OUT1会开启输出,但可能并没有连接]{if(power<=0.2)mos_state.OUT1=0;										//如果功率为0则未连接if(power>0)															//如果功率>0if(mos_state.OUT2||mos_state.TypeC||mos_state.VIN)				//且有其他接口开启if(current.OUT1==0)mos_state.OUT1=0;						//如果OUT1电流还是为0,则证明OUT1接口实际未开启}
/*--------------------------------------------处理接口电压--------------------------------------------------------*/if(mos_state.VIN){														//如果VIN接口是开启的switch(TypeC_VIN_voltage&0x07)										//VIN电压{case 0x07:voltage.VIN=12;break;									//12Vcase 0x03:voltage.VIN=9;break;									//9Vcase 0x01:voltage.VIN=7;break;									//7Vcase 0x00:voltage.VIN=5;break;									//5V}																	}else voltage.VIN=0;													//其他if(mos_state.TypeC){													//如果TYPE-C接口是开启的switch(TypeC_VIN_voltage>>3&0x07)									//TYPE-C电压{case 0x07:voltage.TypeC=12;break;								//12Vcase 0x03:voltage.TypeC=9;break;								//9Vcase 0x01:voltage.TypeC=7;break;								//7Vcase 0x00:voltage.TypeC=5;break;								//5V}}else voltage.TypeC=0;													//其他if(mos_state.OUT1){														//如果接口开启if(current.OUT1)voltage.OUT1=5;										//如果接口有电流else{																//如果接口无电流if(boost>1&0x01)voltage.OUT1=5;								//电压值就是升压值if(boost>2&0x01)voltage.OUT1=9;								//电压值就是升压值if(boost>3&0x01)voltage.OUT1=12;								//电压值就是升压值}																	}else voltage.OUT1=0;													//如果接口未开启if(mos_state.OUT2){														//如果接口开启if(current.OUT2)voltage.OUT2=5;										//如果接口有电流else{																//如果接口无电流if(boost>1&0x01)voltage.OUT2=5;								//电压值就是升压值if(boost>2&0x01)voltage.OUT2=9;								//电压值就是升压值if(boost>3&0x01)voltage.OUT2=12;								//电压值就是升压值}																	}else voltage.OUT2=0;													//如果接口未开启
/*--------------------------------------------处理接口电流--------------------------------------------------------*/if(current.OUT1==0&&mos_state.OUT1)current.OUT1=power/voltage.OUT1;		//如果电流为0,可能是仅插入一个接口,此时电流需要用功率换算if(current.OUT2==0&&mos_state.OUT2)current.OUT2=power/voltage.OUT2;		//如果电流为0,可能是仅插入一个接口,此时电流需要用功率换算if(current.TypeC==0&&mos_state.TypeC)current.TypeC=power/voltage.TypeC;	//如果电流为0,可能是仅插入一个接口,此时电流需要用功率换算if(current.VIN==0&&mos_state.VIN)current.VIN=power/voltage.VIN;			//如果电流为0,可能是仅插入一个接口,此时电流需要用功率换算
/*--------------------------------------------处理xxxx--------------------------------------------------------*/}/*---------------------------------------------------获取常用参数-----------------------------------------------------------*/

ip5328p.h

#ifndef  __IP5328P_H__
#define  __IP5328P_H__extern float power;				//总功率typedef struct{unsigned char OUT1;		   	//OUT1接口unsigned char OUT2;		   	//OUT2接口unsigned char TypeC;	   	        //TypeC接口unsigned char VIN;		   	//VIN(安卓口)
}Interface;extern Interface mos_state;	                //各接口开启状态结构体
extern Interface current;			//各接口电流结构体
extern Interface voltage;			//各接口电压结构体//基础操作函数
void IP5328P_Write(unsigned char reg,unsigned char data);     //写IP5328P寄存器数据
unsigned char IP5328P_Read(unsigned char reg);                //读IP5328P寄存器数据//功能函数
/**************************************读参数*****************************************************************/
float IP5328P_BatVoltage(void);		 						 //读电池两端电压值
float IP5328P_BatOCV(void);									 //电池电压经过电芯内阻和电芯电流进行补偿后的电压
float IP5328P_BatCurrent(void);								 //读取电池电流
float IP5328P_TypeC_Current(void);							 //读取TYPE-C输入输出电流
float IP5328P_VIN_Current(void);							 //读取安卓口的输入电流
float IP5328P_OUT1_Current(void);							 //读取OUT1输出电流
float IP5328P_OUT2_Current(void);							 //读取OUT2输出电流
float IP5328P_Power(void);									 //获取功率
unsigned char IP5328P_TypeC_Flag(void);						 //获取Type-C接口连接状态
unsigned char IP5328P_TypeC_Ability(void);					 //获取Type-C连接的适配器输出能力
unsigned char IP5328P_Electricity(void);					 //获取电量指示级别
unsigned char IP5328P_SYS_Status(void);						 //获取电源状态
unsigned char IP5328P_VinTypeC_State(void);				 	 //获取安卓口和TYPE-C的输入电压
unsigned char IP5328P_GHG_State(void);						 //获取充电状态
unsigned char IP5328P_MOS_ON(void);							 //获取MOS开启状态
unsigned char IP5328P_BOOST(void);							 //获取升压输出电压值范围
unsigned char IP5328P_QC_State(void);						 //获取QC快充是否使能(不是是否正在使用,而是说这个功能是否可以用)
unsigned char IP5328P_DCP_DIG(void);						 //获取获取快充是否使能(不是是否正在使用,而是说这个功能是否可以用)/**************************************写参数*****************************************************************/
void IP5328P_BAT_LOW(unsigned char dat);	 				 //设置电池低电关机电压
void IP5328P_SYS_CTL14(unsigned char chg2bst,unsigned char swclk2,unsigned char swclk1);//设置SYS4/***********************************获取常用参数***************************************************************/
void read_Parameters(void);															 #endif

使用时可以这样,如:

#include "lcd.h"
#include "delay.h"
#include "ip5328p.h"
#include "i2c.h"void main(void)
{LCD_Init();    //LCD初始化i2c_init();Show_Str(0,30,BLUE,BLACK," OUT2   TYPE-C    VIN    OUT1",16,0);while(1){read_Parameters();    //获取参数/*-----------------------------------获取电池电压电流----------------------------------*/sprintf(buf, "BAT:%1.2fV  %1.2fA", IP5328P_BatVoltage(),IP5328P_BatCurrent());						//电池两端的电压和电流Show_Str(0,0,BLUE,BLACK,buf,16,0);
/*-----------------------------------接口状态--------------------------------------*/		sprintf(buf, "  %1d      %1d        %1d      %1d  ",mos_state.OUT2,mos_state.TypeC,mos_state.VIN,mos_state.OUT1);		Show_Str(0,50,BLUE,BLACK,buf,16,0);
/*-----------------------------------获取接口电压----------------------------------*/sprintf(buf, " %2dV    %2dV      %2dV    %2dV",voltage.OUT2,voltage.TypeC,voltage.VIN,voltage.OUT1);Show_Str(0,70,BLUE,BLACK,buf,16,0);
/*-----------------------------------获取电池电压电流----------------------------------*/sprintf(buf, " %1.2fA  %1.2fA    %1.2fA  %1.2fA",current.OUT2,current.TypeC,current.VIN,current.OUT1);Show_Str(0,90,BLUE,BLACK,buf,16,0);
/*-----------------------------------获取电源功率----------------------------------*/sprintf(buf, "Power:%2.1fW   ",power);Show_Str(150,0,BLUE,BLACK,buf,16,0);delay_ms(100);}
}

★结果:

外壳是花4块钱买的,电池用了5节2600mAh的18650,壳子上的孔是用打磨文玩那种手持小电磨钻的,屏幕是135*240的IPS彩屏,加了个开关机电路[真开关机,直接断电那种],用一个按键控制,按下按键开机等待10S自动断电。实际测试中,TYPE-C给充电宝充电能达到稳定的16W,OUT1输出给手机能到18W,虽然数据是通过芯片寄存器读出的,准确性未知,但是最起码基本满足了数据手册的标称值。不过在给手机充电时,确实也是很快的,与我手机的快充充电器并无二致[本人手机也是18W快充的,所以此快充板完全满足我的使用需求]。

具体的程序和资料我放到了gitee上,保证所有人都可以免费下载:https://gitee.com/chaojiwangba/IP5328P

 

 

 


http://www.ppmy.cn/news/282009.html

相关文章

pd快充的电压和电流_实测绿联PD直充、充电宝、车充,全方位快充的神仙体验...

越来越多的智能产品都支持快充了,苹果在iPhone 8开始也加入了快充的行列,自从有了PD快充套装之后,充电效率得到了不少提升,30分钟充电50%的体验,大多数人体验后就很难再回得去了。 苹果官方正式宣布开放了Type-C转Lightning的授权,让果粉享受PD快充有了更多的选择, 国内…

开源 AI 面临的挑战

译者&#xff1a;明明如月 人工智能的代价 尽管我坚信开源人工智能将继续蓬勃发展&#xff0c;但我也认为未来几年企业和政府将越来越有动机限制对新型神经网络架构和技术的应用。本文旨在预测并概述可能在本十年发生的潜在颠覆性变革&#xff0c;并提出一些想法和解决方案&a…

ssm本地上传文件

SSM实现图片本地上传并保存到本地磁盘中 功能描述 实现房屋租赁网站中添加房屋信息的功能。其中add.jsp页面是一个表单提交信息——添加房屋 首先输入房屋的相关信息&#xff0c;并上传房屋的图片。上传成功后会将图片的名字添加到数据库中成功后跳转到success.jsp&#xff…

c++ error:C2504 提示未定义基类

【背景】 说明&#xff1a;如何打开1处&#xff0c; 注释掉3&#xff0c;则会提示4的错误。如果注释掉1&#xff0c;打开3&#xff0c;则正确。总之&#xff0c;在定义函数中将基类的头文件放在 子类前&#xff0c;很简单&#xff0c;但一不小心很容易出错误。

没错,这就是AIR-CT2504-K9的内心!

WLC2504目前已经是思科一款比较老的无线控制器了。其体积小巧&#xff0c;非常适用于小型无线网络或分支机构无线部署场景&#xff0c;它最多支持75个AP&#xff0c;Release8.5版本也基本上就是它的最后一个版本了。 但是由于其带宽的限制&#xff0c;可能不能很好的发挥出某些…

error C2504: “CDialogEx”: 未定义基类-报错解决

当MFC写下如下代码 Dlg d; //Dlg为可视化界面的类 Dlg.DoModal();就会出现 Dlg class类没有DoModal error C2504: “CDialogEx”: 未定义基类-报错解决 在MFC文件中添加资源窗口&#xff0c;后添加新类 随后在h头文件中出现 CDialogEx C class 未定义基类 添加 #include "…

错误C2504:继承未定义基类

错误C2504&#xff1a;继承未定义基类&#xff0c;头文件相互包含

3年经验面试20K+测试岗,看到这样的面试题我懵了....

我要跳槽&#xff01;我是着急忙慌的准备简历——3年软件测试经验&#xff0c;可独立测试大型产品项目&#xff0c;熟悉项目测试流程...薪资要求&#xff1f;3年测试经验起码能要个20K吧 我加班肝了一页半简历&#xff0c;投出去一周&#xff0c;面试电话倒是不少&#xff0c;…