单片机基于BQ28Z610的电池电量计算

在传统无人机或机器人等设备的电池电量剩余预计中,一般都使用分压电阻的方法,采集大

比例电阻的电压从而推算出整体电池电压,用当前电压来粗略的代替当前电量,这里有个很

大的问题就是当主板电路系统中存在高功率器件,比如电机,舵机,继电器等瞬时功率很高

所需要的电流很大瞬间可以把电压拉低,导致电量预计存在很大误差,只有当设备静止时才能

勉强正常。

需要获取准确的电池剩余电量可以使用库仑计结合电池放电曲线来推算。

BQ28Z610适用于 1-2 节串联电池组并具有集成保护器的电池电量监测计。

采用专用主模式 I2C 接口实现自主电池充电控制。

采用内部旁路实现电芯均衡,优化电池运行状况。

高侧保护 N 沟道 FET 驱动器可在故障期间实现串行总线通信。

适用于电压、电流和温度的可编程保护等级。

具备两个独立 ADC 的模拟前端支持电流和电压同步采样。

高精度库伦计数器,输入失调电压误差 < 1µV(典型值)。

支持低至 1mΩ 的电流感应电阻器,同时支持 1mA 电流测量。

支持电池跳变点 (BTP) 功能,用于 Windows® 集成。

SHA-1 认证响应器,用于提高电池组安全性。

适用于高速编程和数据访问的 400kHz I2C 总线通信接口。

紧凑型 12 引脚 VSON 封装 (DRZ)。

stm32f2xx使用硬件i2c与BQ28Z610通信交互。

#ifndef __BQ28Z610_H__
#define __BQ28Z610_H__

#include "stm32f2xx_hal.h"
#include "core_cm3.h"
#include "comtypes.h"

extern __IO BOOLEAN is_i2c2_init;

extern I2C_HandleTypeDef  g_mI2C2Handle;


/**BQ28是I2C主机模式广播和slave设备一样读取。
*/
int BQ_Init(void);


/**
返回剩余电量百分比
*/
int BQ_Get_ElectricQuantity(void);


#endif

#include "bq28z610.h"

#define    READ_TIMOUT                  (300)

#define    I2C_ADDRESS                  (0xAA)

#define    Voltage                      (0x0809)
#define    RemainingCapacity            (0x1011)
#define    FullChargeCapacity           (0x1213)


#define LOCAL_DEBUG

#ifdef LOCAL_DEBUG
static I2C_HandleTypeDef I2CxHandle;


#define I2Cx                             I2C2
#define I2Cx_CLK_ENABLE()                __HAL_RCC_I2C2_CLK_ENABLE()
#define I2Cx_SDA_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOB_CLK_ENABLE()
#define I2Cx_SCL_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOB_CLK_ENABLE() 

#define I2Cx_FORCE_RESET()               __HAL_RCC_I2C2_FORCE_RESET()
#define I2Cx_RELEASE_RESET()             __HAL_RCC_I2C2_RELEASE_RESET()

/* Definition for I2Cx Pins */
#define I2Cx_SCL_PIN                    GPIO_PIN_10
#define I2Cx_SCL_GPIO_PORT              GPIOB
#define I2Cx_SCL_AF                     GPIO_AF4_I2C2
#define I2Cx_SDA_PIN                    GPIO_PIN_11
#define I2Cx_SDA_GPIO_PORT              GPIOB
#define I2Cx_SDA_AF                     GPIO_AF4_I2C2



static void BQ_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{  
		GPIO_InitTypeDef  GPIO_InitStruct;
		
		/*##-1- Enable GPIO Clocks #################################################*/
		/* Enable GPIO TX/RX clock */
		I2Cx_SCL_GPIO_CLK_ENABLE();
		I2Cx_SDA_GPIO_CLK_ENABLE();
		
		/*##-2- Configure peripheral GPIO ##########################################*/  
		/* I2C TX GPIO pin configuration  */
		GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;
		GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
		GPIO_InitStruct.Pull      = GPIO_PULLUP;
		GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
		GPIO_InitStruct.Alternate = I2Cx_SCL_AF;
		
		HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);
			
		/* I2C RX GPIO pin configuration  */
		GPIO_InitStruct.Pin       = I2Cx_SDA_PIN;
		GPIO_InitStruct.Alternate = I2Cx_SDA_AF;
			
		HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);
		 
		/*##-3- Enable I2C peripheral Clock ########################################*/ 
		/* Enable I2C1 clock */
		I2Cx_CLK_ENABLE();
				
}
#endif


int BQ_Init(void)
{
	    
#ifdef LOCAL_DEBUG	
	    BQ_I2C_MspInit(&I2CxHandle);
	
		I2CxHandle.Instance             = I2Cx;
		I2CxHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
		I2CxHandle.Init.ClockSpeed      = 100000 >> 1;
		I2CxHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
		I2CxHandle.Init.DutyCycle       = I2C_DUTYCYCLE_16_9;
		I2CxHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
		I2CxHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
		I2CxHandle.Init.OwnAddress1     = I2C_ADDRESS;
		I2CxHandle.Init.OwnAddress2     = 0;

		if(HAL_I2C_Init(&I2CxHandle) != HAL_OK)
		{
			/* Initialization Error */
			while(1);
		}
#else
		if(!is_i2c2_init) return -1;
#endif	
		
		return 0;
}



int BQ_Get_ElectricQuantity(void)
{
      uint8_t ret;
	  uint8_t readval[2];
	
	  int full,remain;

#ifdef LOCAL_DEBUG	
	  ret = HAL_I2C_Mem_Read( &I2CxHandle, (uint16_t)I2C_ADDRESS,FullChargeCapacity >> 8, I2C_MEMADD_SIZE_8BIT, readval, sizeof(readval), READ_TIMOUT );
	  if(ret != HAL_OK) return -1;
	
	  full =  readval[1] << 8 | readval[0];
	
	  ret = HAL_I2C_Mem_Read( &I2CxHandle, (uint16_t)I2C_ADDRESS,RemainingCapacity >> 8, I2C_MEMADD_SIZE_8BIT, readval, sizeof(readval), READ_TIMOUT );
	  if(ret != HAL_OK) return -1;
#else
	  ret = HAL_I2C_Mem_Read( &g_mI2C2Handle, (uint16_t)I2C_ADDRESS,FullChargeCapacity >> 8, I2C_MEMADD_SIZE_8BIT, readval, sizeof(readval), READ_TIMOUT );
	  if(ret != HAL_OK) return -1;
	
	  full =  readval[1] << 8 | readval[0];
	
	  ret = HAL_I2C_Mem_Read( &g_mI2C2Handle, (uint16_t)I2C_ADDRESS,RemainingCapacity >> 8, I2C_MEMADD_SIZE_8BIT, readval, sizeof(readval), READ_TIMOUT );
	  if(ret != HAL_OK) return -1;    
#endif	

	  remain = readval[1] << 8 | readval[0];
	
	  return remain * 100 / full;
}



/**
	//test electric quantity
	uint8_t datas[10];
	uint8_t percent;
	
    BQ_Init();
	
    while(1)
 	{
		percent = BQ_Get_ElectricQuantity();
		memset(datas,0,sizeof(datas));
		sprintf((char*)datas,"EQ=%d",percent);
			  
		USART1_SendBuf(datas,strlen((char*)datas));
	    HAL_Delay(100);
	}	
*/
//

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值