This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] BQ27441EVM-G1A:电池百分比突然增加/减少

Guru**** 2455360 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/674134/bq27441evm-g1a-battery-percentage-increase-decrease-abruptly

器件型号:BQ27441EVM-G1A

您好!

我正在使用带有微控制器的 I2C 接口使用 BQ27441-G1A 电量监测计。 我使用 I2C 成功地与 BQ27441-G1A 通信、并成功进行读取和写入。 为了供您参考、我附上了我的代码。 如我在 Fualguage_initialize ()函数中的代码所示,我将写入电池电容、配置、设计能量、终止电压、整形器电压至电量。 所有这些参数都成功地写入了燃油表、我通过读取这些值来验证。 在 Fualguage_parameter()函数中,我正在读取电池百分比、电流、电压、设计容量、满容量、 可用容量、电池充电/放电状态。 我还附上了硬件原理图供您参考。 在我的代码中,我在经过一些延迟(7 - 8秒)后连续调用 Fualguage_parameter()。

我正面临着我在下面提到的困境:

=================== 第一种情况===========================

1) 1)考虑到我当前未将 USB 充电器与电路板连接、代码显示 Battery Percentage = 54%、工作正常。

2) 2)现在、我将 USB 充电电缆连接到电路板、现在电池正在充电、工作正常。

3) 3)现在、我按下控制器中的复位开关(仍然 USB 充电电缆连接到电路板上)、现在在 UART 显示屏中、电池百分比= 75%。

所以这里的电池百分比突然增加,差异比上次的读数大。 因此、我在这里得到21%的差异、这比预期的要大得多。

=================== 第二种情况===================

1) 1)考虑到 USB 充电电缆已与我的板连接、并且代码显示电池百分比= 75%、工作正常。

2) 2)现在我从电路板上拔下 USB 充电电缆、电池正在放电、工作正常。

3) 3)现在、我在 UART 显示屏中按控制器中的 RESET 开关电池百分比= 55%。

所以这里的电池百分比突然下降,差异比上次的读数大。 因此、在这里、我会得到20%的差异、这比预期的要大得多。

我仅在连接/移除 USB 充电电缆并复位微控制器、否则工作正常时才会面临这些问题。

那么、为什么我在电池百分比方面会有这么大的差异呢?

请帮我解决这个问题。

感谢您在这方面提供的任何帮助。

谢谢你

 Bhavin

======================================================================== Fuelguage 原理图================================================================

======================================================================== 电池充电器原理图================================================================

================================================================================ main.c ===================================================================

#include
#include "Fualguage.h"
extern volatile I2C_FUNC s_I2C1HandlerFn;
/*------------------ *
/* 燃料变量                                   *
/*------------------ *
extern volatile I2C_FUNC s_I2C0HandlerFn;
extern volatile uint8_t address;
extern volatile uint8_t rw;
extern volatile uint8_t TxRxdata[50];
extern volatile uint8_t TxRxindex;
extern volatile uint8_t read_Write_bytes;
extern volatile uint8_t transfer_complete;
volatile uint8_t Read_FG = 0;
volatile uint8_t percent_bat;
外部电池 Bat_Parameter;
void my_delay (void)
uint32_t i = 800000;
while (i -);
I = 800000;
while (i -);
I = 800000;
while (i -);
I = 800000;
while (i -);
I = 800000;
while (i -);
/*------------------ *
/* 系统正在初始化 clk、模块和引脚复用操作                    *
/*------------------ *
void SYS_Init (void)
 SYS_UnlockReg (); /*解锁受保护的寄存器*/
 /*初始化系统时钟*/
 CLK_SetHCLK (CLK_CLKSEL0_HCLK_S_HIRC、CLK_HCLK_CLK_DEVIDER (1));
 CLK_DisablePLL ();
 CLK->AHBCLK &=~CLK_AHBCLK_DMA_EN;//禁用 CRC 引擎时钟*
 fmc_close();
 CLK->PWRCTL |= CLK_PWRCTL_lirc_EN_MSK;//启用 lirc 而无需调用 HIRC,它在启动时启用*/
 CLK_WaitClockReady (CLK_CLKSTATUS_HIRC_STB_MSK |CLK_CLKSTATUS_lirc_STB_MSK);//等待时钟就绪
 SystemCoreClockUpdate();
 /*选择 IP 时钟源*/
 CLK_SetModuleClock (UART0_MODULE、CLK_CLKSEL1_UART_S_HIRC、CLK_UART_CLK_DEVIDER (1));
 CLK_SetModuleClock (I2C0_MODULE、0、0);
 /*启用 IP 时钟*/
 CLK_EnableModuleClock (UART0_MODULE);
 CLK_EnableModuleClock (I2C0_MODULE);
/*------------------ *
/* Init I/O 多功能(引脚复用)                                *
/*------------------ *
 /*为 UART0设置多功能引脚*/
#ifdef REF_Bord /*用于通过 ICE USB 电缆进行打印*/
 SYS->PB_L_MFP &=~(SYS_PB_L_MFP_PB0_MFP_MSK | SYS_PB_L_MFP_PB1_MFP_MSK);
 SYS->PB_L_MFP ||(SYS_PB_L_MFP_PB0_MFP_UART0_TX | SYS_PB_L_MFP_PB1_MFP_UART0_RX);
其他
 SYS->PB_H_MFP &=~(SYS_PB_H_MFP_PB14_MFP_MSK | SYS_PB_H_MFP_Pb13_MFP_MSK);
 SYS->PB_H_MFP ||(SYS_PB_H_MFP_PB14_MFP_UART0_TX | SYS_PB_H_MFP_Pb13_MFP_UART0_RX);
#endif
 /*为 I2C1设置多功能引脚*/
 SYS->PA_H_MFP =(SYS_PA_H_MFP_PA12_MFP_I2C0_SCL | SYS_PA_H_MFP_PA13_MFP_I2C0_SDA);
 
/*------------------ *
/* 主函数                                              *
/*------------------ *
int32_t main (空)
SYS_Init(); /* Init 系统、IP 时钟和多功能 I/O */
UART_Open (UART0、115200); //将 UART 插入到115200-8n1以显示打印消息*/
ADC_Init();
I2C0_Init();// Init I2C0作为主设备*/
S_I2C0HandlerFn =(I2C_FUNC) I2C_MasterTRx; /*方案控制 i2c 中断专用回调函数*/
Fualguage_initialize();
#ifdef _enable_printf_
    FLG = flags();
    printf("\nBefore BAT_INSERT cmd SEND Flags:");
    for (i=15;i>=0;i---)
      printf("%d"、(flg>>i)&1);
    printf ("\n\r");
#endif
if (executeControlWord (BQ27441_CONTROL_BAT_INSERT))
CLK_SysTickDelay (10000);
#ifdef _enable_printf_
    FLG = flags();
    printf("\nAfter BAT_INSERT CMD SEND Flags:");
    for (i=15;i>=0;i---)
      printf("%d"、(flg>>i)&1);
    printf ("\n\r");
#endif
while ((flags ()& 0x0008)==0)//等待 BAT_DET 位被置位
CLK_SysTickDelay (20);
CLK_SysTickDelay (10000);
my_delay();
my_delay();
my_delay();
Fualguage_parameter();
while (1)
my_delay();
my_delay();
my_delay();
Fualguage_parameter();
================================================================================ Fuelguage.c ========================================================================
#include "nano1X2Series.h"
#include "Fualguage.h"
#include "nuvt_vbel.h"
#define true             1
#define false            0
define 读取1
#define WRITE 0
uint8_t bat_percentage;
电池 Bat_Parameter ={0};
uint8_t FG_Init = SET_BATTERY_Capacity、WriteExtended_Case = ENTER_CONFIG;
uint8_t newCsum = 0;
uint8_t _sealFlag = 0;//全局来识别之前已密封的 IC
uint8_t _userConfigControl = 0;//全局以标识该用户具有控制权  
//输入/退出配置
/*------------------ *
/* 燃料变量                                   *
/*------------------ *
extern volatile I2C_FUNC s_I2C0HandlerFn;
extern volatile uint8_t address;
extern volatile uint8_t rw;
extern volatile uint8_t TxRxdata[50];
extern volatile uint8_t TxRxindex;
extern volatile uint8_t read_Write_bytes;
extern volatile uint8_t transfer_complete;
/*********
秘书长的报告 初始化函数*********
(小部分 /
/*
@func:begin (void)
@param:无
@返回值:uint8_t
@描述:
读取 BQ27441_DEVICE_ID
*
uint8_t begin (空)
  uint16_t DeviceID = 0;
  DeviceID = deviceType();//从 BQ27441读取 deviceType
   
  if (DeviceID = BQ27441_DEVICE_ID)
  {
    返回 true;//如果设备 ID 有效,则返回 true
  }
   
  返回 false;//否则返回 false
/*
@func:setCapacity(uint16_t capacity)
@param:uint16_t
@返回值:uint8_t
@描述:
配置所连接电池的设计容量。
*
uint8_t setCapacity (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;      
返回 writeExtendedData (BQ27441_ID_STATE、capacity_offset、capacityData、2);      
/*
@func:setDesign_Energy (uint16_t capacity)
@param:uint16_t
@返回值:uint8_t
@描述:
配置所连接电池的设计能量。
*
uint8_t setDesign_Energy (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
return writeExtendedData (BQ27441_ID_State、design_energy_offset、capacityData、2);        
/*
@func:setTerminate_Voltage (uint16_t capacity)
@param:uint16_t
@返回值:uint8_t
@描述:
配置所连接电池的终止电压。
*
uint8_t setTerminate_Voltage (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
返回 writeExtendedData (BQ27441_ID_STATE、TERMINATE_VTG_OFFSET、capacityData、2);        
/*
@func:setTaper_rate (uint16_t capacity)
@param:uint16_t
@返回值:uint8_t
@描述:
配置所连接电池的锥形速率。
*
uint8_t setTaper_rate (uint16_t capacity)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
返回 writeExtendedData (BQ27441_ID_STATE、TAPRATE_OFFSET、容量数据、2);    
/*
@func:setTaper_Voltage (uint16_t capacity)
@param:uint16_t
@返回值:uint8_t
@描述:
配置所连接电池的锥形电压。
*
uint8_t setTaper_Voltage (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
return writeExtendedData (BQ27441_ID_STATE、Taper_VTG_OFFSET、capacityData、2);    
/*
@func:setGPOUT (uint16_t 容量)
@param:uint16_t
@返回值:uint8_t
@描述:
将 BQ72441 GPOUT 引脚配置为中断
*
uint8_t setGPOUT (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;
返回 writeExtendedData (BQ27441_ID_REGISTERS"、OPCONFIG_OFFSET、容量数据、2);
/*
μ@:SET_SOC1_Threshold (uint16_t 容量)
@param:uint16_t
@返回值:uint8_t
@描述:
配置 BQ72441的低电池电压阈值百分比
*
uint8_t SET_SOC1_Threshold (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
返回 writeExtendedData (BQ27441_ID_DEBUT、SOC1_OFFSET、容量数据、1);    
/*
@func:SET_FcSet_Threshold (uint16_t 容量)
@param:uint16_t
@返回值:uint8_t
@描述:
配置 BQ72441的低电池电压阈值百分比
*
uint8_t SET_FcSet_Threshold (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
返回 writeExtendedData (BQ27441_ID_CHG_termination、FC_set_offset、capacityData、1);    
/*
@func:SET_FcSet_Threshold (uint16_t 容量)
@param:uint16_t
@返回值:uint8_t
@描述:
配置 BQ72441的低电池电压阈值百分比
*
uint8_t SET_FcClear 阈值(uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
返回 writeExtendedData (BQ27441_ID_CHG_termination、FC_clear_offset、capacityData、1);    
/*
μ@:CLEAR_SOC1_Threshold (uint16_t 容量)
@param:uint16_t
@返回值:uint8_t
@描述:
配置 BQ72441清除阈值百分比
*
uint8_t clear_SOC1_Threshold (uint16_t 容量)
//写入 BQ27441扩展内存的状态子类(82)。
//偏移量0x0A (10)
//设计容量是一个2字节的数据片段- MSB 优先
uint8_t capMSB;
uint8_t capLSB;
uint8_t 容量数据[2]={0};    
capMSB =容量>> 8;
capLSB =容量和0x00FF;    
CapacityData[0]= capMSB;      
CapacityData[1]= capLSB;  
return writeExtendedData (BQ27441_ID_DEBUT、SOC1_CLEAR_OFFSET、capacityData、1);    
/*********
(二 电池特性功能****
(小部分 /
/*
@func:电压(void)
@param:无
@返回值:uint16_t
@描述:
读取并返回电池电压
*
uint16_t 电压(void)
返回 readWord (BQ27441_COMMAND_VOLTAGE);
/*
@func:电流(CURRENT_Measure 类型)
@param:CURRENT_measure
@返回值:int16_t
@描述:
读取并返回指定的电流测量值
*
int16_t 电流(CURRENT_Measure 类型)
int16_t 电流= 0;
开关(类型)
    案例 AVG:
电流=(int16_t) readWord (BQ27441_COMMAND_AVG_CURRENT);
中断;
    案例 STBY:
电流=(int16_t) readWord (BQ27441_COMMAND_STDBY_CURRENT);
中断;
    外壳最大值:
电流=(int16_t) readWord (BQ27441_COMMAND_MAX_CURRENT);
中断;
返回电流;
/*
@func:Capacity (capacity_measure 类型)
@param:capacity_measure
@返回值:uint16_t
@描述:
读取并返回指定的容量测量值
*
uint16_t capacity (capacity_measure 类型)
uint16_t 的容量= 0;
开关(类型)
    案例保留:
返回 readWord (BQ27441_COMMAND_REM_CAPTURE);
中断;
    案例已满:
返回 readWord (BQ27441_COMMAND_FUL_Capacity);
中断;
    案例可用性:
Capacity = readWord (BQ27441_COMMAND_NOM_Capacity);
中断;
    案例 AVAIL_FULL:
Capacity = readWord (BQ27441_COMMAND_AVALE_Capacity);
中断;
    案例 LEASE_F:  
容量= readWord (BQ27441_COMMAND_REM_CAP_FIL);
中断;
    案例 LEASE_UF:
容量= readWord (BQ27441_COMMAND_REM_CAP_UNFLL);
中断;
    FULL_F 案例:
容量= readWord (BQ27441_COMMAND_FULL_CAP_FIL);
中断;
    FLOW_UF 案例:
容量= readWord (BQ27441_COMMAND_FULL_CAP_UNFLL);
中断;
    外壳设计:
Capacity = readWord (BQ27441_extended _ capacity);
返回能力;
/*
@func:电源(空)
@param:无
@返回值:int16_t
@描述:
读取并返回测量的平均功耗
*
int16_t power (void)
返回(int16_t) readWord (BQ27441_COMMAND_AVG_POWER);
/*
@func:soc (soc_measure 类型)
@param:soc_measure
@返回值:uint16_t
@描述:
读取并返回指定的充电测量状态
*
uint16_t SoC (SoC_Measure 类型)
uint16_t socGet = 0;
开关(类型)
    已过滤案例:
socRet = readWord (BQ27441_COMMAND_SOC);
中断;
    未过滤案例:
socRet = readWord (BQ27441_COMMAND_SOC_UNFLL);
中断;
返回 socret;
/*
@func:SOH (SOH_Measure 类型)
@param:SOH_measure
@返回值:uint8_t (运行状况)
@描述:
读取并返回指定的运行状况测量状态
*
uint8_t SOH (SOH_Measure 类型)
uint16_t sohRaw;
uint8_t sohStatus;
uint8_t sohPercent;
SohRaw = readWord (BQ27441_COMMAND_SOH);
SohStatus = SohRaw >> 8;
sohPercent = sohRaw 和0x00FF;
如果(type =percent)
返回肥皂 Percent;
其他
返回 SohStatus;
/*
@func:温度(temp_measure 类型)
@param:temp_measure
@返回值:uint16_t (温度测量)
@描述:
读取并返回指定的温度测量值
*
uint16_t 温度(temp_measure 类型)
uint16_t temp = 0;
开关(类型)
    外壳电池:
temp = readWord (BQ27441_COMMAND_TEMP);
中断;
    Case internal_TEMP:
temp = readWord (BQ27441_COMMAND_INT_TEMP);
中断;
返回温度;
/*********
秘书长的报告 控制子命令********
(小部分 /
/*
@func:DeviceType (void)
@param:无
@返回值:uint16_t (器件类型)
@描述:
读取器件类型-应为0x0421
*
uint16_t deviceType (void)
返回 readControlWord (BQ27441_CONTROL_DEVICE_TYPE);
/*
@func:enterConfig (uint8_t)
@param:uint8_t (UserControl)
@返回值:uint8_t
@描述:
--如果是密封,则取消密封
--进入配置模式--设置 Flag()中的 CFGUPMODE 位
*
uint8_t enterConfig (uint8_t UserControl)
int i = 0;
if (UserControl)_userConfigControl = true;
如果(密封())
#ifdef _enable_printf_          
    uint16_t stat = STATUS();
    printf ("\n\n\rBefore unched Control_status:");
    for (i=0x0F;i >=0;i---)
    {
      printf ("%d"、(stat >> I)& 1);
    }
#endif      
     
unseal();//必须在进行更改之前解除密封
    while (status ()& 0x2000)
      CLK_SysTickDelay (8000);
#ifdef _enable_printf_          
    STAT = STATUS();
    printf ("\n\rfafter unched Control_status:");
    for (i=0x0F;i >=0;i---)
    {
      printf ("%d"、(stat >> I)& 1);
    }
#endif        
if (executeControlWord (BQ27441_CONTROL_SET_CFGUPDATE))
{          
uint16_t 超时= BQ72441_I2C_TIMEOUT;   
uint16_t j = 0;
while ((timeout--)&&(!(flags ()& BQ27441_flag_CFGUPMODE)))
CLK_SysTickDelay (10000);
如果(超时>0)
    {
返回 true;
    }
返回 false;
/*
@func:exitConfig (uint8_t)
@param:uint8_t (resumm)
@返回 val:uint8_t (true 或 false)
@描述:
--退出配置模式,并具有执行调整的选项
--退出配置模式有两种方法:
执行 EXIT_CFGUPDATE 命令
2.执行 SOFT_RESET 命令
-- EXIT_CFGUPDATE 退出配置模式_不 带 OCV (开路电压)
测量、无需电阻器即可更新未过滤的 SoC 和 SoC。
--如果需要新的 OCV 测量或电阻值,SOFT_RESET 或
-- EXIT_RESIM 应用于退出配置模式。
*
uint8_t exitConfig (uint8_t 电阻)
IF (电阻)
{      
if (softreset())(如果(softreset())
{    
uint16_t j = 0;
      CLK_SysTickDelay (10000);
while (flags()& BQ27441_flag_CFGUPMODE)
CLK_SysTickDelay (10000);
       
      if (FG_Init = SET_SOC1_CLEAR_THRESHOLD)
      {
        seal();//如果我们的 IC 是密封的,则会重新密封
        while (!(status ()& 0x2000))
          CLK_SysTickDelay (10000);
      }
      返回 true;    
}      
返回 false;      
其他
返回 executeControlWord (BQ27441_CONTROL_EXIT_CFGUPDATE);      
/*
μ@func:标志(空)
@param:无
@返回值:uint16_t
@描述:
--读取 flags()命令
*
uint16_t 标志(空)
返回 readWord (BQ27441_COMMAND_FLAGS);
/*
@func:状态(空)
@param:无
@返回值:uint16_t
@描述:
--读取 control()的 control_status 子命令
*
uint16_t status (void)
返回 readControlWord (BQ27441_CONTROL_STATUS);
/*
@func:密封(空)
@param:无
@返回值:uint8_t
@描述:
--检查 BQ27441-G1A 是否密封。
*
uint8_t 密封(空)
uint16_t stat = STATUS();
int i = 0;
#ifdef _enable_printf_    
  printf ("\n\rin 密封控制状态:");
  for (i=0x0F;i >=0;i---)
  {
    printf ("%d"、(stat >> I)& 1);
  }
  printf ("\n\r");
#endif    
返回((stat >> 13)& 1);
/*
@func:seal (void)
@param:无
@返回值:uint8_t
@描述:
--密封 BQ27441-G1A
*
uint8_t 密封(空)
{    
return readControlWord (BQ27441_CONTROL_SACULD);
/*
@func:unseal (void)
@param:无
@返回值:uint8_t
@描述:
--拆开 BQ27441-G1A 的密封
*
uint8_t unseal (空)
//要解封 BQ27441,请将密钥写入控制器
//命令。 然后立即再次将同一个密钥写入控制。
IF (readControlWord (BQ27441_unseque_key))
返回 readControlWord (BQ27441_unseque_key);
返回 false;
/*
@func:opConfig (void)
@param:无
@返回值:uint16_t
@描述:
--从扩展数据中读取16位寄存器
*
uint16_t opConfig (空)
返回 readWord (BQ27441_extended _OPCONFIG);
/*
@func:softReset (void)
@param:无
@返回值:uint8_t
@描述:
--发出 BQ27441-G1A 的软复位信号
*
uint8_t 软复位(空)
返回 executeControlWord (BQ27441_CONTROL_SOFT_RESET);
/*
μ@:readWord (uint16_t 子地址)
@param:uint16_t (子地址)
@返回值:uint16_t
@描述:
--从 BQ27441-G1A 读取一个16位命令字
*
uint16_t readWord (uint16_t 子地址)
uint8_t data[2];    
//  HAL_I2C_Mem_Read (&Fualguage_I2C2descriptor、BQ27741_I2C_address、SubAddress、1、(unsigned char *) data、2、100);
FG_I2C_READ (子地址、2);
 返回((uint16_t) TxRxDATA[1]<< 8)| TxRxDATA[0];
/*
@func:readControlWord (uint16_t 函数)
@param:uint16_t (函数)
@返回值:uint16_t
@描述:
--从 BQ27441-G1A 的 control()中读取16位子命令()
*
uint16_t readControlWord (uint16_t 函数)
uint8_t subCommandMSB;
uint8_t subCommandLSB;
uint8_t command[2]={0};
uint8_t data[2]={0、0};
subCommandMSB =(函数>> 8);
subCommandLSB =(函数和0x00FF);
命令[0]= subCommandLSB;
命令[1]= subCommandMSB;
FG_I2C_Write (0、2、command);
// HAL_I2C_Mem_Write (&Fualguage_I2C2descriptor、BQ27741_I2C_address、(uint8_t) 0、1、command、2、100);
     
  CLK_SysTickDelay (7);    
FG_I2C_READ (0、2);
if (transfer_complete = 1)
//  if (!(HAL_I2C_Mem_Read (&Fualguage_I2C2descriptor、BQ27741_I2C_address、(uint8_t) 0、1、(unsigned char *) data、2、100))))
返回((uint16_t) TxRxDATA[1]<< 8)| TxRxDATA[0];
返回 false;
/*
@func:executeControlWord (uint16_t 函数)
@param:uint16_t (函数)
@返回值:uint8_t
@描述:
--从 BQ27441-G1A 的 control()执行子命令()
*
uint8_t executeControlWord (uint16_t 函数)
uint8_t subCommandMSB;
uint8_t subCommandLSB;
uint8_t command[2]={0};
uint8_t data[2]={0、0};
subCommandMSB =(函数>> 8);
subCommandLSB =(函数和0x00FF);
命令[0]= subCommandLSB;
命令[1]= subCommandMSB;
FG_I2C_Write (0、2、command);
if (transfer_complete = 1)
// if (!(HAL_I2C_Mem_Write (&Fualguage_I2C2descriptor、BQ27741_I2C_address、(uint8_t) 0、1、command、2、100)))
  {
返回 true;
  }
返回 false;
/*********
秘书长的报告 扩展数据命令*********
(小部分 /
/*
@func:blockDataControl (void)
@param:无
@返回值:uint8_t
@描述:
--发出 BlockDataControl()命令以启用 BlockData 访问
*
uint8_t blockDataControl (空)
uint8_t enableByte = 0x00;
FG_I2C_Write (BQ27441_extended _control、1、enableByte);
//  返回(!(HAL_I2C_Mem_Write (&Fualguage_I2C2descriptor、BQ27741_I2C_address、BQ27441_extended _control、1、enableByte、1)));
if (transfer_complete = 1)
返回 true;
返回 false;
/*
@func:blockDataClass (uint8_t id)
@param:uint8_t
@返回值:uint8_t
@描述:
--发出 DataClass()命令以设置要访问的数据类
*
uint8_t blockDataClass (uint8_t id)
FG_I2C_Write (BQ27441_extended _DATACLASS、1、&id);
//  返回(!(HAL_I2C_Mem_Write (&Fualguage_I2C2descriptor、BQ27741_I2C_address、BQ27441_extended _DATACLASS、1、&id、1、100)));
if (transfer_complete = 1)
返回 true;
返回 false;   
/*
@func:blockDataOffset (uint8_t offset)
@param:uint8_t
@返回值:uint8_t
@描述:
--发出 DataBlock()命令以设置要访问的数据块
*
uint8_t blockDataOffset (uint8_t offset)
FG_I2C_Write (BQ27441_extended _DATABLOCK、1、偏移量);
//  返回(!(HAL_I2C_Mem_Write (&Fualguage_I2C2descriptor、BQ27741_I2C_address、BQ27441_extended _DATABLOCK、1、offset、1、100)));
if (transfer_complete = 1)
返回 true;
返回 false;    
/*
@func:blockDataChecksum (void)
@param:无
@返回值:uint8_t
@描述:
--使用 BlockDataCheckSum()读取当前校验和
*
uint8_t blockDataChecksum (空)
uint8_t csum;
FG_I2C_READ (BQ27441_extended _CHECKSUM、1);
//  HAL_I2C_Mem_Read (&Fualguage_I2C2descriptor、BQ27741_I2C_address、BQ27441_extended _ checksum、1、&csum、1、100);
CSUM = TxRxDATA[0];
返回 csum;
/*
μ@:readBlockData (uint8_t offset)
@param:uint8_t
@返回值:uint8_t
@描述:
--使用 BlockData()从已加载的扩展数据中读取一个字节
*
uint8_t readBlockData (uint8_t 偏移)
uint8_t ret;
uint8_t 地址=偏移+ BQ27441_extended _BLOCKDATA;
FG_I2C_READ (地址、1);
//  HAL_I2C_Mem_Read (&Fualguage_I2C2descriptor、BQ27741_I2C_address、address、1、&ret、1、100);
RET = TxRxDATA[0];    
回程;
/*
@func:my_readBlockData (uint8_t offset)
@param:uint8_t
@返回值:uint8_t
@描述:
--使用 BlockData()从已加载的扩展数据中读取一个字节
*
uint16_t my_readBlockData (uint8_t 偏移)
uint8_t ret[2]={0};
uint8_t 地址=偏移+ BQ27441_extended _BLOCKDATA;
FG_I2C_READ (地址、2);
//  HAL_I2C_Mem_Read (&Fualguage_I2C2descriptor、BQ27741_I2C_address、address、1、ret、2100);
  返回(((TxRxDATA[0]<< 8)| TxRxDATA[1]);
/*
μ@func:writeBlockData (uint8_t offset、uint8_t data)
@param:uint8_t、uint8_t
@返回值:uint8_t
@描述:
--使用 BlockData()将字节写入已加载数据的偏移量
*
uint8_t writeBlockData (uint8_t offset、uint8_t data)
uint8_t 地址=偏移+ BQ27441_extended _BLOCKDATA;  
FG_I2C_Write (address、1、&data);
//  返回(!(HAL_I2C_Mem_Write (&Fualguage_I2C2descriptor、BQ27741_I2C_address、address、1、&data、1、100)));
if (transfer_complete = 1)
返回 true;
返回 false;    
/*
@func:computeBlockChecksum (void)
@param:无
@返回值:uint8_t
@描述:
--读取加载的扩展数据的所有32个字节并计算 a  
校验和。
*
uint8_t 计算块校验和(空)
uint8_t data[32]={0};    
uint8_t csum = 0;
int i=0;
FG_I2C_READ (BQ27441_extended _ BLOCKDATA、32);
//  HAL_I2C_Mem_Read (&Fualguage_I2C2descriptor、BQ27741_I2C_address、BQ27441_extended、BLOCKDATA、1、data、32、100);
  
  
对于(i=0;i<32;i++)
CSUM += TxRxDATA[i];
CSUM = 255 - csum;
#ifdef _enable_printf_    
  printf ("\r\nncsum:%d\r\n"、csum);
#endif    
返回 csum;
/*
μ@func:writeBlockChecksum (uint8_t csum)
@param:uint8_t
@返回值:uint8_t
@描述:
--使用 BlockDataCheckSum()命令写入校验和值
*
uint8_t writeBlockChecksum (uint8_t csum)
FG_I2C_Write (BQ27441_extended _checksum、1、&csum);
//  返回(!(HAL_I2C_Mem_Write (&Fualguage_I2C2descriptor、BQ27741_I2C_address、BQ27441_extended _CHECKSUM、1、&csum、1、100)));
if (transfer_complete = 1)
返回 true;
  返回 false;
/*
μ@:readExtendedData (uint8_t ClassID、uint8_t offset)
@param:uint8_t、uint8_t
@返回值:uint16_t
@描述:
--从指定类 ID 和位置偏移的扩展数据读取
*
uint16_t readExtendedData (uint8_t ClassID、uint8_t offset)
uint16_t retData = 0;
uint8_t oldCsum = 0;
if (!_userConfigControl) enterConfig (false);
   
if (!blockDataControl())////启用块数据内存控制
返回 false;//如果启用失败则返回 false
  CLK_SysTickDelay (200000);
if (!blockDataClass (ClassID))//使用 DataBlockClass()编写类 ID
返回 false;
  CLK_SysTickDelay (200000);
blockDataOffset (offset /32);//写入32位块偏移(通常为0)
  CLK_SysTickDelay (200000);
computeBlockChecksum ();//计算校验和进入
  CLK_SysTickDelay (200000);
oldCsum = blockDataChecksum ();
  // retData = readBlockData (偏移% 32);//从偏移读取(限制为0-31)
  retData = my_readBlockData (偏移% 32);//从偏移读取(限制为0-31)
  if (!_userConfigControl) exitConfig (true);
  CLK_SysTickDelay (200000);
   
返回 retData;
/*
@func:writeExtendedData
@param:uint8_t、uint8_t、uint8_t *、uint8_t
@返回值:uint8_t
@描述:
--将指定数量的字节写入指定的扩展数据  
类 ID、位置偏移。
*
uint8_t writeExtendedData (uint8_t ClassID、uint8_t offset、uint8_t * data、uint8_t len)
// while (WriteExtended_case <= EXIT_CONFIG)
//{
  switch (WriteExtended_case)
  {
    case enter_config:
    {       
      如果(len > 32)
        返回 false;
       
      if (!_userConfigControl) enterConfig (false);
       
      if (!blockDataControl())////启用块数据内存控制
        返回 false;//如果启用失败则返回 false
//       CLK_SysTickDelay (7);
CLK_SysTickDelay (10000);
      if (!blockDataClass (ClassID))//使用 DataBlockClass()编写类 ID
        返回 false;
       
//       CLK_SysTickDelay (7);
CLK_SysTickDelay (10000);
      blockDataOffset (offset /32);//写入32位块偏移(通常为0)        
      WriteExtended_Case = COMPUTER_BLOCK_CHKSUM;
    }
    中断;
     
    案例 COMPUTER_BLOCK_CHKSUM:
    {
      computeBlockChecksum ();//计算校验和进入        
      WriteExtended_case = get_checksum;
    }
    中断;
     
    案例 get_checksum:
    {
int i = 0;
      uint8_t oldCsum = blockDataChecksum ();
#ifdef _enable_printf_                  
      printf ("\n\roldCsum:%u\n\r"、oldCsum);
#endif            
      //写入数据字节:
      对于(i = 0;i < len;i++)
      {
        //写入 offset,mod 32 (如果 offset 大于32)
        //上面的 blockDataOffset 设置32位块
        writeBlockData ((offset % 32)+ i、data[i]);  
//         CLK_SysTickDelay (7);
CLK_SysTickDelay (10000);
      }
     
      //使用 BlockDataChecksum (0x60)写入新的校验和
      newCsum = computeBlockChecksum ();//计算新校验和
#ifdef _enable_printf_          
      printf ("\n\rnewCsum:%u\n\r"、newCsum);
#endif          
      WriteExtended_case = write_checksum;
    }
    中断;
     
    WRITE_CHECKSUM 情况:
    {
      writeBlockChecksum (newCsum);          
      IF (SOC1_CLR_THRESHOLD || DEDIGN_Capacity)
      {          
        WriteExtended_case = EXIT_CONFIG;
      }
      其他
      {
        WriteExtended_case = ENTER_CONFIG;
        返回 true;
      }
    }
    中断;
     
    案例 EXIT_CONFIG:
    {          
      exitConfig (真);                
// WriteExtended_case++;
      WriteExtended_case = ENTER_CONFIG;
      返回 true;
    }
    中断;
  }//切换
  
  返回 false;
/*
@func:read_battery_percentage (void)
@param:无
@返回值:无
@描述:
--读取电池电量百分比
*
void read_battery_percentage (void)
  操作
  {
    bat_parameter.percentage = soc (已过滤);
    if (Bat_parameter.percentage <= 100)
      中断;
  }while (Bat_parameter.percentage > 100);
   
  bat_percentage =(Bat_parameter.percenty*100)/833);
   
#ifdef _enable_printf_          
  printf ("百分比:%u %\n\r"、Bat_parameter.percent);
#endif      
   
/*
@func:Fualguage_initialize (void)
@param:无
@返回值:无
@描述:
-- Fualguage 初始化设置设计容量、设计能量、
终止电压和锥率
*
void Fualguage_initialize (void)(空)
   
//  uint16_t data = opConfig();
   
  while (FG_Init <= SET_SOC1_CLEAR_THRESHOLD)
  {
    开关(FG_Init)
    {
      案例 SET_BATTERY_Capacity:
      {
#ifdef _enable_printf_       
        printf ("\n\r\n\r\n----- 在"设置设计容量..."中);          
#endif
        if (setCapacity (battery_capacity))
        {
          FG_Init = SET_OPCONFIG;
        }
      }
      中断;
       
      案例 SET_OPCONFIG:
      {
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在"设置 GPOUT 引脚配置..."中);
#endif        
        if (setGPOUT (OPCONFIG))
          FG_Init = SET_design_energy;
      }
      中断;
       
      案例 set_design_energy:
      {
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在"设置设计能量..."中);
#endif    
        if (setDesign_Energy (design_energy))
          FG_Init = SET_TERMINATE_VOLTAGE;
// FG_Init = SET_FC_SET;
/* exitConfig (真);
FG_Init++;*/
      }
      中断;
       
      案例 SET_TERMINATE_VOLTAGE:
      {       
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在设置终止电压...\n\n\r\n");
#endif    
        if (setTerminate_Voltage (terminate_voltage))
          FG_Init = SET_Tape_Rate;
      }
      中断;
       
      案例 SET_Tape_Rate:
      {          
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在设置锥度速率中...\n\n\r\n");
#endif    
        if (setTaper_rate (tape_rate))
          FG_Init = SET_Tape_VOLTAGE;
FG_Init = SET_SOC1_CLEAR_THRESHOLD;
exitConfig (真);
FG_Init++;
      }
      中断;
       
      案例 SET_Tape_Voltage:
      {    
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在"设置锥形电压..."中);
#endif      
        if (setTaper_Voltage (taper_voltage))
          FG_Init = SET_SOC1_THRESHOLD;
      }
      中断;
       
      案例 SET_SOC1_THRESHOLD:
      {
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在设置 SOC1设置阈值...\n\n\r\n");
#endif        
        IF (SET_SOC1_Threshold (SOC1_SET_THRESHOLD))
          FG_Init = SET_FC_SET;
      }
      中断;
       
       
      案例 SET_FC_set:
      {
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在设置 FC_Set 阈值...\n\r\n");
#endif        
        if (SET_FcSet_Threshold (FC_Set))(设置 FcSet_Threshold (FC_Set))
          FG_Init = SET_FC_CLEAR;
      }
      中断;       
       
      案例 SET_FC_CLEAR:
      {
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在 Set FC_Clear Threshold (设置 FC_Clear 阈值)...\n\r\n\r\n");
#endif        
        if (SET_FcClear 阈值(FC_CLEAR))
{            
FG_Init = SET_SOC1_CLEAR_THRESHOLD;
exitConfig (真);
FG_Init++;
      }
      中断;                   
       
      案例 SET_SOC1_CLEAR_THRESHOLD:
      {
#ifdef _enable_printf_        
        printf ("\n\r\n\r\n----- 在"设置 SOC1清除阈值..."中);
#endif          
        IF (CLEAR_SOC1_Threshold (SOC1_CLEAR_THRESHOLD))
          FG_Init++;
      }
      中断;
       
    }//切换       
     
  }
   
//  clk_SysTickDelay (900);     
//  clk_SysTickDelay (50000);
void Check_Battery_Chg_Discg (void)
  int Avg_Power = 0;
  Avg_Power =功率();
   
  /*放电*/
  IF (Avg_Power < 0)
  {
    bat_parameter.discharge = 1;
    Bat_Parameter.charging = 0;
#ifdef _enable_printf_          
    printf ("电池正在放电\n");
#endif     
  }
  /*充电*/
  如果(Avg_Power > 0)则为其他值
  {
    Bat_Parameter.charging = 1;
    bat_parameter.discharge = 0;
#ifdef _enable_printf_          
    printf ("电池正在充电");
#endif      
  }   
  /*未放电*/
  否则、如果(Avg_Power = 0)
  {
    Bat_Parameter.charging = 0;
    bat_parameter.discharge = 0;
#ifdef _enable_printf_          
    printf ("电池未充电、未放电\n");
#endif      
  }     
   
/*
@func:Fualguage_parameter (void)
@param:无
@返回值:无
@描述:
读取 Fualguage 参数
-电池百分比
-电池电流
-蓄电池电压
- Fualguage 设计容量
-满容量富古吉
-可用容量
*
void Fualguage_parameter (void)
//  if (FG_initialization_complete)
//  {
    uint16_t flg = 0、opcnfg = 0、Battery 电压= 0;
INT8_t I = 0;
uint16_t stat = 0;
     
    操作
    {
      bat_parameter.percentage = soc (已过滤);
      if (Bat_parameter.percentage <= 100)
        中断;
    }while (Bat_parameter.percentage > 100);
//#if 0  
//     SEC = 0;
//     while (sec<3);
//     bat_percentage =(Bat_parameter.percenty*100)/833);
     
     
#ifdef _enable_printf_          
    printf ("百分比:%u %\n\r"、Bat_parameter.percent);
#endif    
     
    BAT_PARAMETER.CURRENT =电流(AVG);
    if (Bat_parameter.current < 0)
      bat_parameter.current =-(Bat_parameter.current);
#ifdef _enable_printf_          
    printf ("当前:%d mAh\n\r\n",Bat_parameter.current);
#endif    
     
//     SEC = 0;
//     while (sec<3);      
     
    battery_Voltage =电压();
    BAT_Parameter.Voltage =(悬空) BAT_Voltage/1000;
#ifdef _enable_printf_          
    printf ("电压:%f V\n\r\n",Bat_parameter.Voltage");
#endif    
     
//     SEC = 0;
//     while (sec<3);      
     
    bat_parameter.design_capacity =容量(设计);
#ifdef _enable_printf_          
    printf ("设计容量:%u mAh\n\r\n",Bat_parameter.Design_capacity);
#endif    
     
//     SEC = 0;
//     while (sec<3);      
     
    bat_parameter.full_capacity = capacity (full);
#ifdef _enable_printf_          
    printf ("满容量:%u mAh\n\r\n、Bat_parameter.full_capacity);
#endif    
     
//     SEC = 0;
//     while (sec<3);      
     
    bat_parameter.ave_capacity = capacity (avail);
#ifdef _enable_printf_          
    printf ("可用容量:%u mAh\n\r\n",Bat_parameter.ave_capacity);
#endif    
     
     
//     SEC = 0;
//     while (sec<3);      
     
#ifdef _enable_printf_
    FLG = flags();
    printf("\nFlags:");
    for (i=15;i>=0;i---)
      printf("%d"、(flg>>i)&1);
    printf ("\n\r");
#endif          
     
     
//     SEC = 0;
//     while (sec<3);      
     
#ifdef _enable_printf_    
    STAT = STATUS();
    printf("\n\n\rControl_status:");
    for (i=0x0F;i >=0;i---)
    {
      printf ("%d"、(stat >> I)& 1);
    }
    printf ("\n\r");
#endif  
     
//     SEC = 0;
//     while (sec<3);      
     
#ifdef _enable_printf_   
    opcnfg = opConfig();      
    printf("\nOpConfig:");
    for (i=15;i>=0;i---)
      printf("%d"、(opcnfg>>i)&1);
    printf ("\n\r");
#endif  
     
//     SEC = 0;
//     while (sec<3);      
     
    CHECK_BATTERY_Chg_Discchg ();
 //#endif   
//  }
void FG_I2C_Read (uint8_t 地址、uint8_t Read_Bytes)
memset (TxRxdata、0、sizeof (TxRxdata));
TxRxINDEX = 0;
TRANSFER_COMPLETE = 0;
Read_Write_Bytes = Read_Bytes;
address =地址;
RW =读取;
/* I2C 作为主器件发送 START 信号*/
 I2C_SET_CONTRAL_REG (I2C0、I2C_STA);
while (transfer_complete = 0);
void FG_I2C_Write (uint8_t 地址、uint8_t write_bytes、uint8_t *数据)
uint8_t i = 0;
memset (TxRxdata、0、sizeof (TxRxdata));
for (i=0;i < write_bytes;i++)
TxRxDATA[i]=数据[i];
TxRxINDEX = 0;
TRANSFER_COMPLETE = 0;
Read_Write_Bytes = write_bytes;
address =地址;
RW =写入;
/* I2C 作为主器件发送 START 信号*/
 I2C_SET_CONTRAL_REG (I2C0、I2C_STA);
while (transfer_complete = 0);
================================================================================ Fuelguage.h ================================================================================

#ifndef __FUALGUAGE_H
#define __FUALGUAGE_H

#define TIMEOUT 10000
#define BQ72441_I2C_TIMEOUT 2000

///---------------- 电池参数宏-------------------------------------------------------

#define battery_capacity 5000 //例如800mAh 电池
// DesignEnergy = battery_capacity (mAh)* 3.7V
#define design_energy 18500
#define TERMINATE_VOLTAGE 3300 //终止电压= 3300mV
#define 锥形电流115 //锥形电流= 115mA
// Taper_rate =(int)(battery_capacity /(0.1 * Taper_current))
#define Tape_Rate 434
#define Taper_voltage 4200
#define SOC1_SET_THRESHOLD 10 //低电池阈值百分比中断
#define SOC1_CLEAR_THRESHOLD 11 //在达到此百分比后、低电池阈值中断清除
#define FC_set 98 //充电在此百分比之后终止
#define FC_CLEAR 95 //标志的 FC 位清零低于此百分比
#define OPCONFIG 0x1DFC


typedef 结构

uint8_t 充电:1;
uint8_t 放电:1;
uint8_t Bat_Low:1;
int16_t 百分比;
int16_t 电流;
int16_t Design_capacity;
int16_t full_capacity;
int16_t ave_capacity;
浮动电压;
}电池;

typedef 枚举

Set_battery_capacity、
SET_OPCONFIG、
Set_design_energy、
SET_TERMINATE_VOLTAGE、
Set_Tape_Rate、
Set_Tape_Voltage、
SET_SOC1_THRESHOLD、
SET_FC_SET、
SET_FC_CLEAR、
SET_SOC1_CLEAR_THRESHOLD
}Fual_Guage_Init;

typedef 枚举

ENTER_CONFIG、
Compute _ block_CHKSUM、
GET_CHECKSUM、
WRITE_CHECKSUM、
EXIT_CONFIG
} Write_ExtendedData;

#define TIMER_EXPIE FG_Timer_Flag >= 2.

/* I2C 读取需要此延迟*/
(j = 0;j < 500;j++)的#define delay


#define SOC1_CLR_THRESHOLD ((偏移= 1)&&(ClassID = 49)
#define DEDIGN_Capacity ((offset ==10)&&(ClassID ==82)

#define FG_INITIALL_COMPLETE FG_Init > SET_SOC1_CLEAR_THRESHOLD

// Current()函数的参数,指定要读取的电流
typedef 枚举{
平均值、//平均电流(默认值)
STBY、//待机电流
最大//最大电流
} CURRENT_measure;

// capacity()函数的参数,指定要读取的容量
typedef 枚举{
保留、//剩余容量(默认)
全容量、//全容量
可用、//可用容量
AVALE_FULL、//完全可用容量
LEASE_F、//过滤剩余容量
LEASE_UF、//未过滤的剩余容量
FULL_F、//已过滤全部容量
FULL_UF、//未过滤的满容量
设计//设计容量
} capacity_measure;

// SoS()函数的参数
typedef 枚举{
已过滤、//已过滤充电状态(默认)
未过滤//充电状态未过滤
} SoC_Measure;

// SOH()函数的参数
typedef 枚举{
百分比、//运行状况百分比(默认值)
SOH_STAT //运行状况状态位
} SOH_measure;

// temperature ()函数的参数
typedef 枚举{
电池、//电池温度(默认值)
INTERNAL_TEMP //内部 IC 温度
} temp_measure;

// setGPOUTFunction()函数的参数
typedef 枚举{
SoC_INT、//将 GPOUT 设置为 SOC_INT 功能
// BAT_LOW //将 GPOUT 设置为 BAT_LOW 功能<--- 对此进行了注释
} gpout_function;

//////////////////////////////////////////////
//常规常量//
//////////////////////////////////////////////
#define BQ27441_unseque_key 0x8000 //密钥代码来解封 BQ27441-G1A
#define BQ27441_DEVICE_ID 0x0421 //默认器件 ID

//////////////////////////////////////////////
//标准命令//
//////////////////////////////////////////////
//电量监测计使用一系列2字节标准命令来启用系统
//读取和写入电池信息。 每个命令都有一个关联的
//顺序命令代码对。
#define BQ27441_COMMAND_CONTROL 0x00 //控制()
#define BQ27441_COMMAND_TEMP 0x02 //温度()
#define BQ27441_COMMAND_VOLTAGE 0x04 //电压()
#define BQ27441_COMMAND_FLAGS 0x06 // Flags()
#define BQ27441_COMMAND_NOM_Capacity 0x08 // NominalAvailableCapacity()
#define BQ27441_COMMAND_AVALE_Capacity 0x0A //可用 Capacity ()
#define BQ27441_COMMAND_REM_CAPTURE 0x0C //重新定义 Capacity ()
#define BQ27441_COMMAND_FUL_Capacity 0x0E // FullChargeCapacity()
#define BQ27441_COMMAND_AVG_CURRENT 0x10 // AverageCurrent ()
#define BQ27441_COMMAND_STDBY_CURRENT 0x12 //标准电流()
#define BQ27441_COMMAND_MAX_CURRENT 0x14 // MaxLoadCurrent ()
#define BQ27441_COMMAND_AVG_POWER 0x18 // AveragePower()
#define BQ27441_COMMAND_SOC 0x1C // StateOfCharge ()
#define BQ27441_COMMAND_TEMP 0x1E //内部温度()
#define BQ27441_COMMAND_SOH 0x20 // StateOfHealth ()
#define BQ27441_COMMAND_REM_CAP_UNFL 0x28 //重新保护电容未过滤()
#define BQ27441_COMMAND_REM_CAP_FIL 0x2A //重新保护电容已分配()
#define BQ27441_COMMAND_FULL_CAP_UNFL 0x2C // FullChargeCapacityUnfiltered ()
#define BQ27441_COMMAND_FULL_CAP_FIL 0x2E // FullChargeCapacityFiled()
#define BQ27441_COMMAND_SOC_UNFL 0x30 // StateOfChargeUnfilter()

///////////////////////////////////////////////////////
//控制子命令//
///////////////////////////////////////////////////////
//发出 Control()命令需要后续的2字节子命令。 这些
//附加字节指定所需的特定控制函数。 。
// Control()命令允许系统控制燃油的特定功能
正常运行期间的//测量仪表以及器件处于中时的附加功能
//不同的访问模式。
#define BQ27441_CONTRAL_STATUS 0x00
#define BQ27441_CONTRAL_DEVICE_TYPE 0x01
#define BQ27441_CONTRAL_FW_VERSION 0x02
#define BQ27441_CONTRAL_DM_CODE 0x04
#define BQ27441_CONTROL_PREV_MACWRITE 0x07
#define BQ27441_CONTRAL_CHEM_ID 0x08
#define BQ27441_CONTRAL_BAT_INSERT 0x0C
#define BQ27441_CONTRAL_BAT_REMOVE 0x0D
#define BQ27441_CONTRAL_SET_HIBERNATE 0x11
#define BQ27441_CONTRAL_CLEAR_HIBERNATE 0x12
#define BQ27441_CONTRAL_SET_CFGUPDATE 0x13
#define BQ27441_CONTRAL_SHUTDOWN_ENABLE 0x1B
#define BQ27441_CONTRAL_SHUTDOWN 0x1C
#define BQ27441_CONTRAL_SABLECed 0x20
#define BQ27441_CONTRAL_PULSE_SOC_INT 0x23
#define BQ27441_CONTRAL_RESET 0x41
#define BQ27441_CONTRAL_SOFT_RESET 0x42
#define BQ27441_CONTRAL_EXIT_CFGUPDATE 0x43
#define BQ27441_CONTROL_EXIT_RESIM 0x44

////////////////////////////////////////////////////////////////////////////////////////////
//控制状态字-位定义//
////////////////////////////////////////////////////////////////////////////////////////////
// CONTRAL_STATUS 的16位数据的位位置。
// control_status 指示电量监测计将状态信息返回到
// Control()地址0x00和0x01。 只读状态字包含状态
//作为条件保证或自动置位或清零的位
//通过使用指定的子命令。
#define BQ27441_STATUS_SHUTDOWNEN (1<<15)
#define BQ27441_STATUS_WDRESET (1<<14)
#define BQ27441_STATUS_SS (1<<13)
#define BQ27441_STATUS_CALMODE (1<<12)
#define BQ27441_STATUS_CCA (1<<11)
#define BQ27441_STATUS_BCA (1<<10)
#define BQ27441_STATUS_Qmax_up (1<<9)
#define BQ27441_STATUS_RES_UP (1<<8)
#define BQ27441_STATUS_INITCOMP (1<<7)
#define BQ27441_STATUS_HIBERNATE (1<<6)
#define BQ27441_STATUS_SLEEP (1<<4)
#define BQ27441_STATUS_LDMD (1<<3)
#define BQ27441_STATUS_RUP_DIS (1<<2)
#define BQ27441_STATUS_VOK (1<<1)

////////////////////////////////////////////////////////////////////////////
//标志命令-位定义//
////////////////////////////////////////////////////////////////////////////
// Flags()的16位数据的位位置
//此读字函数返回电量监测状态的内容
//寄存器、描述当前的运行状态。
#define BQ27441_FLAG_OT (1<<15)
#define BQ27441_FLAG_UT (1<<14)
#define BQ27441_FLAG_FC (1<<9)
#define BQ27441_FLAG_CHG (1<<8)
#define BQ27441_FLAG_OCVTAKEN (1<<7)
#define BQ27441_FLAG_ITPOR (1<<5)
#define BQ27441_FLAG_CFGUPMODE (1<<4)
#define BQ27441_FLAG_BAT_DET (1<<3)
#define BQ27441_FLAG_SOC1 (1<<2)
#define BQ27441_FLAG_SOCF (1<<1)
#define BQ27441_FLAG_DSG (1<0)

///////////////////////////////////////////////////////////
//扩展数据命令//
///////////////////////////////////////////////////////////
//扩展数据命令提供了标准之外的附加功能
//命令集。 它们的使用方式相同;但与标准不同
//命令、扩展命令不限于2字节字。
#define BQ27441_extended _OPCONFIG 0x3A // OpConfig ()
#define BQ27441_extended _ capacity 0x3C // DesignCapacity ()
#define BQ27441_DELEDAND_DATACLASS 0x3E // DataClass ()
#define BQ27441_DELEDAND_DATABLOCK 0x3F //数据块()
#define BQ27441_extended BLOCKDATA 0x40 // BlockData ()
#define BQ27441_extended 校验和0x60 // BlockDataCheckSum ()
#define BQ27441_extended _control 0x61 // BlockDataControl ()

//////////////////////////////////////////////////////////////////////////////////////
//配置偏移//
//////////////////////////////////////////////////////////////////////////////////////
#define capacity_offset 10.
#define design_energy_offset 12.
#define TERMINAT_VTG_OFFSET 16.
#define TAPRATE_OFFSET 27
#define Tape_VTG_OFFSET 29
#define OPCCONFIG_OFFSET 0
#define SOC1_OFFSET 0
#define SOC1_CLEAR_OFFSET 1.
#define FC_set_offset 5.
#define FC_clear_offset 6.

//////////////////////////////////////////////////////////////////////////////////////
//配置类,子类 ID //
//////////////////////////////////////////////////////////////////////////////////////
//要访问扩展数据的子类,请设置 DataClass()函数
//使用这些值之一。
//配置类
#define BQ27441_ID_SAFETY 2 //安全
#define BQ27441_ID_CHG_Termination 36 //充电终止
#define BQ27441_ID_CONFIG_DATA 48 //数据
#define BQ27441_ID_DELOD 49 //放电
#define BQ27441_ID_REGISTERS" 64 //寄存器
#define BQ27441_ID_POWER 68 //电源
//电量监测类别
#define BQ27441_ID_IT_CFG 80 // IT 配置
#define BQ27441_ID_CURRENT_THRESH 81 //电流阈值
#define BQ27441_ID_STATE 82 //状态
// Ra 表类
#define BQ27441_ID_R_A_RAM 89 // R_A RAM
//校准类
#define BQ27441_ID_CALIB_DATA 104 //数据
#define BQ27441_ID_CC_CAL 105 // CC 校准
#define BQ27441_ID_CURRENT 107 // Current
//安全类
#define BQ27441_ID_CODETS112 //代码

//////////////////////////////////////////////////////////////////////////////////////////
// OpConfig 寄存器-位定义//
//////////////////////////////////////////////////////////////////////////////////////////
// OpConfig 寄存器的位位置
#define BQ27441_OPCONFIG_BIE (1<<13)
#define BQ27441_OPCONFIG_BI_PU_EN (1<<12)
#define BQ27441_OPCONFIG_GPIOPOL (1<<11)
#define BQ27441_OPCONFIG_SLEEP (1<<5)
#define BQ27441_OPCONFIG_RMFCC (1<<4)
#define BQ27441_OPCONFIG_BATLOWEN (1<<2)
#define BQ27441_OPCONFIG_TEMPS (1<0)


//函数声明
uint8_t begin (void);
uint8_t setCapacity (uint16_t 容量);
uint16_t 电压(void);
int16_t CURRENT (CURRENT_Measure 类型);
uint16_t capacity (capacity_measure 类型);
int16_t power (void);
uint16_t soc (soc_measure 类型);
uint8_t SOH (SOH_Measure 类型);
uint16_t 温度(temp_measure 类型);
uint16_t deviceType (void);
uint8_t enterConfig (uint8_t UserControl);
uint8_t exitConfig (uint8_t 电阻);
uint16_t flags (void);
uint16_t status (void);
uint8_t 密封(void);
uint8_t seal (void);
uint8_t unseal (void);
uint16_t opConfig (void);
uint16_t readWord (uint16_t 子地址);
uint16_t readControlWord (uint16_t 函数);
uint8_t executeControlWord (uint16_t 函数);
uint8_t blockDataControl (void);
uint8_t blockDataClass (uint8_t id);
uint8_t blockDataOffset (uint8_t offset);
uint8_t blockDataChecksum (void);
uint8_t readBlockData (uint8_t offset);
uint8_t writeBlockData (uint8_t offset、uint8_t data);
uint8_t computeBlockChecksum (void);
uint8_t writeBlockChecksum (uint8_t csum);
uint16_t readExtendedData (uint8_t ClassID、uint8_t offset);
uint8_t writeExtendedData (uint8_t ClassID、uint8_t offset、uint8_t * data、uint8_t len);
uint8_t softReset (void);
uint8_t setDesign_Energy (uint16_t 容量);
uint8_t setTerminate_Voltage (uint16_t capacity);
uint8_t setTaper_rate (uint16_t capacity);
uint16_t my_readBlockData (uint8_t offset);
void Fualguage_initialize (void);
void Fualguage_parameter (void);
uint8_t setTaper_Voltage (uint16_t capacity);
uint8_t setGPOUT (uint16_t 容量);
uint8_t SET_SOC1_Threshold (uint16_t 容量);
uint8_t clear_SOC1_Threshold (uint16_t 容量);
void read_battery_percentage (void);
void Check_Battery_Chg_Discg (void);
uint8_t SET_FcSet_Threshold (uint16_t 容量);
uint8_t SET_FcClear 阈值(uint16_t 容量);
void FG_I2C_Read (uint8_t 地址、uint8_t Read_Bytes);
void FG_I2C_Write (uint8_t Address、uint8_t write_bytes、uint8_t *数据);

#endif

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Bhavin、
    您是否看过 bq27441的快速入门指南?
    www.ti.com/.../sluuap7
    谢谢
    Onyx
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Onyx Ahiakwo、

    感谢您的回复,我查看了快速入门指南( www.ti.com/.../sluuap7.pdf )和 www.ti.com/.../sluuac9a.pdf 。 我能够配置设计容量、设计能耗、终止电压和锥率、并通过读取我写入的值来验证这些参数。 只有连接/移除 USB 充电电缆并复位微控制器、我才会面临此问题、否则它工作正常。 请参阅我在查询中提到的第一个和第二个场景。

    谢谢你
    Bhavin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Bhavin
    您不应在使用电量监测计时复位。 这样做将导致运行新的 rem 电容器仿真、并且根据当时是否存在电流、将导致进行错误的 OCV 测量、从而导致您看到的跳转。

    谢谢
    Onyx
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Onyx Ahiakwo、

    感谢您的回复。 您能不能通过查看代码和硬件原理图来告诉我哪里出错了。

    谢谢你
    Bhavin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此问题是否有任何更新?
    感谢您在这方面提供的任何帮助。

    谢谢你
    Bhavin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Bhavin、

    我回答说、您需要防止发生这些重置。

    谢谢

    Onyx