写在前面:第一次写博客,格式什么的都不懂,各位看客酌情参考。之前博主在正点原子曾发过求助文章未得到回应,后面自己慢慢摸索有了一定的结论,距今已有3年余,今日重新编辑博客是因为许多朋友加到我微信讨论相关配置及操作,索性写在这里供大家参考。

1、概述: 

独立式电量计DS2781,由Dallas于2006年推出,计算1节或2节Li+和Li+聚合物电池组的剩余电量,并直接由2.5V至10V电源供电。该器件完成16位电流测量,以及11位电压和温度测量。片上非易失存储器用于存储电池的特性数据和应用参数。DS2781采用这些测量数据和存储的数据计算剩余电池电量。此外,片内算法和状态报告功能减少了器件和主机处理器之间需要的交互访问量。因此软件开发大大简化。
DS2781通过计算低阻值检流电阻两端的压降来测量电流。编程功能可对检流电阻进行补偿,以校正整个温度范围内检流电阻的阻值变化。因此可以采用较低成本的检流电阻,而不会影响电流的测量精度。为进一步提高电流测量精度,DS2781还提供自动电流失调校准和用户可编程增益补偿。此外,DS2781包含40字节EEPROM:24字节用于存储电池特性数据和应用参数,16字节供主机系统或电池组制造商使用。器件和主机之间通过1-Wire®接口进行通信,将电池组的接点减少为单根线。

 

2、详细内容:

我之前做开发时大部分为英文原文档,今天去美信官网找到了中文翻译手册,大家读起来应该会更爽一点。具体内容不在这里赘述,大家自行阅读。

关于DS2781的操作流程有几个注意点:
1、每个电量芯片在配置完成后对应一个电池,一一对应的,若更换其中任意一个需要重新建模。
2、电量建模。
3、自学习。
关于电量建模:有两种那个方式:
    方法一:使用美信提供的上位机软件及评估板(可以自己画)一键配置;此种方法使用一劳永逸,上位机自动生成空电量满电量等参数并直接写入到DS2781的EEPROM中。
    方法二:自行建模,此方法需要通过单总线方式将相关建模参数写入相应的EEPRO中。这种方式建模难度很大, 博主当时是使用了3000mAh的电池,建模时跟电池方面的大佬沟通后的预估值,这种方式在后期的应用中误差很大。 故而不建议使用。
关于自学习:建模完成后很重要
    其实很多朋友在建模完成后发现读出来的数据全是0XFFFF,其中有一个原因就是没有进行自学习。

附中文版数据手册DS2781_DATASHEET_中文版

评估板上位机软件下载

3、硬件设计

 图中DATA为单总线通信口,
RSNS1为采样电阻,PACK+为外部接口,J5为电池接口
其中PACK+接口需要使充电输入端(充电)与外部网络输入端(放电)并联此处(语言能力实在是差),使电量芯片能始终监视电池充电和放电。

4、软件设计

早些年写代码也不规范,大家将就看看


/********************************************************************
module function :electric power manage
Author:罗黛心言
Creation date:2018.08.27
Modification content and date:
********************************************************************/

#include "PowerDS2781.h"
#include "cmsis_os.h"
#include <string.h>
/********************************************************************
pin41 PA8
********************************************************************/

uint8_t  DS_IO_READ() 	{return(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5));}
BAT DS2781;
/********************************************************************
function name:     			void DS_Rset()
function performance:		reset pulse
suction parameter: 
outlet parameters:			
remark:									标准	 
********************************************************************/
void DS_Init_IO(void)
{ 
    GPIO_InitTypeDef GPIO_InitStruct;	//	
	__HAL_RCC_GPIOA_CLK_ENABLE();
	GPIO_InitStruct.Pin = GPIO_PIN_5;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}



uint8_t Init_DS(void)
{
	if(DS_Check()) 
		return(1);   //初始化失败!
	
	DS_Write_Byte(0xCC);
	return (0);
}

void DS_Init(void)
{
	DS_Init_IO();   //拉高总线,推完输出  高电平	
	while(Init_DS())
	{
		DS_IO_OUT();
		DS_OUT_High();
		delay_xms(1);   //延时1ms
	}
}

uint16_t  highspeed()
{
	uint16_t data = 0;
	Write_data(0x62,0x02);
	copy_data_ds2780(0x62);
	recall_data_ds2780(0x62);
	data = Read_byte_data(0x62);
	return (data);
}

void DS_Rset(void)
{
	DS_IO_OUT();
	DS_OUT_Low();
	delay_us(T_RSTL);// 800us
}

/********************************************************************
function name:     			uint8_t DS_Check(void)
function performance:		Power Meter chip detection
suction parameter: 
outlet parameters:			return 1:no sensor; return 0:a sensor;
remark:						 
********************************************************************/
uint8_t DS_Check(void)
{
	uint8_t retry = 0,tlow =0;
	DS_Rset();     //拉低800us
	DS_IO_IN();    //等待总线拉高  进入接收模式
	
	while((DS_IO_READ())&&(retry < T_PDH))   //拉低总线,同时等待T_PDH的长时间
	{
		retry++;
		delay_us(1);
	}
	if(retry>=T_PDH)
		return(1);

	while((!DS_IO_READ())&&(tlow <= T_wait)) //脉冲响应 低电平240us
	{
		tlow++;
		delay_us(1);
	}
	
	if(tlow > T_wait)
		return(1);
	delay_us(T_RSTH - tlow-retry);
	return(0);


}

/********************************************************************
function name:     			uint8_t DS_Readbit(void)
function performance:		read data of bit
suction parameter: 
outlet parameters:			return data
remark:						 
********************************************************************/
uint8_t DS_ReadBit(void)
{
	uint8_t data = 0;
	
	DS_IO_OUT();
	DS_OUT_Low();             //下降沿启动读有效
	delay_us(2);              //延时2us
	DS_IO_IN();               //释放总线
	delay_us(8);              //延时8us
	data = DS_IO_READ()&0X01; //读数据	
	delay_us(T_SLOT-T_RDV);	  //等待时隙结束
	return (data);
}

/********************************************************************
function name:     			uint8_t DS_ReadByte(void)
function performance:		read data of byte
suction parameter: 
outlet parameters:			return data
remark:						 
********************************************************************/
uint8_t DS_ReadByte(void)
{
	uint8_t i = 0,data = 0;	

	for(i=0;i<8;i++)
	{
		data>>=1;
		if(DS_ReadBit())
		data |= 0x80;
	}

	return (data);	
}

void DS_Write_Bit(uint8_t Bbit)
{	
	DS_IO_OUT();
	DS_OUT_Low();//下降沿启动写有效
	if(Bbit)     //写 1 
	{
		delay_us(T_LOW1);         //延时拉高时间 10us
		DS_OUT_High();            //拉高电平 必须保证 15us~60us的时间让DS2781采样,因此在15us之前就要拉高数据总线,置1操作;
		delay_us(T_SLOT-T_LOW1);  //保证采样时间的完整性 T_SLOT= 100us
		DS_IO_IN();               //释放总线
	}
	else 
	{
		delay_us(T_LOW0);         //延时拉高时间 90us
		DS_OUT_High();
		delay_us(T_SLOT-T_LOW0);
		DS_IO_IN();               //释放总线
	}
}
/********************************************************************
function name:     			void DS_Write_Byte(uint8_t data)
function performance:		
suction parameter: 			data: waiting to be written 
outlet parameters:			
remark:						 
********************************************************************/
void DS_Write_Byte(uint8_t data)
{
	uint8_t i = 0;
	
	for(i=0;i<8;i++)
	{
		DS_Write_Bit(data&0x01);
		data  =data >> 1;
		
	}

}


uint16_t  Read_byte_data(uint8_t start_address)
{
	uint8_t one_byte_data1 = 0;
	Write_DS_cmd(Read_Data,start_address);
	one_byte_data1 = DS_ReadByte(); //LSB
	return(one_byte_data1);
}

uint8_t Write_data(uint8_t write_address,uint8_t dat)
{
	Write_DS_cmd(Write_Data,write_address);
	DS_Write_Byte(dat);//写入数据
	return(0);
}


void Write_DS_cmd(uint8_t cmd,uint8_t address)
{
	DS_Check();
    DS_Write_Byte(DS_Just_one); //主机发出Skip Net Address命令  0XCC
    DS_Write_Byte(cmd); // 主机发出xx命令
	DS_Write_Byte(address); // 主机发出地址命令
}

void copy_data_ds2780(uint8_t address)
{
	Write_DS_cmd(Copy_Data,address);
	osDelay(1);
}
void recall_data_ds2780(unsigned char address)
{
    Write_DS_cmd(Recall_Data,address);
	osDelay(10);
}


/*******************************得到电压 mV 440mS刷新*************************************/
float Get_Voltage(void)
{
	uint8_t VoltH = 0,VoltL = 0;
	uint16_t volat = 0;
	float Voltage = 0;
	
	VoltH = Read_byte_data(VOLT_RMSB);
	VoltL = Read_byte_data(VOLT_RMSB+0x01);
	
	volat = (VoltH<<3) + (VoltL>>5);
	volat = volat & 0x3FF; //限定最大值
	Voltage = volat * VOLT_STEP;
	return (Voltage);
}

/*******************************得到温度 ℃ 440mS刷新*************************************/
float Get_Temp(void)
{
	uint8_t TempH = 0,TempL = 0;
	float tmp = 0;
	uint16_t Temp_HEX = 0;
	TempH = Read_byte_data(TEMP_RMSB);
	TempL = Read_byte_data(TEMP_RMSB+0x01);
	Temp_HEX = TempH * 256 + TempL;
	if(TempH&0x80) //说明是负值电流在放电
	{			
        Temp_HEX = Temp_HEX & 0x7FFF; //去掉符号位
		Temp_HEX = (~(Temp_HEX - 1)) & 0x7FFF;   //补码----原值
		Temp_HEX = (Temp_HEX >> 5) & 0x03FF;	
		tmp = -(Temp_HEX * TEMP_STEP);
	}
	else           //说明是正值电流在冲电
	{
		Temp_HEX = (Temp_HEX >> 5) & 0x03FF;	
		tmp = Temp_HEX * TEMP_STEP;
	}	
	return (tmp);
}

/*******************************得到电流 mA 采样电阻20mΩ  3.515S刷新************************************/
float Get_Current(void) 
{
	uint8_t CurrH = 0,CurrL = 0;
	float Current = 0;
	uint16_t Voltage_HEX = 0;
	CurrH= Read_byte_data(IREA_RMSB);  //0X0E当前电流
	CurrL = Read_byte_data(IREA_RMSB+0x01);
	Voltage_HEX = CurrH * 256 + CurrL;
	
	if(CurrH&0x80) //说明是负值电流在放电
	{			
        Voltage_HEX = Voltage_HEX & 0x7FFF; //去掉符号位
		Voltage_HEX = (~(Voltage_HEX - 1)) & 0x7FFF;   //补码----原值
		Current = -(Voltage_HEX * CURR_STEP);		
	}
	else           //说明是正值电流在冲电
	{
		Current = Voltage_HEX * CURR_STEP;
	}
	
	return Current;	
}
/*******************************得到平均电流 mA 采样电阻20mΩ  28S刷新************************************/
uint16_t Get_Average_Current(void)
{
	uint8_t CurrH = 0,CurrL = 0;
	uint16_t Current = 0;
	CurrH= Read_byte_data(IAVG_RMSB);
	CurrL = Read_byte_data(IAVG_RMSB+0x01);
	Current = (CurrH<<8) + CurrL;
    Current = Current*AVCU_STEP;
	return (Current);
	
}


/*******************************读出设置的空电压值************************************/
uint16_t Get_VAE_Voltage(void)
{
	uint8_t VAE = 0;
	VAE= Read_byte_data(VVAE_REGS);
	return (VAE);	
}

/*******************************得到累计电量 mAh 放电负 3.515S刷新*************************************/
uint16_t Get_Accumulate_Voltameter(void)
{
	uint8_t VoltameterH = 0,VoltameterL = 0;
	uint8_t pos = 0;
	
	uint16_t Accumulate_Voltameter = 0;
	VoltameterH= Read_byte_data(ACRN_RMSB);
	VoltameterL = Read_byte_data(ACRN_RMSB+0x01);
	if(VoltameterH&0x80) pos = 0;
	else pos = 1;
	
	Accumulate_Voltameter = (VoltameterH<<8) + VoltameterL;
	if(pos ==0) //放电
	{
		Accumulate_Voltameter = (~(Accumulate_Voltameter - 1));
		Accumulate_Voltameter = Accumulate_Voltameter * ACRN_STEP ;//* ACUR_STEP;
		return (Accumulate_Voltameter);	
	}
	Accumulate_Voltameter = Accumulate_Voltameter * ACRN_STEP;//* CURR_STEP;
	return (Accumulate_Voltameter);
}

/*******************************得到剩余相对有效电量 mAh 百分比 3.515S刷新*************************************/
uint16_t Get_RARC_Voltameter(void)
{
 uint8_t RARCH = 0;
 RARCH = Read_byte_data(RARC_RMSB);
 return (RARCH);
}

/*******************************得到剩余绝对有效电量 mAh 3.515S刷新*************************************/
uint16_t Get_Residue_Voltameter(void)
{
	uint8_t RAACH = 0,RAACL = 0;
	uint16_t RAAC = 0;
	RAACH = Read_byte_data(RAAC_RMSB);
	RAACL = Read_byte_data(RAAC_RMSB+0X01);
	RAAC = (RAACH<<8) + RAACL;
	RAAC = RAAC*RAAC_STEP;
	return (RAAC);
}
/*******************************得到剩余绝对待机电量 mAh 3.515S刷新*************************************/
uint16_t Get_Residue_Wait_Voltameter(void)
{
	uint8_t RSACH = 0,RSACL = 0;
	uint16_t RSAC = 0;
	RSACH = Read_byte_data(RSAC_RMSB);
	RSACL = Read_byte_data(RSAC_RMSB+0X01);
	RSAC = (RSACH<<8) + RSACL;
	return (RSAC);
}
/*******************************得到电量状态 剩余百分比  3.515S刷新*************************************/
uint16_t Get_FULL(void)
{
	uint8_t FULLH = 0,FULLL = 0;
	uint16_t FULL = 0;
	FULLH = Read_byte_data(FULL_REGS);
	FULLL = Read_byte_data(FULL_REGS+0X01);
	FULL = (FULLH<<8) + FULLL;
	FULL = FULL&0X3FFF;
	FULL = FULL * FULL_STEP;
	return (FULL);
}
/*******************************得到空电量 百分比 放电负 3.515S刷新*************************************/
uint16_t Get_AE(void)
{
	uint8_t AEAEH = 0,AEAEL = 0;
	uint16_t AEAE = 0;
	AEAEH = Read_byte_data(AEAE_REGS);
	AEAEL = Read_byte_data(AEAE_REGS+0X01);//AEAE_REGS
	AEAE = (AEAEH<<8) + AEAEL;
	AEAE = AEAE *AEAE_STEP;
	return (AEAE);
}

uint8_t Get_STATUS(void)
{
	uint8_t STATUS = 0;
	STATUS = Read_byte_data(STAT_RMSB);
	return (STATUS);
}



void SET_STATUS(uint8_t cmds)
{
	Write_DS_cmd(cmds,STAT_RMSB);
	osDelay(10);
	copy_data_ds2780(STAT_RMSB);
}

void set_RAAC(uint16_t raac)
{
	uint16_t datas=0;
	uint8_t b=0;
	datas = raac / 1.25;
	b = datas>>8;
	Write_data(0x10,b);
	osDelay(40);
	copy_data_ds2780(0x10);
	osDelay(40);
	b = datas&0x00ff;
	Write_data(0x11,b);
	osDelay(40);
	copy_data_ds2780(0x11);
}



void Set_register_ds2780(void)
{
	//写之前擦除EEPROM中的数据
	for(int i = 0;i < 32;i ++)
	{
		Write_data(CTRL_REGS + i,0xFF);         
		copy_data_ds2780(CTRL_REGS + i);     
		vTaskDelay(10);
	}

	/***************控制寄存器格式**************/
	Write_data(CTRL_REGS,CTRL_STAT);     //进入低电压4.9V睡眠模式
	copy_data_ds2780(CTRL_REGS);         //写入芯片的EEPROM中
	vTaskDelay(10);
    /**********以下大部分参数可用DS2480配合读出***********/	
	
	/*********************累积偏移***********************
	AB_uV = AB_mA    * SR_mΩ    AB_mA?
	      = 0.3125mA * 20.0mΩ = 6.25μV
	ValueStored(61H) = AB_uV/1.5625μV = 04H
	****************************************************/
	Write_data(ABAB_REGS,0X04);
	copy_data_ds2780(ABAB_REGS);
	vTaskDelay(10);
	/*********************老化系数可不写*****************
	范围:49.2%~100% 
	单位:0.78%
	AS:  95% (推荐值)
	当电池的初始容量大于电池特性表中设置好的标称容量时,允许学习该较大容量。
	通过上述基于放电次数的老化估计和容量学习功能修改AS值。主机系统可以读、
	写AS,然而在写AS时必须慎重,以免累积的老化估计值被错误数值覆盖。通常,
	不需要通过主机写AS,因为DS2781会将AS自动定期保存到EEPROM内。
    上电时重新恢复EEPROM存储的AS值。
	****************************************************/
	
	/*******************老化容量2500mAh******************
	AC_uV = AC_mA * SR_mΩ       AC_mA?
	      =2500mA * 20.0mΩ = 50000μV
	ValueStored(62H) = AB_uV/6.25μV >>8 = 1FH 
	ValueStored(63H) = AB_uV/6.25μV     = 40H 
	****************************************************/
	Write_data(ACAC_RMSB,0X1F);
	copy_data_ds2780(ACAC_RMSB);
	vTaskDelay(10);
	Write_data(ACAC_RLSB,0X40);
	copy_data_ds2780(ACAC_RLSB);
	vTaskDelay(10);
	/*********************充电电压8.3V********************
	//完成充电电压值
	ValueStored(64H) = CV_V/0.03904V = 213 = D5H
	****************************************************/
	Write_data(VCHG_REGS,0XD5);
	copy_data_ds2780(VCHG_REGS);
	vTaskDelay(10);
	/*********************最小充电电流200mA***************
	AC_mA = 100mA  步进:2.5mA
	ValueStored(65H) = AC_mA/2.5mA  = 50H 
	****************************************************/
	Write_data(IMIN_REGS,0X50);
	copy_data_ds2780(IMIN_REGS);	
	vTaskDelay(10);
	/*********************有效空电压 6.6V****************
	AE_V = VV_V / SR_mΩ       VV_V?
	ValueStored(66H)   =6.6V /39.04mV = 169μV = A9H
	****************************************************/
	Write_data(VVAE_REGS,0XA9);
	copy_data_ds2780(VVAE_REGS);	
	vTaskDelay(10);
	/*********************有效空电流 380mA***********************/
	/*******************************************
	AEC_uV = CC_mA * SR_mΩ       CC_mA?
	ValueStored(67H) = AEC_uV/200μV  = 26H 
	理解:有效空电流的确定应该为配套设备工作在较大负载的时候并且
	是电压在维持设备的最小电压(这个电压一定大于保护电压,这里保护电压
	大于是4.9V,与电池特性有关,一般电池厂家会给出),这是设备还能正常工作
	的最小的电压和电流;
	经测试:本系统最小维持电压6.6V;最小维持电流400mA;给值:380mA
	****************************************************/
	Write_data(IIAE_REGS,0X26);
	copy_data_ds2780(IIAE_REGS);
	vTaskDelay(10);
	/*********************有效空***********************/
	/*******************************************
	ValueStored(68H) = AE40_mA / AC_mA       AE40_mA?AC_mA?
	      =18mA / (2800mAH*2XY(-10)) = 07H
	
	****************************************************/
	Write_data(AE40_REGS,0x06);
	copy_data_ds2780(AE40_REGS);
	vTaskDelay(10);
	/*********************检测电阻初值 20mΩ**************
	ValueStored(69H) = 1/0.020Ω =32H
	****************************************************/
	Write_data(RSEN_REGS,0X32);
	copy_data_ds2780(RSEN_REGS);
	vTaskDelay(10);
	/*********************满电量2500***********************/
	/*******************************************
	FULL40_μV = FULL40_mA * SR_mΩ       
	      =2500mAH * 20.0mΩ = 50000μV
	ValueStored(6AH) = FULL40_μV/6.25μV >>8 = 1FH (x*1000转0x)
	ValueStored(6BH) = FULL40_μV/6.25μV = 40H 
	****************************************************/
	Write_data(FULL_RMSB,0X1F);
	copy_data_ds2780(FULL_RMSB);
	vTaskDelay(10);
	Write_data(FULL_RLSB,0X40);
	copy_data_ds2780(FULL_RLSB);
	vTaskDelay(10);
     /**********依然利用器件资料中给的参数*************/
	 
	/*********************全段边坡***********************/
	Write_data(FULL_3040,0x0D);
	copy_data_ds2780(FULL_3040);
	vTaskDelay(10);
	Write_data(FULL_2030,0x12);
	copy_data_ds2780(FULL_2030);
	vTaskDelay(10);
	Write_data(FULL_1020,0x31);
	copy_data_ds2780(FULL_1020);
	vTaskDelay(10);
	Write_data(FULL_0010,0x36);
	copy_data_ds2780(FULL_0010);
	vTaskDelay(10);
	/*********************AE段边坡***********************/
	Write_data(AEAE_3040,0x04);
	copy_data_ds2780(AEAE_3040);
	vTaskDelay(10);
	Write_data(AEAE_2030,0x0A);
	copy_data_ds2780(AEAE_2030);
	vTaskDelay(10);
	Write_data(AEAE_1020,0x12);
	copy_data_ds2780(AEAE_1020);
	vTaskDelay(10);
	Write_data(AEAE_0010,0x25);
	copy_data_ds2780(AEAE_0010);
	vTaskDelay(10);
	/*********************SE段边坡***********************/
	Write_data(SESE_3040,0x02);
	copy_data_ds2780(SESE_3040);
	vTaskDelay(10);
	Write_data(SESE_2030,0x04);
	copy_data_ds2780(SESE_2030);
	vTaskDelay(10);
	Write_data(SESE_1020,0x05);
	copy_data_ds2780(SESE_1020);
	vTaskDelay(10);
	Write_data(SESE_0010,0x15);
	copy_data_ds2780(SESE_0010);
	vTaskDelay(10);
	/*********************检流电阻增益***********************/
	/*******************************************
	ValueStored(78H) = (RSGAIN*1024)>>8 = 04H 
	ValueStored(79H) = (RSGAIN*1024) = 08H 
	*******************************************/
	Write_data(RSGA_RMSB,0X04);//0X04
	copy_data_ds2780(RSGA_RMSB);
	vTaskDelay(10);
	Write_data(RSGA_RLSB,0X1F);//0X08
	copy_data_ds2780(RSGA_RLSB);
	vTaskDelay(10);
	/********************************************/
	/*******************************************
	ValueStored(7AH) = (RSTCO/30.5176)= 0/30.5176 = 04H 
	*******************************************/
	//检测电阻问票系数
	Write_data(RSTC_REGS,0X00);
	copy_data_ds2780(RSTC_REGS);
	vTaskDelay(10);
    //输入失效电流	
	Write_data(COBB_REGS,0XFC);
	copy_data_ds2780(COBB_REGS);
	vTaskDelay(10);
    //  温度测试模型折现点,4段波,折线点温度值	
	Write_data(T34_REGS,0X12);
	copy_data_ds2780(T34_REGS);
	vTaskDelay(10);
	Write_data(T23_REGS,0X00);
	copy_data_ds2780(T23_REGS);
	vTaskDelay(10);
	Write_data(T12_REGS,0XF4);
	copy_data_ds2780(T12_REGS);
	vTaskDelay(10);
}


void GET_register_ds2780(void)
{
	memset(&DS2781,0,30);    //清除缓存数组的值将DS2781清零处理
	
	recall_data_ds2780(EEPR_REGS);
	DS2781.EEPR = Read_byte_data(EEPR_REGS);

	recall_data_ds2780(ABAB_REGS);
	DS2781.AB = Read_byte_data(ABAB_REGS);

	recall_data_ds2780(ACAC_RMSB);
	DS2781.AC.U8[1] = Read_byte_data(ACAC_RMSB);
	
	recall_data_ds2780(ACAC_RLSB);
	DS2781.AC.U8[0] = Read_byte_data(ACAC_RLSB);
	
	recall_data_ds2780(VCHG_REGS);
	DS2781.VCHG = Read_byte_data(VCHG_REGS);
	
	recall_data_ds2780(IMIN_REGS);
	DS2781.IMIN = Read_byte_data(IMIN_REGS);
	
	recall_data_ds2780(VVAE_REGS);
	DS2781.VVAE = Read_byte_data(VVAE_REGS);
	
	recall_data_ds2780(IIAE_REGS);
	DS2781.IIAE = Read_byte_data(IIAE_REGS);
	
	recall_data_ds2780(AE40_REGS);
	DS2781.AE40 = Read_byte_data(AE40_REGS);
	
	recall_data_ds2780(RSEN_REGS);
	DS2781.RSEN = Read_byte_data(RSEN_REGS);
	
	recall_data_ds2780(FULL_RMSB);
	DS2781.FULL40.U8[1] = Read_byte_data(FULL_RMSB);
	
	recall_data_ds2780(FULL_RLSB);
	DS2781.FULL40.U8[0] = Read_byte_data(FULL_RLSB);
	
	/*********************FULL段边坡***********************/
	recall_data_ds2780(FULL_3040);
	DS2781.FULL3040 = Read_byte_data(FULL_3040);
	
	recall_data_ds2780(FULL_2030);
	DS2781.FULL2030 = Read_byte_data(FULL_2030);
	
	recall_data_ds2780(FULL_1020);
	DS2781.FULL1020 = Read_byte_data(FULL_1020);
	
	recall_data_ds2780(FULL_0010);
	DS2781.FULL0010 = Read_byte_data(FULL_0010);
	
	/*********************AE段边坡***********************/
	recall_data_ds2780(AEAE_3040);
	DS2781.AE3040 = Read_byte_data(AEAE_3040);
	
	recall_data_ds2780(AEAE_2030);
	DS2781.AE2030 = Read_byte_data(AEAE_2030);
	
	recall_data_ds2780(AEAE_1020);
	DS2781.AE1020 = Read_byte_data(AEAE_1020);
	
	recall_data_ds2780(AEAE_0010);
	DS2781.AE0010 = Read_byte_data(AEAE_0010);
	
	/*********************SE段边坡***********************/
	recall_data_ds2780(SESE_3040);
	DS2781.SE3040 = Read_byte_data(SESE_3040);
	
	recall_data_ds2780(SESE_2030);
	DS2781.SE2030 = Read_byte_data(SESE_2030);
	
	recall_data_ds2780(SESE_1020);
	DS2781.SE1020 = Read_byte_data(SESE_1020);
	
	recall_data_ds2780(SESE_0010);
	DS2781.SE0010 = Read_byte_data(SESE_0010);
	

	recall_data_ds2780(RSGA_RMSB);//0X04
	DS2781.RSGAIN.U8[1] = Read_byte_data(RSGA_RMSB);
	
	recall_data_ds2780(RSGA_RLSB);//0X08
	DS2781.RSGAIN.U8[0] = Read_byte_data(RSGA_RLSB);

	recall_data_ds2780(RSTC_REGS);
	DS2781.RSTC = Read_byte_data(RSTC_REGS);
	
	recall_data_ds2780(COBB_REGS);
	DS2781.COB = Read_byte_data(COBB_REGS);
	
	recall_data_ds2780(T34_REGS);
	DS2781.T34 = Read_byte_data(T34_REGS);
	
	recall_data_ds2780(T23_REGS);
	DS2781.T23 = Read_byte_data(T23_REGS);
	
	recall_data_ds2780(T12_REGS);
	DS2781.T12 = Read_byte_data(T12_REGS);
	
}




如果大家配置完成后(即便配置错误)读温度数据和电压数据正常,但是电量数据为0XFFFF。大家一定要记得自学习,方法就是电量耗尽至设置的空电量和电压,手册中有提到状态寄存器的标志位如下图;

 大家自行判断。时间确实久了,博主记得确实不清楚了,不喜勿喷!

                                                                                -----------罗黛心言/20211103

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐