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.

[参考译文] BQ76952:如何更改 CC 增益值

Guru**** 2585275 points
Other Parts Discussed in Thread: BQ76952, BQSTUDIO, BQ76942

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

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1015699/bq76952-how-to-change-cc-gain-value

器件型号:BQ76952
主题中讨论的其他器件: BQSTUDIOBQ76942

您好!

我使用的是 BQ76952,它具有 Stm32LRC431控制器,  

我面临一些问题、

  • 1Mohm R Sense 的默认 CC 增益为7.4768、而我使用0.5m Ω 分流器、因此我需要将 CC 增益更改为 14.9536如何使用 IEEE754单精度4字节格式修改寄存器
  • 在使用制造状态 INIT 将 MOSFET 切换至0x0050时、主充电和放电会打开、 而我在 FET 选项中设置预放电位时、预放电会打开、并且会立即关闭并打开主放电、而不会连接任何负载。 它与我的 CC 增益或我需要配置的任何内容有关。

请 Matt

谢谢、此致

罗希思西

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

    您好、Rohith、

    要修改 CC 增益、您将需要写入地址0x91A8并使用与将数据写入 RAM 类似的方法写入4字节值。 您可以 使用此转换器获取要发送到地址 https://www.h-schmidt.net/FloatConverter/IEEE754.html的十六进制值。  

    您将需要初始化 TX_6Byte[6]阵列、如 TX_4Byte。 此外、请确保先进入 ConfigUpdate 模式、然后在完成寄存器更新后退出。

      TX_6Byte[0] =  0xA8; TX_6Byte[1] =  0x91; TX_6Byte[2] =  0x..; TX_6Byte[3] =  0x..; TX_6Byte[4] = 0x..;  TX_6Byte[5] = 0x..;
      I2C_WriteReg (0x3E、 TX_6Byte、6);  
      delayUS(1000);
      TX_2Byte[0] = 校验和(TX_6Byte、6); TX_2Byte[1] =  0x08;  // 校验和 和 长度**编辑:您将需要将0x08用于 TX_2Byte[1]而不是0x06。
      I2C_WriteReg (0x60、 TX_2Byte、 2);   
      delayUS(1000);
    预放电关断基于操作。 有两个设置:预放电超时和预放电停止增量(可在 TRM 的第5.2.3.2.2节"预滤波器模式"中找到)、用于指示放电应关闭的时间。 如果您想让它们保持较长时间、则需要调整这些设置以满足您的要求。
    希望这对您有所帮助。
    最棒的
    Andrew
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Andrew

    所面临的问题

    • 如何计算电流值当我使用0.5 m Ω Rsense 时,我按照建议更改了 CC 增益,我不确定  应该进行哪些 CC2、CC3配置来计算,以便在我使用此函数时将电流值作为输出。 即使 我尝试使用具有1 m Ω Rsense 分流器的该函数、我也会得到一些错误的五位值  
    • 我需要修改哪些寄存器?

    uint16_t AFE_ReadCurrent (){
    I2C_ReadReg (0x3A、RX_2Byte、2);
    返回(RX_2Byte[1]*256 + RX_2Byte[0]);//电流以 mA 为单位报告

    MOSFET 上的问题

    • 当我将制造状态写入0x0050并打开 FET 并观察 FET 选项中的 FET 状态预放电位使能时、我的预放电 FET 和充电 FET I 打开、我的放电 FET 在关闭预放电 FET 时打开。 通过泵式70V 接收充电 FET 输出、而我的放电 FET 未通过泵式电压开启、其电压为10 -15V (杂散电压)。 在完全为70V 的电压下打开放电时、应采取什么措施?
    • 即使我修改了预充电增量和超时。

    这是我的 c 代码

    /*用户代码 begin Header */
    /**
    秘书长的报告
    *@文件:main.c
    *@简介:主要节目机构
    秘书长的报告
    *@注意
    *
    *

    Copyright版权所有(c) 2021 STMicroelectronics。
    *保留所有权利。


    *
    *此软件组件由 ST 根据 BSD 3条款许可、
    *"许可证";除非符合、否则不得使用此文件
    *许可证。 您可以在以下位置获取许可证副本:
    * opensource.org/licenses/BSD-3-Clause
    *
    秘书长的报告
    *
    /*用户代码结尾标头*/
    /*包括------------------------------------------ *
    #include "main.h"

    /*私有包括---------------------------------------------- *
    /*用户代码 begin 包括*/
    #include
    /*用户代码末尾包括*/

    /*私人 typedef ------------------------------------------------------- *
    /*用户代码 begin PTD */

    /*用户代码结束 PTD */

    /*私人定义------------------------------------------------------- *
    /* USER CODE BEGIN PD */
    #define DEV_ADDR 0x10 //器件地址
    #define CRC_Mode 0 // 0表示禁用、1表示启用
    #define MAX_BUFFER_SIZE 10 //缓冲区最大大小
    //#define DEBUG_RX_DO 引脚 GPIO_PIN_10
    //#define DEBUG_RX_DO GPIO_Port GPIOA
    /*用户代码末尾 PD */

    /*私有宏------------------------------------------------------- *
    /*用户代码 begin PM */

    /*用户代码结束 PM */

    /*私有变量------------------------------------------------------- *
    I2C_HandleTypeDef hi2c1;

    TIM_HandleTypeDef htim1;
    TIM_HandleTypeDef htim2;

    UART_HandleTypeDef huart1;

    /*用户代码 begin PV */
    uint8_t spiData [2];
    uint8_t spiRxData [2];
    uint8_t rxdata [2];
    uint8_t busyData [2]={0xFF、0xFF};

    uint8_t TX_2Byte [2]={0x00、0x00};
    uint8_t TX_3字节[3]={0x00、0x00、0x00};
    uint8_t TX_4字节[4]={0x00、0x00、0x00、0x00};
    uint8_t TX_6Byte [6]={0x00、0x00、0x00、0x00、0x00、 0x00};
    uint8_t TX_Buffer [MAX_Buffer_SIZE]={0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00};

    uint8_t RX_2Byte [2]={0x00、0x00};
    uint8_t RX_3Byte [3]={0x00、0x00、0x00};
    uint8_t RX_4字节[4]={0x00、0x00、0x00、0x00};
    uint8_t RX_6Byte [6]={0x00、0x00、0x00、0x00、0x00、 0x00};
    uint8_t RX_12字节[12]={0x00、0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00、0x00、0x00、 0x00、0x00};
    uint8_t RX_32byte [32]={0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00};
    uint8_t RX_Buffer [MAX_Buffer_SIZE]={0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00};
    unsigned int RX_CRC_Check = 0;
    //电池电压、温度、CC2电流、堆叠电压、PACK 引脚电压、 LD 引脚电压
    uint16_t CellVoltage [16]={0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00};
    浮点温度[3]={0、0、0};
    FET_Temperature = 0;
    浮点 HDQ_Temp = 0;
    浮点 DCHG_Temp = 0;
    浮点 DDSG_Temp = 0;
    uint16_t Stack_Voltage = 0x00;
    uint16_t LD_Voltage = 0x00;
    uint16_t PACK_Voltage = 0x00;
    uint16_t PACK_CURRENT = 0x00;
    浮点电流= 0;
    uint16_t AlarmBits = 0x00;
    uint32_t Samp1[2]={0x00、0x00};
    uint32_t RES = 0;
    uint32_t min_cell = 0;
    uint32_t Max_cell = 0;
    uint32_t CC3_CURRENT;
    uint32_t CC1_CURRENT;
    uint32_t Raw_CC2_Count;
    uint32_t Raw_CC3_Count;

    uint8_t SafetyStatusA;//安全状态寄存器 A
    uint8_t SafetyStatusB;//安全状态寄存器 B
    uint8_t SafetyStatusC;//安全状态寄存器 C
    uint8_t PFStatusA;//永久故障状态寄存器 A
    uint8_t PFStatusB;//永久故障状态寄存器 B
    uint8_t PFStatusC;//永久故障状态寄存器 C
    uint8_t FET_Status;// FET 状态寄存器内容请参阅 TRM 第12.2.20节-显示 FET 的状态

    uint16_t CB_ActiveCells;//电池平衡活动电池
    uint16_t DEVICE_NUMBER;

    uint8_t uV_Fault = 0;//欠压故障状态
    uint8_t OV_Fault = 0;//过压故障状态
    uint8_t SCD_Fault = 0;//短路故障状态
    uint8_t OCD_Fault = 0;//过流故障状态
    uint8_t LD_on = 0;//加载检测状态位
    uint8_t DCHG = 0;//放电 FET 状态
    uint8_t CHG = 0;//充电 FET 状态
    uint8_t PCHG = 0;//预充电 FET 状态
    uint8_t PDSG = 0;//预放电 FET 状态

    uint32_t 累加器介入_Int;
    uint32_t 累加成帧;
    uint32_t 累加时间;
    /*用户代码末尾 PV */

    /*私有函数原型------------------------------------------------------- *
    void SystemClock_Config (void);
    静态空 MX_GPIO_Init (空);
    静态空 MX_I2C1_Init (空);
    静态空 MX_TIM1_Init (空);
    静态空 MX_USART1_UART_Init (空);
    静态空 MX_TIM2_Init (空);
    /*用户代码 begin PFP */
    void delayUS (uint32_t us){//设置以微秒为单位的延迟。
    //uint8_t Tim = 0;
    _HAL_TIM_SET_COUNTER (&htim1、0);//将计数器值设置为0
    while (__HAL_TIM_GET_COUNTER (&htim1)< us);

    void delay_ticks (uint32_t ticks)

    SysTick -> LOAD =节拍;
    SysTick ->VAL = 0;
    SysTick ->CTRL = SysTK_CTRL_ENABLE_MSK;
    // COUNTFLAG 位在计数器到达0时设置为1。
    //读取时会自动清除。
    while ((SysTick ->CTRL & SysTick _CTRL_COUNTFLAG_MSK)=0);
    SysTick ->CTRL = 0;

    void CopyArray (uint8_t *源、uint8_t *目标、uint8_t 计数)

    uint8_t copyIndex = 0;
    for (copyIndex = 0;copyIndex < count;copyIndex++)

    dest[copyIndex]= source[copyIndex];

    unsigned char 校验和(unsigned char * ptr、unsigned char len)
    //计算写入 RAM 寄存器时的校验和。 校验和是字节总和的倒数。

    unsigned char i;
    unsigned char 校验和= 0;

    for (i=0;<len; i++)
    校验和+= PTR[i];

    校验和= 0xff &~Ω 校验和;

    return (校验和);

    unsigned char CRC8 (unsigned char * ptr、unsigned char len)

    unsigned char i;
    unsigned char crc=0;
    while (len--!=0)

    对于(i=0x80;i!=0;i/=2)

    if ((CRC & 0x80)!= 0)

    CRC *= 2;
    CRC ^= 0x107;

    其他
    CRC *= 2;

    if ((* ptr & i)!=0)
    CRC ^= 0x107;

    PTR++;

    return (CRC);

    void I2C_WriteReg (uint8_t reg_addr、uint8_t * reg_data、uint8_t count)

    #if CRC_Mode

    uint8_t CRC_COUNT = 0;
    CRC_COUNT = COUNT * 2;
    uint8_t crc1stByteBuffer [3]={0x10、reg_addr、reg_data[0]};
    unsigned int j;
    unsigned int i;
    uint8_t temp_CRC_buffer [3];

    TX_Buffer[0]= REG_DATA[0];
    TX_Buffer[1]= CRC8 (CRC 1stByteBuffer、3);

    J = 2;
    对于(i=1 <count; i++)

    TX_Buffer[j]= reg_data[i];
    J = j + 1;
    temp_CRC_buffer[0]= REG_DATA[i];
    TX_Buffer[j]= CRC8 (temp_CRC_buffer、1);
    J = j + 1;

    HAL_I2C_Mem_Write (&hi2c1、DEV_ADDR、REG_addr、1、TX_Buffer、 计数、1000);

    #endif

    #if CRC_Mode < 1
    HAL_StatusTypeDef 状态= HAL_OK;
    State=HAL_I2C_Mem_Write (&hi2c1、DEV_ADDR、REG_addr、1、REG_DATA、 计数、1000);
    if (state!= HAL_OK)


    #endif


    int I2C_ReadReg (uint8_t reg_addr、uint8_t * reg_data、uint8_t count)

    unsigned int RX_CRC_FAIL = 0;//复位为0。 如果处于 CRC 模式且 CRC 失败、则该值将递增。

    #if CRC_Mode

    uint8_t CRC_COUNT = 0;
    uint8_t ReceiveBuffer [10]={0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00};
    CRC_COUNT = COUNT * 2;
    unsigned int j;
    unsigned int i;
    unsigned char CRCc = 0;
    uint8_t temp_CRC_buffer [3];

    HAL_I2C_Mem_Read (&hi2c1、DEV_ADDR、REG_addr、1、ReceiveBuffer、 crc_count、1000);
    uint8_t crc1stByteBuffer [4]={0x10、reg_addr、0x11、ReceiveBuffer[0]};
    CRCc = CRC8 (CRC 1stByteBuffer、4);
    if (CRCc!= ReceiveBuffer[1])
    RX_CRC_FAIL += 1;

    RX_Buffer[0]= ReceiveBuffer[0];

    J = 2;
    对于(i=1 <count; i++)

    RX_Buffer[i]=接收缓冲器[j];
    TEMP_CRC_BUFFER[0]=接收缓冲器[j];
    J = j + 1;
    CRCc = CRC8 (TEMP_CRC_BUFFER、1);
    if (CRCc!= ReceiveBuffer[j])
    RX_CRC_FAIL += 1;
    J = j + 1;

    CopyArray (RX_Buffer、REG_DATA、CRC_COUNT);

    #endif

    #if CRC_Mode < 1
    // HAL_StatusTypeDef state = HAL_OK;
    HAL_I2C_Mem_Read (&hi2c1、DEV_ADDR、reg_addr、1、reg_data、 计数、1000);
    //if (state!= HAL_OK)
    //{

    //}
    #endif

    返回0;


    void AFE_Reset (){
    //重置命令。 将所有寄存器复位为默认值或 OTP 中编程的值。
    TX_2Byte[0]= 0x12;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_Init(){
    //配置器件 RAM 中的所有参数

    //进入 configupdate 模式(子命令0x0090)-需要处于 CONFIG_UPDATE 模式才能对器件 RAM 设置进行编程
    //有关 CONFIG_UPDATE 模式的完整说明,请参阅 TRM 第7.6节
    TX_2Byte[0]= 0x90;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    delayUS(2000);

    //进入 CONFIG_UPDATE 模式后、可以对 RAM 寄存器进行编程。 对 RAM 进行编程时、校验和和长度也必须为
    //编程以使更改生效。 BQ76952 TRM 的第13章详细介绍了所有 RAM 寄存器。
    //查找说明的一种更简单的方法是在 BQStudio Data Memory 屏幕中找到。 将鼠标移到寄存器名称上时、
    //屏幕上将弹出对寄存器和位的完整说明。
    // TRM 的第13.9节中也提供了数据存储器的摘要。

    //"电源配置"-设置 DSLP_LDO - 0x9234 = 0x2D82 (请参阅 TRM 第13.3.2节)
    //设置 DSLP_LDO 位可使 LDO 在器件进入深度睡眠模式时保持活动状态
    TX_4Byte[0]= 0x34;TX_4Byte[1]= 0x92;TX_4Byte[2]= 0x82;TX_4Byte[3]= 0x2D;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //'re 4/0 Config'-设置 REG0_EN 位以启用前置稳压器
    TX_3Byte[0]= 0x37;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x01;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //'re 4/12 Config'-启用具有3.3V 输出的 REG1
    TX_3Byte[0]= 0x36;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x0D;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //'VCell Mode'-启用16节电池- 0x9304 = 0x0000 (请参阅 TRM 第13.3.2.19节)
    // 0x0000设置16个单元格的默认值。
    TX_4Byte[0]= 0x04;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0x00;TX_4Byte[3]= 0x00;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //“默认报警屏蔽”-启用全扫描和可扫描位
    // 0xF882
    TX_4Byte[0]= 0x6D;TX_4Byte[1]= 0x92;TX_4Byte[2]= 0x82;TX_4Byte[3]= 0xf8;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //在'Enabled Protections A'中启用保护0x9261 = 0xBC (请参阅 TRM 第13.3.3.2节)
    //启用 SCD (短路)、OCD1 (放电过流)、OCC (充电过流)、
    // COV (过压)、CUV (欠压)
    TX_3Byte[0]= 0x61;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x00;/0xFC
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //启用'Enabled Protections B'中的所有保护0x9262 = 0xF7 (请参阅 TRM 第13.3.3.3节)
    //启用 OTF (过热 FET)、OTINT (内部过热)、OTD (放电过热)、
    // OTC (充电过热)、UTINT (内部欠温)、UTD (放电欠温)、UTC (充电欠温)
    TX_3Byte[0]= 0x62;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x00;//0xF7
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    #if 1.
    //将 TS1设置为测量电池温度- 0x92FD = 0x07 (请参阅 TRM 第13.3.2.12节)
    TX_3Byte[0]= 0xFD;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x07;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //将 TS3设置为测量 FET 温度- 0x92FF = 0x0F (请参阅 TRM 第13.3.2.14节)
    TX_3Byte[0]= 0xFF;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x0F;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    #endif
    #if 1.
    //设置 DFETOFF 引脚以控制 CHG 和 DSG FET - 0x92FB = 0x42 (设置为0x00以禁用)
    //请参阅 TRM 第13.3.2.10节、表13-7
    #if 0
    TX_3Byte[0]= 0xFB;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0xC2;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    #endif
    //设置警报引脚- 0x92FC = 0x2A -请参阅 TRM 第13.3.2.11节、表13-8
    //这会将警报引脚配置为在启用时驱动高电平(REG1电压)。
    //其他可用选项包括低电平有效、驱动 HiZ、使用 REG18 (1.8V)的驱动、弱内部上拉和下拉
    TX_3Byte[0]= 0xFC;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x2A;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    #endif

    #if 1.
    //设置电池平衡配置- 0x9335 = 0x03 -处于静置或充电模式时的自动平衡
    //参见 TRM 第13.3.11节。 TRM 的第10章详细介绍了电池平衡
    //另请参阅 TI.com 上的“使用 BQ76952、BQ76942电池监控器实现电池平衡”文档
    TX_3Byte[0]= 0x35;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x03;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //设置 COV (过压)阈值- 0x9278 = 0x55 (4301mV)
    // COV 阈值是该值乘以50.6mV、请参阅 TRM 第13.6.2节
    TX_3Byte[0]= 0x78;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x55;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //设置 SCD 阈值- 0x9286 = 0x05 (在1m Ω 感应电阻上100mV = 100A)
    //请参阅 TRM 部分13.6.7 0x05=100mV
    TX_3Byte[0]= 0x86;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x05;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //设置 SCD 延迟- 0x9287 = 0x03 (30us)请参阅 TRM 第13.6.7节
    //单位15us
    TX_3Byte[0]= 0x87;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x03;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //将 SCDL 锁存限制设置为1,以便仅在卸载时设置 SCD 恢复0x9295 = 0x01
    //如果未设置,则 SCD 将根据时间恢复(SCD 恢复时间参数)。
    //参见 TRM 第13.6.11.1节
    TX_3Byte[0]= 0x95;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x01;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    #if 1.
    //预充电启动 V
    TX_4Byte[0]= 0x0A;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0x48;TX_4Byte[3]= 0xF4;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //预充电停止 V
    TX_4Byte[0]= 0x0C;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0x1C;TX_4Byte[3]= 0xF3;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //预充电超时
    TX_3Byte[0]= 0x0E;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x00;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //预放电停止增量
    TX_3Byte[0]= 0x0F;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x00;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //放电电流阈值
    TX_4Byte[0]= 0x10;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0xE2;TX_4Byte[3]= 0xFF;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    // HAL_DELAY (1);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //充电电流阈值
    TX_4Byte[0]= 0x12;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0xF6;TX_4Byte[3]= 0xFF;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    // HAL_DELAY (1);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    #endif
    //毛培养状态初始化
    TX_4Byte[0]= 0x43;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0x10;TX_4Byte[3]= 0x00;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    // HAL_DELAY (1);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    //FET 选项
    TX_3Byte[0]= 0x08;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x1F;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //保护配置
    TX_4Byte[0]= 0x5F;TX_4Byte[1]= 0x92;TX_4Byte[2]= 0x00;TX_4Byte[3]= 0x00;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    // HAL_DELAY (1);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //取消保护 a
    TX_3Byte[0]= 0x69;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x00;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //Disccharg 保护 B
    TX_3Byte[0]= 0x6A;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x00;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //Disccharg 保护 C
    TX_3Byte[0]= 0x6B;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x00;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //体二极管
    TX_4Byte[0]= 0x73;TX_4Byte[1]= 0x92;TX_4Byte[2]= 0xEC;TX_4Byte[3]= 0xFF;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    // HAL_DELAY (1);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //CC 增益
    TX_6Byte[0]= 0xA8;TX_6Byte[1]= 0x91;TX_6Byte[2]= 0xF2;TX_6Byte[3]= 0x41;TX_6Byte[4]= 0x6f; TX_6Byte[5]= 0x41;
    I2C_WriteReg (0x3E、TX_6Byte、6);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_6Byte、6);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //HDQ 配置
    TX_3Byte[0]= 0x00;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x0B;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //DCHG 热敏电阻配置
    TX_3Byte[0]= 0x01;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x0B;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //TS1温度偏移
    TX_3Byte[0]= 0xCE;TX_3Byte[1]= 0x91;TX_3Byte[2]= 0x19;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //TS3温度偏移
    TX_3Byte[0]= 0xD0;TX_3Byte[1]= 0x91;TX_3Byte[2]= 0x19;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //HDQ 温度偏移
    TX_3Byte[0]= 0xD1;TX_3Byte[1]= 0x91;TX_3Byte[2]= 0x19;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //DCHG 温度偏移
    TX_3Byte[0]= 0xD2;TX_3Byte[1]= 0x91;TX_3Byte[2]= 0x19;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    #if 0
    //数据状态
    TX_2Byte[0]= 0x76;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(1000);
    I2C_ReadReg (0x40、RX_12字节、12);
    CC3_CURRENT =(RX_12Byte[21]<<8)+(RX_12Byte[20]);
    CC1_CURRENT =(RX_12Byte[23]<<8)+(RX_12Byte[22]);
    RAW_CC2_Count =((RX_12Byte[27]<<24)+(RX_12Byte[26]<<16)+(RX_12Byte[25]<8)+ RX_12Byte[24]);
    RAW_CC3_Count =((RX_12Byte[31]<<24)+(RX_12Byte[30][<16)+(RX_12Byte[29]<8)+ RX_12Byte[28]);
    delayUS(1000);
    #endif
    #if 0
    //TS3
    TX_3Byte[0]= 0xFF;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x0B;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    //TS1
    TX_3Byte[0]= 0xFD;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x0B;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    #endif

    #endif
    #if 0
    //***** 制造状态**** //
    TX_4Byte[0]= 0x43;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0x50;TX_4Byte[3]= 0x00;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    // HAL_DELAY (1);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x61、TX_2Byte、2);
    delayUS(1000);
    //********* //
    /***** FET 选项******* //
    TX_3Byte[0]= 0x08;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x1F;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    //********* //
    //******** 在*******上的所有 FET //
    TX_2Byte[0]= 0x96;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(1000);
    //********* //
    AFE_ReadFETStatus();
    #endif
    //退出 configupdate 模式-子命令0x0092
    TX_2Byte[0]= 0x92;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(1000);

    void Enable_REG1 ()

    TX_2Byte[0]= 0x90;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    //'re 4/0 Config'-设置 REG0_EN 位以启用前置稳压器
    TX_3Byte[0]= 0x37;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x01;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    //'re 4/12 Config'-启用具有3.3V 输出的 REG1
    TX_3Byte[0]= 0x36;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x0D;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);
    //退出 configupdate 模式-子命令0x0092
    TX_2Byte[0]= 0x92;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    //delayUS(1000);

    /********* Rohith ********编写的函数 //
    void AFE_FETOptions(){
    TX_3Byte[0]= 0x08;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x1F;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    void AFE_ManufacturingStatus (){

    TX_4Byte[0]= 0x43;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0x50;TX_4Byte[3]= 0x00;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    // HAL_DELAY (1);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x61、TX_2Byte、2);
    delayUS(1000);


    void Manufacturing 状态读取(){


    void pdsg_test(){
    TX_2Byte[0]= 0x1C;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void PCHG_TEST (){
    TX_2Byte[0]= 0x1E;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void CHG_TEST (){
    TX_2Byte[0]= 0x1F;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void DSG_TEST (){
    TX_2Byte[0]= 0x20;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void charge pump(){
    TX_3Byte[0]= 0x09;TX_3Byte[1]= 0x93;TX_3Byte[2]= 0x01;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);
    delayUS(1000);

    void ComM_Type (){
    TX_3Byte[0]= 0x39;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x12;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);

    void Swap_Comm_Mode (){
    TX_2Byte[0]= 0x90;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);


    TX_3Byte[0]= 0x39;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x12;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    //delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);

    TX_2Byte[0]= 0xBC;TX_2Byte[1]= 0x29;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    TX_2Byte[0]= 0x92;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void Dfet_off (){

    TX_3Byte[0]= 0xFB;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x00;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);

    void CFET_OFF (){

    TX_3Byte[0]= 0xFA;TX_3Byte[1]= 0x92;TX_3Byte[2]= 0x00;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);


    void Status_Read(){
    uint8_t rd_data;
    TX_2Byte[0]= 0x57;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(2000);
    I2C_ReadReg (0x40、RX_2Byte、2);
    RD_DATA =(RX_2Byte[1]*256 + RX_2Byte[0]);

    void Vcell(){
    TX_4Byte[0]= 0x04;TX_4Byte[1]= 0x93;TX_4Byte[2]= 0x00;TX_4Byte[3]= 0x00;
    I2C_WriteReg (0x3E、TX_4Byte、4);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_4Byte、4);TX_2Byte[1]= 0x06;//校验和和长度
    I2C_WriteReg (0x60、TX_2Byte、2);

    //********* 结束******* //
    // FET 控制命令

    void AFE_FET_ENABLE(){
    //切换制造状态寄存器中的 FET_EN 位。 因此、该命令可用于启用或禁用 FET。
    TX_2Byte[0]= 0x22;TX_2Byte[1]= 0x00;//0x22
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_FET_Control (uint8_t FET_States){// bit 3 = PCHG_OFF、bit 2 = CHG_OFF、bit 1 = PDSG_OFF、bit 0 = DSG_OFF
    TX_3Byte[0]= 0x97;TX_3Byte[1]= 0x00;TX_3Byte[2]= FET_States;
    I2C_WriteReg (0x3E、TX_3Byte、3);
    delayUS(1000);
    TX_2Byte[0]=校验和(TX_3Byte、3);TX_2Byte[1]= 0x05;
    I2C_WriteReg (0x60、TX_2Byte、2);

    void DSG_PDSG_OFF (){
    //禁用放电(和预放电) FET
    //子命令0x0093请参阅 TRM 表5-8 (DSG_PDSG_OFF ())
    TX_2Byte[0]= 0x93;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void CHG_PCHG_OFF (){
    //禁用充电(和预充电) FET
    //子命令0x0094请参阅 TRM 表5-8 (CHG_PCHG_OFF ())
    TX_2Byte[0]= 0x94;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_All_FET_OFF (){
    //使用命令0x0095禁用所有 FET 请参阅 TRM 表5-8
    TX_2Byte[0]= 0x95;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_All_FETs_on (){
    //要使用命令0x0096启用的所有 FET 请参阅 TRM 表5-8
    TX_2Byte[0]= 0x96;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_BOTHOFF (){
    //使用 DFETOFF (BOTHOFF)引脚禁用所有 FET
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_8、GPIO_PIN_SET);// DFETOFF 引脚(BOTHOFF)设置为低电平

    void AFE_RESET_BOTHOFF (){
    //重置 DFETOFF (BOTHOFF)引脚
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_8、GPIO_PIN_RESET);// DFETOFF 引脚(BOTHOFF)设置为低电平

    void AFE_ReadFETStatus(){
    //读取 FET 状态以查看启用了哪些 FET
    I2C_ReadReg (0x7F、RX_2Byte、2);
    FET_Status =(RX_2Byte[1]*256 + RX_2Byte[0]);
    DCHG = 0x4 & RX_2Byte[0];//放电 FET 状态
    CHG = 0x1 & RX_2Byte[0];//充电 FET 状态
    PCHG = 0x2 & RX_2Byte[0];//预充电 FET 状态
    PDSG = 0x8 & RX_2Byte[0];//预放电 FET 状态


    // FET 控制命令结束


    // AFE 电池平衡命令

    void CB_ACTIVE_Cells (){
    //检查哪些电池正在平衡的状态
    TX_2Byte[0]= 0x83;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    I2C_ReadReg (0x40、RX_2Byte、2);
    CB_ActiveCells =(RX_2Byte[1]*256 + RX_2Byte[0]);

    void CFET_OFF_LO (){
    TX_2Byte[0]= 0x28;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void DFET_OFF_LO (){
    TX_2Byte[0]= 0x28;TX_2Byte[1]= 0x01;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    // AFE 电池平衡命令结束


    // AFE 电源命令
    void AFE_DeepSleep (){
    //将器件置于深度睡眠模式。 请参阅 TRM 第7.4节
    TX_2Byte[0]= 0x0F;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_ExitDeepSleep (){
    //退出深度睡眠模式。 请参阅 TRM 第7.4节
    TX_2Byte[0]= 0x0E;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_ShutdownCommand (){
    //将器件置于关断模式。 请参阅 TRM 第7.5节
    TX_2Byte[0]= 0x10;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_ShutdownPin (){
    //使用 RST_SHUT 引脚将器件置于关断模式
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_9、GPIO_PIN_SET);//设置 RST_SHUT 引脚

    void AFE_ReleaseShutdownPin (){
    //释放 RST_SHUT 引脚
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_9、GPIO_PIN_RESET);//重置 RST_SHUT 引脚

    void AFE_SLEEP_ENABLE (){// SLEEP_ENABLE 0x0099
    //允许器件在电流低于睡眠电流时进入睡眠模式。 请参阅 TRM 第7.3节
    TX_2Byte[0]= 0x99;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void AFE_SLEEP_DISABLE (){// SLEEP_DISABLE 0x009A
    //使器件退出睡眠模式。 请参阅 TRM 第7.3节
    TX_2Byte[0]= 0x9A;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    // AFE 电源命令结束


    // AFE 状态和故障命令

    uint16_t AFE_ReadAlarmStatus(){
    //读取该寄存器以找出警报引脚被置为有效的原因。 有关完整说明、请参阅 TRM 的第6.6节。
    I2C_ReadReg (0x62、RX_2Byte、2);
    返回(RX_2Byte[1]*256 + RX_2Byte[0]);

    void AFE_ReadSafetyStatus(){
    //读取安全状态 A/B/C 并查找设置了哪些位
    //这显示触发了哪些主要保护
    I2C_ReadReg (0x03、RX_2Byte、2);
    SafetyStatusA =(RX_2Byte[1]*256 + RX_2Byte[0]);
    UV_Fault = 0x4 & RX_2Byte[0];
    OV_Fault = 0x8 & RX_2Byte[0];
    SCD_Fault=0x8 & RX_2Byte[1];
    OCD_Fault = 0x2 & RX_2Byte[1];
    I2C_ReadReg (0x05、RX_2Byte、2);
    SafetyStatusB =(RX_2Byte[1]*256 + RX_2Byte[0]);
    I2C_ReadReg (0x07、RX_2Byte、2);
    SafetyStatusC =(RX_2Byte[1]*256 + RX_2Byte[0]);

    void AFE_ReadPFStatus(){
    //读取永久性故障状态 A/B 并查找设置了哪些位
    //这显示触发了哪些永久性故障
    I2C_ReadReg (0x0B、RX_2Byte、2);
    PFStatusA =(RX_2Byte[1]*256 + RX_2Byte[0]);
    I2C_ReadReg (0x0D、RX_2Byte、2);
    PFStatusB =(RX_2Byte[1]*256 + RX_2Byte[0]);
    I2C_ReadReg (0x0F、RX_2Byte、2);
    PFStatusC =(RX_2Byte[1]*256 + RX_2Byte[0]);


    void AFE_ControlStatus(){
    //控制状态寄存器-位0 - LD_ON (检测到负载)
    //请参阅 TRM 表6-1
    I2C_ReadReg (0x00、RX_2Byte、2);
    LD_ON = 0x1 & RX_2Byte[0];

    void AFE_BatteryStatus(){
    //电池状态寄存器-请参阅 TRM 表6-2
    I2C_ReadReg (0x12、RX_2Byte、2);

    void AFE_ClearVault (){
    TX_2Byte[0]= 0x00;TX_2Byte[1]= 0xf8;
    I2C_WriteReg (0x62、TX_2Byte、2);

    void AFE_ClearScanBits (){
    TX_2Byte[0]= 0x82;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x62、TX_2Byte、2);

    void AFE_PFReset (){
    TX_2Byte[0]= 0x29;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    uint16_t AFE_DeviceID (){
    //使用子命令0x0001读取设备 ID
    TX_2Byte[0]= 0x01;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(500);
    I2C_ReadReg (0x40、RX_2Byte、2);
    返回(RX_2Byte[1]*256 + RX_2Byte[0]);

    void AFE_STATUS (){
    TX_2Byte[0]= 0x90;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(1000);
    TX_2Byte[0]= 0x75;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(1000);
    I2C_ReadReg (0x40、RX_32byte、32);
    MAX_CELL =(RX_32byt[5]<<8)+(RX_32byte[4]);
    MIN_CELL =(RX_32BYTE[7]<8)+(RX_32BYTE[6]);
    CC3_CURRENT =(RX_32BYTE[21]<<8)+(RX_32BYTE[20]);
    CC1_CURRENT =(RX_32BYTE[23]<<8)+(RX_32BYTE[22]);
    RAW_CC2_Count =((RX_32byt[27]<<24)+(RX_32byt[26]<<16)+(RX_32byt[25]<8)+ RX_32byt[24]);
    RAW_CC3_Count =((RX_32byt[31]<<24)+(RX_32byt[30]<<16)+(RX_32byt[29]<8)+ RX_32byt[28]);
    delayUS(1000);
    TX_2Byte[0]= 0x92;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);


    // AFE 状态和故障命令结束


    // AFE 测量命令

    uint16_t AFE_ReadCellVoltage (uint8_t CHANNEL){
    I2C_ReadReg (通道*2+0x14、RX_2Byte、2);
    返回(RX_2Byte[1]*256 + RX_2Byte[0]);//电池电压以 mV 为单位报告

    uint16_t AFE_ReadStackVoltage (){
    I2C_ReadReg (0x34、RX_2Byte、2);
    返回10 *(RX_2Byte[1]*256 + RX_2Byte[0]);//电压以0.01V 为单位报告

    uint16_t AFE_ReadPackVoltage (){
    I2C_ReadReg (0x36、RX_2Byte、2);
    返回10 *(RX_2Byte[1]*256 + RX_2Byte[0]);//电压以0.01V 为单位报告

    uint16_t AFE_ReadLDVoltage (){
    I2C_ReadReg (0x38、RX_2Byte、2);
    返回10 *(RX_2Byte[1]*256 + RX_2Byte[0]);//电压以0.01V 为单位报告

    uint16_t AFE_ReadCurrent (){
    //uint8_t cure = 0;
    I2C_ReadReg (0x3A、RX_2Byte、2);
    返回(RX_2Byte[1]*256 + RX_2Byte[0]);//电流以 mA 为单位报告

    float AFE_ReadTemperature (uint8_t channel){
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_15、GPIO_PIN_SET);
    开关(通道)

    情况0:
    I2C_ReadReg (0x70、RX_2Byte、2);// TS1引脚
    中断;
    案例1:
    I2C_ReadReg (0x74、RX_2Byte、2);// TS3引脚、FET 温度
    中断;
    案例2:
    I2C_ReadReg (0x76、RX_2Byte、2);// HDQ、FET 温度
    中断;
    案例3:
    I2C_ReadReg (0x78、RX_2Byte、2);// DCHG 引脚、FET 温度
    中断;
    默认值:break;

    返回(0.1 *(float)(RX_2Byte[1]*256 + RX_2Byte[0]))- 273.15;//将0.1K 转换为 Celcius


    void AFE_ReadPassQ(){
    //读取累积的电荷和 DASTATUS6的时间(请参阅 TRM 表4-6)
    TX_2Byte[0]= 0x76;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(1000);
    I2C_ReadReg (0x40、RX_12字节、12);
    累加器介入_Int =((RX_12Byte[3]<<24)+(RX_12Byte[2]<<16)+(RX_12Byte[1]<8)+ RX_12Byte[0]);
    累加器强_分数=((RX_12Byte[7]<<24)+(RX_12Byte[6]<<16)+(RX_12Byte[5]<8)+ RX_12Byte[4]);
    累加器时间=((RX_12Byte[11]<24)+(RX_12Byte[10][<16)+(RX_12Byte[9]<8)+ RX_12Byte[8]);

    void AFE_ClearPassQ(){
    //清除累积的电荷和时间,命令0x0082
    TX_2Byte[0]= 0x82;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);

    void config_mode(){
    TX_2Byte[0]= 0x90;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);


    void Exit_config_mode(){
    TX_2Byte[0]= 0x92;TX_2Byte[1]= 0x00;
    I2C_WriteReg (0x3E、TX_2Byte、2);


    // AFE 测量命令结束

    /*用户代码末尾 PFP */

    /*私人用户代码------------------------------------------------------- *
    /*用户代码开始0 */

    /*用户代码结束0 */

    /**
    *@简要介绍应用程序入口点。
    *@retval int
    *
    int main (空)

    /*用户代码 begin 1 */
    volatile int i = 0;
    char UART_buf[50];
    int UART_buf_len;

    /*用户代码结束1 */

    /* MCU 配置------------------------------------------------------- *

    /*复位所有外设、初始化闪存接口和 SysTick。 *
    HAL_Init();

    /*用户代码 begin Init */

    /*用户代码结束初始化*/

    /*配置系统时钟*/
    SystemClock_Config();

    /*用户代码 begin sysinit */

    /*用户代码结束 sysinit */

    /*初始化所有已配置的外设*/
    mx_GPIO_Init();
    mx_I2C1_Init();
    MX_TIM1_Init();
    mx_USART1_UART_Init();
    MX_TIM2_Init();
    /*用户代码 begin 2 */
    //DFET 引脚 fetofff (低电平)
    HAL_TIM_Base_Start (&H);
    //HAL_GPIO_WritePin (GPIOC、GPIO_PIN_7、GPIO_PIN_RESET);// DEFET 引脚
    HAL_GPIO_WritePin (GPIOA、GPIO_PIN_3、GPIO_PIN_RESET);

    delayUS(10000);

    AFE_RESET();
    delayUS(60000);
    AFE_Init();
    delayUS(10000);
    //AFE_FET_ENABLE ();
    //delayUS(10000);
    AFE_All_FETs_on ();
    AFE_ReadFETStatus();
    delayUS(10000);
    AFE_SLEEP_DISABLE();

    delayUS (60000);delayUS (60000);delayUS (60000);delayUS (60000);//等待 FET 关闭后开始测量
    CellVoltage[1]= AFE_ReadCellVoltage (1);
    CellVoltage[5]= AFE_ReadCellVoltage (5);
    CellVoltage[10]= AFE_ReadCellVoltage (10);
    STACK_Voltage = AFE_ReadStackVoltage ();
    PACK_Voltage = AFE_ReadPackVoltage ();
    LD_Voltage = AFE_ReadLDVoltage ();
    //PACK_CURRENT = AFE_ReadCurrent ();
    温度[0]= AFE_ReadTemperature (0);
    FET_Temperature = AFE_ReadTemperature (1);
    HDQ_Temp = AFE_ReadTemperature (2);
    DCHG_Temp = AFE_ReadTemperature (3);
    //DDSG_Temp = AFE_ReadTemperature (4);
    // AFE_All_FETs_on ();
    // AFE_ReadFETStatus();

    #if 0
    AFE_SLEEP_DISABLE();
    AFE_ManufacturingStatus();
    AFE_ReadFETStatus();
    电荷泵();
    AFE_FETOptions();
    // AFE_FET_ENABLE ();
    AFE_FET_Control (0x00);
    AFE_ReadFETStatus();
    AFE_All_FETs_on ();
    AFE_ReadFETStatus();
    #endif

    HAL_StatusTypeDef stat = HAL_OK;
    STAT = HAL_I2C_IsDeviceReady (&hi2c1、0x10、2、10);
    if (stat =HAL_OK)



    /*用户代码末尾2 */

    /*无限循环*/
    /*用户代码在*/时开始
    while (1)

    /*用户代码结束,同时*/

    /*用户代码 begin 3 */
    AFE_STATUS();
    PACK_CURRENT = AFE_ReadCurrent ();
    电流= PACK_CURRENT * 14.9538;
    AFE_ReadFETStatus();
    // HAL_GPIO_WritePin (RS485_1_RO_DO_UC_GPIO_Port、UC_RDE_DO_RS485_1_Pin、1);//启用 uart1
    // HAL_GPIO_WritePin (uC_DI_DO_RS485_1_GPIO_Port、uC_RDE_DO_RS485_1_Pin、1);//启用 UART1
    // HAL_GPIO_WritePin (GPIOA、GPIO_PIN_10、1);//启用 UART1
    HAL_GPIO_WritePin (DEBUG_RX_DO_GPIO_Port、DEBUG_RDE_DO_Pin、1);
    for (int i = 0;i <=15;i++)

    CellVoltage[i]= AFE_ReadCellVoltage (i);
    printf ("电池电压[%d]=%d"、I、电池电压);


    温度[0]= AFE_ReadTemperature (0)* 10;
    printf ("环境温度:%d"、Temperature[0]);
    FET_Temperature = AFE_ReadTemperature (1)* 10;
    printf ("温度 MOSFET:%d"、FET_Temperature);
    HDQ_Temp = AFE_ReadTemperature (2)* 10;
    printf (“HDQ 温度:%d”,HDQ_Temp);
    DCHG_Temp = AFE_ReadTemperature (3)* 10;
    printf (“DCHG 温度:%d”,DCHG_Temp);
    // DDSG_Temp = AFE_ReadTemperature (4);
    //PA10端口、PA8引脚、1.
    HAL_GPIO_WritePin (DEBUG_RX_DO_GPIO_Port、DEBUG_RDE_DO_Pin、1);
    // HAL_GPIO_WritePin (RS485_1_RO_DO_UC_GPIO_Port、UC_RDE_DO_RS485_1_Pin、1);//启用 uart1
    // HAL_GPIO_WritePin (RDE_DO_GPIO_Port、RDE_DO_Pin、0);//禁用 uart2
    // HAL_GPIO_WritePin (GPIOA、GPIO_PIN_10、1);//启用 UART1
    // HAL_GPIO_WritePin (RS485_1_RO_DO_UC_GPIO_Port、UC_RDE_DO_RS485_1_Pin、0);//禁用 UART1
    #if 1.
    IF (AlarmBits & 0x82){
    AFE_ClearScanBits();

    IF (AlarmBits & 0xC000){
    AFE_ReadSafetyStatus();
    AFE_ReadPFStatus();
    AFE_ClearVault ();
    AFE_PFReset ();

    #endif

    /*用户代码结束3 */

    /**
    *@简要系统时钟配置
    *@Retval 无
    *
    空系统时钟配置(空)

    RCC_OscInitTypeDef RCC_OscInitStruct={0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct={0};
    RCC_PeriphCLKInitTypeDef PeriphClkInit ={0};

    /**根据指定的参数初始化 RCC 振荡器
    *在 RCC_OscInitTypeDef 结构中。
    *
    RCC_OscInitStruct.OscatorType = RCC_OSCILATORTYPE_MSI;
    RCC_OscInitStruct.MSIState = RCC_MSI_ON;
    RCC_OscInitStruct.MSICalibrationValue = 0;
    RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
    RCC_OscInitStruct.PLL.PLLM = 1;
    RCC_OscInitStruct.PLL.PLLN = 36;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
    IF (HAL_RCC_OscConfig (&RCC_OscInitStruct)!= HAL_OK)

    ERROR_Handler();

    /**初始化 CPU、AHB 和 APB 总线时钟
    *
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLK 分频器= RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig (&RCC_ClkInitStruct, flash_latit_4)!= HAL_OK)

    ERROR_Handler();

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1;
    PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
    PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig (&PeriphClkInit)!= HAL_OK)

    ERROR_Handler();

    /**配置主内部稳压器输出电压
    *
    if (HAL_PWREx_ControlVoltageScaling (PWR_Regulator _VOLTAGE_SCALE1)!= HAL_OK)

    ERROR_Handler();

    /**
    *@I2C1初始化函数简介
    *@param 无
    *@Retval 无
    *
    静态空 MX_I2C1_Init (空)

    /*用户代码 begin I2C1_Init 0 */

    /*用户代码结束 I2C1_Init 0 */

    /*用户代码 begin I2C1_Init 1 */

    /*用户代码结束 I2C1_Init 1 */
    hi2c1.instance = I2C1;
    hi2c1.Init.Timing = 0x10808DD3;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init (&hi2c1)!= HAL_OK)

    ERROR_Handler();

    /**配置模拟过滤器
    *
    if (HAL_I2CEx_ConfigAnalogFilter (&hi2c1、I2C_ANALOGUEFILTER_ENABLE)!= HAL_OK)

    ERROR_Handler();

    /**配置数字过滤器
    *
    if (HAL_I2CEx_ConfigDigitalFilter (&hi2c1、0)!= HAL_OK)

    ERROR_Handler();

    /*用户代码 begin I2C1_Init 2 */

    /*用户代码结束 I2C1_Init 2 */

    /**
    *@TIM1初始化函数简介
    *@param 无
    *@Retval 无
    *
    静态空 MX_TIM1_Init (空)

    /*用户代码 begin TIM1_Init 0 */

    /*用户代码结束 TIM1_Init 0 */

    TIM_ClockConfigTypeDef sClockSourceConfig ={0};
    TIM_MasterConfigTypeDef sMasterConfig ={0};

    /*用户代码 begin TIM1_Init 1 */

    /*用户代码结束 TIM1_Init 1 */
    hdim1.instance = TIM1;
    Htim1.Init.Prescaler = 63;
    Htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.period = 65535;
    Htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    hdim1.Init.RefetitionCounter = 0;
    htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init (&htim1)!= HAL_OK)

    ERROR_Handler();

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource (&htim1、&sClockSourceConfig)!= HAL_OK)

    ERROR_Handler();

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_Timex_MasterConfigSynchronization (&htim1、&sMasterConfig)!= HAL_OK)

    ERROR_Handler();

    /*用户代码 begin TIM1_Init 2 */

    /*用户代码结束 TIM1_Init 2 */

    /**
    *@TIT2初始化函数简介
    *@param 无
    *@Retval 无
    *
    静态空 MX_TIM2_Init (空)

    /*用户代码 begin TIM2_Init 0 */

    /*用户代码结束 TIM2_Init 0 */

    TIM_ClockConfigTypeDef sClockSourceConfig ={0};
    TIM_MasterConfigTypeDef sMasterConfig ={0};
    TIM_OC_InitTypeDef sConfigOC ={0};

    /*用户代码 begin TIM2_Init 1 */

    /*用户代码结束 TIM2_Init 1 */
    hdim2.instance = TIT2;
    hdim2.Init.Prescaler = 63;
    Htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    hdim2.Init.period = 65535;
    Htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init (&htim2)!= HAL_OK)

    ERROR_Handler();

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource (&htim2、&sClockSourceConfig)!= HAL_OK)

    ERROR_Handler();

    if (HAL_TIM_OC_Init (&htim2)!= HAL_OK)

    ERROR_Handler();

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_Timex_MasterConfigSynchronization (&htim2、&sMasterConfig)!= HAL_OK)

    ERROR_Handler();

    sConfigOC.OCMode = TIM_OCMODE_TIM;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFast_disable;
    if (HAL_TIM_OC_ConfigChannel (&htim2、&sConfigOC、TIM_CHANNEL)!= HAL_OK)

    ERROR_Handler();

    if (HAL_TIM_OC_ConfigChannel (&htim2、&sConfigOC、TIM_CHANNEL)!= HAL_OK)

    ERROR_Handler();

    if (HAL_TIM_OC_ConfigChannel (&htim2、&sConfigOC、TIM_CHANNEL 3)!= HAL_OK)

    ERROR_Handler();

    if (HAL_TIM_OC_ConfigChannel (&htim2、&sConfigOC、TIM_CHANNEL)!= HAL_OK)

    ERROR_Handler();

    /*用户代码 begin TIM2_Init 2 */

    /*用户代码结束 TIM2_Init 2 */

    /**
    *@简要 USART1初始化函数
    *@param 无
    *@Retval 无
    *
    静态空 MX_USART1_UART_Init (空)

    /*用户代码 begin USART1_Init 0 */

    /*用户代码结束 USART1_Init 0 */

    /*用户代码 begin USART1_Init 1 */

    /*用户代码结束 USART1_Init 1 */
    huart1.instance = USART1;
    huart1.Init.budrate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.stopbits = UART_stopbits_1;
    huart1.Init.Parity = UART_parity;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.oversing= UART_oversing_16;
    huart1.Init.OneBitSampling = UART_one_bit_sample_disable;
    huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_UART_Init (&huart1)!= HAL_OK)

    ERROR_Handler();

    /*用户代码 begin USART1_Init 2 */

    /*用户代码结束 USART1_Init 2 */

    /**
    *@简单 GPIO 初始化函数
    *@param 无
    *@Retval 无
    *
    静态空 MX_GPIO_Init (空)

    GPIO_InitTypeDef GPIO_InitStruct={0};

    /* GPIO 端口时钟启用*/
    _HAL_RCC_GPIOA_CLK_ENABLE ();
    _HAL_RCC_GPIOC_CLK_ENABLE();
    _HAL_RCC_GPIOD_CLK_ENABLE ();
    _HAL_RCC_GPIOB_CLK_ENABLE ();

    /*配置 GPIO 引脚输出电平*/
    HAL_GPIO_WritePin (RST_SHIT_B_UC_GPIO_Port、RST_SHIT_B_UC_Pin、GPIO_PIN_RESET);

    /*配置 GPIO 引脚输出电平*/
    HAL_GPIO_WritePin (DFETOFF_B_UC_GPIO_Port、DFETOFF_B_UC_Pin、GPIO_PIN_RESET);

    /*配置 GPIO 引脚输出电平*/
    HAL_GPIO_WritePin (GPIOA、DEBUG_RDE_DO_PIN|UC_TEMP_EN_DO_M_Pin、GPIO_PIN_SET);

    /*配置 GPIO 引脚输出电平*/
    HAL_GPIO_WritePin (RDE_DO_GPIO_Port、RDE_DO_Pin、GPIO_PIN_RESET);

    /*配置 GPIO 引脚:RST_SHIT_B_UC_Pin DEBUG_RDE_DO_Pin UC_TEMP_EN_DO_M_Pin *
    GPIO_InitStruct.Pin = RST_SHut_B_uC_Pin |调试_RDE_DO_Pin | uC_TEMP_EN_DO_M_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPSI_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPED_FREQ_LOW;
    HAL_GPIO_Init (GPIOA、&GPIO_InitStructt);

    /*配置 GPIO 引脚:DFETOFF_B_UC_Pin */
    GPIO_InitStruct.Pin = DFETOFF_B_uC_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPSI_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPED_FREQ_LOW;
    HAL_GPIO_Init (DFETOFF_B_UC_GPIO_Port、&GPIO_InitStructt);

    /*配置 GPIO 引脚:RDE_DO_Pin */
    GPIO_InitStruct.Pin = RDE_DO_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPSI_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPED_FREQ_LOW;
    HAL_GPIO_Init (RDE_DO_GPIO_Port、&GPIO_InitStructt);

    /*用户代码 begin 4 */

    /*用户代码结束4 */

    /**
    *@简述如果发生错误、则执行此函数。
    *@Retval 无
    *
    空 Error_Handler (空)

    /*用户代码 begin Error_Handler_debug */
    /*用户可以添加自己的实现以报告 HAL 错误返回状态*/
    _disable_IRQ ();
    while (1)


    /*用户代码 End Error_Handler_debug */

    #ifdef use_full_assert
    /**
    *@brief 会报告源文件的名称和源行号
    *发生了 assert_param 错误的位置。
    *@param 文件:指向源文件名的指针
    *@param 行:assert_param 错误行源代码
    *@Retval 无
    *
    void assert_failed (uint8_t *文件、uint32_t 行)

    /*用户代码 begin 6 */
    /*用户可以添加自己的实施以报告文件名和行号,
    示例:printf ("错误的参数值:第%d\r\n"行上的文件%s、文件、行)*/
    /*用户代码结束6 */

    #endif /* use_full_assert */

    /******** (c)版权所有 STMicroelectronics ***** 文件末尾****/

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

    您好、Rohith、  

    为了解决当前读数的问题、您是否获得了~65、000的值? 电流读数将为二进制补码、因此您看到的十进制数实际上附加了一个符号、以获得负电流。 考虑到器件上的电流读数从 SRP 到 SRN、这通常是正常的。 以下是二进制补码转换器的链接、可为您提供帮助: https://www.rapidtables.com/convert/number/decimal-to-hex.html

    此外、我在 AFE_Init 的 CC 增益部分的代码中注意到、第568行应为 TX_2Byte[1]= 0x08;(我编辑了原始帖子以更新此帖子)。 此外、如果您使用0.5m Ω Rsense、则需要同时更新 CCGain (0x91A8)和容量增益(0x91AC)。 这不会影响您的原始结果、但会影响累积电荷功能。

    为了解决您的 FET 问题、我将通过您的代码来查看这种方法是否存在任何问题、但现在、我想查看 FET 的运行是否存在误解。 根据我的理解、当您为器件加电时(以及在设置配置后)、充电 FET 和预放电 FET 将开启(根据您的规格)、然后在预放电增量/超时后、预放电 FET 将关闭、然后放电 FET 将开启。 这是正常操作。 预放电 FET 应在达到电压差值或达到超时时间后关闭、以便放电 FET 可以导通。

    您现在似乎遇到了放电 FET 在整个70V 电压下无法开启的问题。 这可能是由多种因素引起的、但常见的触发器是发生故障、该故障专门关断放电 FET (可能是欠压故障(不太可能)或放电过流(OCD1))。 我建议读取安全状态寄存器。 在您的代码中、有一个 AFE_ReadSafetyStatus 函数、该函数具有相应的 UV_Fault、OCD_Fault 标志、您可以使用这些标志进行监控。 您还需要检查是否触发了任何其他故障位。

    希望这对您有所帮助、

    Andrew  

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

    您好、

    我已按照您的建议进行了更改、

    我观察到放电 MOSFET 未通过泵旋转、

    以下是我的观察结果、

    • 当我尝试打开放电 FET 时、我能够观察到 DSG 的 FET 状态已打开、但无法测量70V、在这里、我只能观察到状态位已打开。

    我在这里附加了我的实时手表图像、

    我在这里连接了各种硬件引脚的电压测量值、

    • 我观察到,当我打开所有 FET 时,预充电 FET 没有打开,制造状态为0x0050,打开预充电 FET 的方法是什么。
    • 我还会禁用预放电超时和预放电增量位为0,并假设放电 FET 已打开,而放电 FET 未在70V 时打开,并且我观察到已设置了 afe 状态。

    我附上了我的守则、请仔细查看。

    /* USER CODE BEGIN Header */
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * <h2><center>Copyright Copyright (c) 2021 STMicroelectronics.
      * All rights reserved.</center></h2>
      *
      * This software component is licensed by ST under BSD 3-Clause license,
      * the "License"; You may not use this file except in compliance with the
      * License. You may obtain a copy of the License at:
      *                        opensource.org/licenses/BSD-3-Clause
      *
      ******************************************************************************
      */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include<stdio.h>
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    #define DEV_ADDR 0x10    // Device address
    #define CRC_Mode  0  // 0 for disabled, 1 for enabled
    #define MAX_BUFFER_SIZE     10  //Max buffer size
    //#define DEBUG_RX_DO_Pin GPIO_PIN_10
    //#define DEBUG_RX_DO_GPIO_Port GPIOA
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    I2C_HandleTypeDef hi2c1;
    
    TIM_HandleTypeDef htim1;
    TIM_HandleTypeDef htim2;
    
    UART_HandleTypeDef huart1;
    
    /* USER CODE BEGIN PV */
    uint8_t spiData [2];
    uint8_t spiRxData [2];
    uint8_t rxdata [2];
    uint8_t busyData [2] = {0xFF, 0xFF};
    
    uint8_t TX_2Byte [2] = {0x00, 0x00};
    uint8_t TX_3Byte [3] = {0x00, 0x00, 0x00};
    uint8_t TX_4Byte [4] = {0x00, 0x00, 0x00, 0x00};
    uint8_t TX_6Byte [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    uint8_t TX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    
    uint8_t RX_2Byte [2] = {0x00, 0x00};
    uint8_t RX_3Byte [3] = {0x00, 0x00, 0x00};
    uint8_t RX_4Byte [4] = {0x00, 0x00, 0x00, 0x00};
    uint8_t RX_6Byte [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    uint8_t RX_12Byte [12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    uint8_t RX_32Byte [32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00 ,0x00, 0x00, 0x00, 0x00,0x00, 0x00};
    uint8_t RX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    unsigned int RX_CRC_Check = 0;
    // Variables for cell voltages, temperatures, CC2 current, Stack voltage, PACK Pin voltage, LD Pin voltage
    uint16_t CellVoltage [16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    float Temperature [3] = {0,0,0};
    float FET_Temperature = 0;
    float HDQ_Temp = 0;
    float DCHG_Temp = 0;
    float DDSG_Temp = 0;
    uint16_t result_bin = 0;
    uint16_t Stack_Voltage = 0x00;
    uint16_t LD_Voltage = 0x00;
    uint16_t PACK_Voltage = 0x00;
    uint16_t PACK_Current = 0x00;
    float Current = 0;
    uint16_t AlarmBits = 0x00;
    uint32_t Samp1[2] ={0x00, 0x00};
    uint32_t Res = 0;
    uint32_t Min_cell = 0;
    uint32_t Battery_voltage_sum = 0;
    uint32_t Avg_cell_temp = 0;
    uint32_t Fet_temp = 0;
    uint32_t Max_cell_temp = 0;
    uint32_t Min_cell_temp = 0;
    uint32_t Avg_min_max_temp = 0;
    uint32_t Max_cell = 0;
    uint32_t CC3_Current;
    uint32_t CC1_Current;
    uint32_t Raw_CC2_Count;
    uint32_t Raw_CC3_Count;
    
    uint8_t SafetyStatusA;  // Safety Status Register A
    uint8_t SafetyStatusB;  // Safety Status Register B
    uint8_t SafetyStatusC;  // Safety Status Register C
    uint8_t PFStatusA;   // Permanent Fail Status Register A
    uint8_t PFStatusB;   // Permanent Fail Status Register B
    uint8_t PFStatusC;   // Permanent Fail Status Register C
    uint8_t FET_Status;  // FET Status register contents See TRM Section 12.2.20  - Shows states of FETs
    
    uint16_t CB_ActiveCells;  // Cell Balancing Active Cells
    uint16_t DEVICE_NUMBER;
    
    uint8_t	UV_Fault = 0;   // under-voltage fault state
    uint8_t	OV_Fault = 0;   // over-voltage fault state
    uint8_t	SCD_Fault = 0;  // short-circuit fault state
    uint8_t	OCD_Fault = 0;  // over-current fault state
    uint8_t LD_ON = 0;							// Load Detect status bit
    uint8_t DCHG = 0;   // discharge FET state
    uint8_t CHG = 0;   // charge FET state
    uint8_t PCHG = 0;  // pre-charge FET state
    uint8_t PDSG = 0;  // pre-discharge FET state
    
    uint32_t AccumulatedCharge_Int;
    uint32_t AccumulatedCharge_Frac;
    uint32_t AccumulatedCharge_Time;
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_I2C1_Init(void);
    static void MX_TIM1_Init(void);
    static void MX_USART1_UART_Init(void);
    static void MX_TIM2_Init(void);
    /* USER CODE BEGIN PFP */
    void delayUS(uint32_t us) {   // Sets the delay in microseconds.
    	//uint8_t tim = 0;
    	__HAL_TIM_SET_COUNTER(&htim1,0);  // set the counter value a 0
    	while (__HAL_TIM_GET_COUNTER(&htim1) < us);
    }
    
    void delay_ticks(uint32_t ticks)
    {
        SysTick->LOAD = ticks;
        SysTick->VAL = 0;
        SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
        // COUNTFLAG is a bit that is set to 1 when counter reaches 0.
        // It's automatically cleared when read.
        while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
        SysTick->CTRL = 0;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    unsigned char Checksum(unsigned char *ptr, unsigned char len)
    	// Calculates the checksum when writing to a RAM register. The checksum is the inverse of the sum of the bytes.
    {
    	unsigned char i;
    	unsigned char checksum = 0;
    
    	for(i=0; i<len; i++)
    		checksum += ptr[i];
    
    	checksum = 0xff & ~checksum;
    
    	return(checksum);
    }
    
    
    
    unsigned char CRC8(unsigned char *ptr, unsigned char len)
    {
    	unsigned char i;
    	unsigned char crc=0;
    	while(len--!=0)
    	{
    		for(i=0x80; i!=0; i/=2)
    		{
    			if((crc & 0x80) != 0)
    			{
    				crc *= 2;
    				crc ^= 0x107;
    			}
    			else
    				crc *= 2;
    
    			if((*ptr & i)!=0)
    				crc ^= 0x107;
    		}
    		ptr++;
    	}
    	return(crc);
    }
    
    void I2C_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
    		#if CRC_Mode
    		{
    		uint8_t crc_count = 0;
    		crc_count = count * 2;
    		uint8_t crc1stByteBuffer [3] = {0x10, reg_addr, reg_data[0]};
    		unsigned int j;
    		unsigned int i;
    		uint8_t temp_crc_buffer [3];
    
    		TX_Buffer[0] = reg_data[0];
    		TX_Buffer[1] = CRC8(crc1stByteBuffer,3);
    
    		j = 2;
    		for(i=1; i<count; i++)
    		{
    			TX_Buffer[j] = reg_data[i];
    			j = j + 1;
    			temp_crc_buffer[0] = reg_data[i];
    			TX_Buffer[j] = CRC8(temp_crc_buffer,1);
    			j = j + 1;
    		}
    		HAL_I2C_Mem_Write(&hi2c1, DEV_ADDR, reg_addr, 1, TX_Buffer, count, 1000);
    		}
    		#endif
    
    		#if CRC_Mode < 1
    		 HAL_StatusTypeDef state = HAL_OK;
    		state=HAL_I2C_Mem_Write(&hi2c1, DEV_ADDR, reg_addr, 1, reg_data, count, 1000);
    		if(state != HAL_OK)
    				{
    
    				}
    		#endif
    }
    
    
    int I2C_ReadReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
    	unsigned int RX_CRC_Fail = 0;  // reset to 0. If in CRC Mode and CRC fails, this will be incremented.
    
    	#if CRC_Mode
    	{
    		uint8_t crc_count = 0;
    		uint8_t ReceiveBuffer [10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    		crc_count = count * 2;
    		unsigned int j;
    		unsigned int i;
    		unsigned char CRCc = 0;
    		uint8_t temp_crc_buffer [3];
    
    		HAL_I2C_Mem_Read(&hi2c1, DEV_ADDR, reg_addr, 1, ReceiveBuffer, crc_count, 1000);
    		uint8_t crc1stByteBuffer [4] = {0x10, reg_addr, 0x11, ReceiveBuffer[0]};
    		CRCc = CRC8(crc1stByteBuffer,4);
    		if (CRCc != ReceiveBuffer[1])
    			RX_CRC_Fail += 1;
    
    		RX_Buffer[0] = ReceiveBuffer[0];
    
    		j = 2;
    		for (i=1; i<count; i++)
    		{
    			RX_Buffer[i] = ReceiveBuffer[j];
    			temp_crc_buffer[0] = ReceiveBuffer[j];
    			j = j + 1;
    			CRCc = CRC8(temp_crc_buffer,1);
    			if (CRCc != ReceiveBuffer[j])
    				RX_CRC_Fail += 1;
    			j = j + 1;
    		}
    		CopyArray(RX_Buffer, reg_data, crc_count);
    	}
    	#endif
    
    	#if CRC_Mode < 1
    	// HAL_StatusTypeDef state = HAL_OK;
    		 HAL_I2C_Mem_Read(&hi2c1, DEV_ADDR, reg_addr, 1, reg_data, count, 1000);
    		//if(state != HAL_OK)
    		//{
    
    		//}
    	#endif
    
    	  return 0;
    }
    
    int decToBinary(int n)
    {
    	// array to store binary number
    	uint8_t binaryNum[32];
    	uint8_t Bin_num [4] = {0 , 0 , 0, 0};
    
    	// counter for binary array
    	int i = 0;
    	while (n > 0) {
    
    		// storing remainder in binary array
    		binaryNum[i] = n % 2;
    		n = n / 2;
    		i++;
    	}
    
    	// printing binary array in reverse order
    	for (int j = i - 1; j >= 0; j--)
    		Bin_num[j] =  binaryNum[j];
    
    
    	return Bin_num;
    }
    void AFE_Reset() {
    	// Reset command. Resets all registers to default values or the values programmed in OTP.
    	TX_2Byte[0] = 0x12; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_Init() {
    	// Configures all parameters in device RAM
    
    	// Enter CONFIGUPDATE mode (Subcommand 0x0090) - It is required to be in CONFIG_UPDATE mode to program the device RAM settings
    	// See TRM Section 7.6 for full description of CONFIG_UPDATE mode
    	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    
    	delayUS(2000);
    
    	// After entering CONFIG_UPDATE mode, RAM registers can be programmed. When programming RAM, checksum and length must also be
    	// programmed for the change to take effect. All of the RAM registers are described in detail in Chapter 13 of the BQ76952 TRM.
    	// An easier way to find the descriptions is in the BQStudio Data Memory screen. When you move the mouse over the register name,
    	// a full description of the register and the bits will pop up on the screen.
    	// A summary of the Data Memory is also in Section 13.9 of the TRM.
    
    	// 'Power Config' - Set DSLP_LDO  - 0x9234 = 0x2D82  (See TRM section 13.3.2)
    	// Setting the DSLP_LDO bit allows the LDOs to remain active when the device goes into Deep Sleep mode
      TX_4Byte[0] = 0x34; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x82; TX_4Byte[3] = 0x2D;
      I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// 'REG0 Config' - set REG0_EN bit to enable pre-regulator
    	TX_3Byte[0] = 0x37; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x01;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// 'REG12 Config' - Enable REG1 with 3.3V output
    	TX_3Byte[0] = 0x36; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x0D;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// 'VCell Mode' - Enable 16 cells - 0x9304 = 0x0000  (See TRM section 13.3.2.19)
    	// 0x0000 sets the default value of 16 cells.
      TX_4Byte[0] = 0x04; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x00; TX_4Byte[3] = 0x00;
      I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// 'Default Alarm Mask' - Enable FullScan and ADScan bits
    	// 0xF882
      TX_4Byte[0] = 0x6D; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x82; TX_4Byte[3] = 0xF8;
      I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// Enable protections in 'Enabled Protections A' 0x9261 = 0xBC (See TRM section 13.3.3.2)
    	// Enables SCD (short-circuit), OCD1 (over-current in discharge), OCC (over-current in charge),
    	// COV (over-voltage), CUV (under-voltage)
    	TX_3Byte[0] = 0x61; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;  //0xFC
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// Enable all protections in 'Enabled Protections B' 0x9262 = 0xF7 (See TRM section 13.3.3.3)
    	// Enables OTF (over-temperature FET), OTINT (internal over-temperature), OTD (over-temperature in discharge),
    	// OTC (over-temperature in charge), UTINT (internal under-temperature), UTD (under-temperature in discharge), UTC (under-temperature in charge)
    	TX_3Byte[0] = 0x62; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;  //0xF7
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    #if 1
    	// Set TS1 to measure Cell Temperature - 0x92FD = 0x07   (See TRM Section 13.3.2.12)
    	TX_3Byte[0] = 0xFD; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x07;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// Set TS3 to measure FET Temperature - 0x92FF = 0x0F   (See TRM Section 13.3.2.14)
    	TX_3Byte[0] = 0xFF; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x0F;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    #endif
    #if 1
    	// Set DFETOFF pin to control BOTH CHG and DSG FET - 0x92FB = 0x42 (set to 0x00 to disable)
    	// See TRM section 13.3.2.10, Table 13-7
    #if 0
    	TX_3Byte[0] = 0xFB; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xC2;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    #endif
    	// Set up Alert Pin - 0x92FC = 0x2A  - See TRM Section 13.3.2.11, Table 13-8
    	// This configures the Alert pin to drive high (REG1 voltage) when enabled.
    	// Other options available include active-low, drive HiZ, drive using REG18 (1.8V), weak internal pull-up and pull-down
    	TX_3Byte[0] = 0xFC; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x2A;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    #endif
    
    #if 1
    	// Set up Cell Balancing Configuration - 0x9335 = 0x03   -  Automated balancing while in Relax or Charge modes
    	// See TRM Section 13.3.11. Chapter 10 of TRM describes Cell Balancing in detail
    	// Also see "Cell Balancing with BQ76952, BQ76942 Battery Monitors" document on ti.com
    	TX_3Byte[0] = 0x35; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x03;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// Set up COV (over-voltage) Threshold - 0x9278 = 0x55 (4301 mV)
    	// COV Threshold is this value multiplied by 50.6mV  See TRM section 13.6.2
    	TX_3Byte[0] = 0x78; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x55;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// Set up SCD Threshold - 0x9286 = 0x05 (100 mV = 100A across 1mOhm sense resistor)
    	// See TRM section 13.6.7    0x05=100mV
    	TX_3Byte[0] = 0x86; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x05;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// Set up SCD Delay - 0x9287 = 0x03 (30 us)    See TRM section 13.6.7
    	// Units of 15us
    	TX_3Byte[0] = 0x87; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x03;
      I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// Set up SCDL Latch Limit to 1 to set SCD recovery only with load removal 0x9295 = 0x01
    	// If this is not set, then SCD will recover based on time (SCD Recovery Time parameter).
    	// See TRM section 13.6.11.1
    	TX_3Byte[0] = 0x95; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x01;
    	I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    #if 1
    	// precharge start V
    	TX_4Byte[0] = 0x0A; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0xB8; TX_4Byte[3] = 0x0B; // 0x48 0xF4
    	I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// precharge stop V
    	TX_4Byte[0] = 0x0C; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x1C; TX_4Byte[3] = 0x03;  //0x1C F3;
    	I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	// predischarge time out
    	TX_3Byte[0] = 0x0E; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x00;
    	I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	//predischarge stop delta
    	TX_3Byte[0] = 0x0F; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x00;
    	I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	//discharge current threshold
    	TX_4Byte[0] = 0x10; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x64; TX_4Byte[3] = 0x00;  //0xE2; 0xFF
    	I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	// HAL_Delay(1);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	//charge current threshold
    	TX_4Byte[0] = 0x12; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x32; TX_4Byte[3] = 0x00; //0xF6 0xFF;
    	I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	// HAL_Delay(1);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    #endif
    // Maufcturing status init
    	TX_4Byte[0] = 0x43; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x10; TX_4Byte[3] = 0x00;
    	I2C_WriteReg(0x3E, TX_4Byte, 4);
    	delayUS(1000);
    	// HAL_Delay(1);
    	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    //Fet options
    	TX_3Byte[0] = 0x08; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x1F;
    	I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    	delayUS(1000);
    
    	//Protection config
    	TX_4Byte[0] = 0x5F; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x00; TX_4Byte[3] = 0x00;
    		I2C_WriteReg(0x3E, TX_4Byte, 4);
    		delayUS(1000);
    		// HAL_Delay(1);
    		TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    		I2C_WriteReg(0x60, TX_2Byte, 2);
    		delayUS(1000);
    
    		//Discharg protection A
    		TX_3Byte[0] = 0x69; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
    		I2C_WriteReg(0x3E, TX_3Byte, 3);
    		delayUS(1000);
    		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    		I2C_WriteReg(0x60, TX_2Byte, 2);
    		delayUS(1000);
    
    		//Discharg protection B
    		TX_3Byte[0] = 0x6A; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
    		I2C_WriteReg(0x3E, TX_3Byte, 3);
    		delayUS(1000);
    		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    		I2C_WriteReg(0x60, TX_2Byte, 2);
    		delayUS(1000);
    
    		//Discharg protection C
    		TX_3Byte[0] = 0x6B; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
    		I2C_WriteReg(0x3E, TX_3Byte, 3);
    		delayUS(1000);
    		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    		I2C_WriteReg(0x60, TX_2Byte, 2);
    		delayUS(1000);
    
    		//Body diode
    		TX_4Byte[0] = 0x73; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0xEC; TX_4Byte[3] = 0xFF;
    				I2C_WriteReg(0x3E, TX_4Byte, 4);
    				delayUS(1000);
    				// HAL_Delay(1);
    				TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    
    		//CC Gain
    				TX_6Byte[0] = 0xA8; TX_6Byte[1] = 0x91; TX_6Byte[2] = 0xF2; TX_6Byte[3] = 0x41; TX_6Byte[4] = 0x6F; TX_6Byte[5] = 0x41;
    				  I2C_WriteReg(0x3E, TX_6Byte, 6);
    				  delayUS(1000);
    				  TX_2Byte[0] = Checksum(TX_6Byte, 6); TX_2Byte[1] = 0x08;  // Checksum and Length
    				  I2C_WriteReg(0x60, TX_2Byte, 2);
    				  delayUS(1000);
    
    			//HDQ config
    				TX_3Byte[0] = 0x00; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0B;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    
    				//DCHG thermistor config
    				TX_3Byte[0] = 0x01; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0B;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    
    				//TS1 temp offset
    				TX_3Byte[0] = 0xCE; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    
    				//TS3 temp offset
    				TX_3Byte[0] = 0xD0; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    
    				//HDQ temp offset
    				TX_3Byte[0] = 0xD1; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    
    				//DCHG temp offset
    				TX_3Byte[0] = 0xD2; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    
    #if 0
    				//Data Status
    				TX_2Byte[0] = 0x76; TX_2Byte[1] = 0x00;
    				I2C_WriteReg(0x3E,TX_2Byte,2);
    				delayUS(1000);
    				I2C_ReadReg(0x40, RX_12Byte, 12);
    				CC3_Current = (RX_12Byte[21]<<8) + (RX_12Byte[20]);
    				CC1_Current = (RX_12Byte[23]<<8) + (RX_12Byte[22]);
    				Raw_CC2_Count = ((RX_12Byte[27]<<24) + (RX_12Byte[26]<<16) + (RX_12Byte[25]<<8) + RX_12Byte[24]);
    				Raw_CC3_Count = ((RX_12Byte[31]<<24) + (RX_12Byte[30]<<16) + (RX_12Byte[29]<<8) + RX_12Byte[28]);
    				delayUS(1000);
    #endif
    #if 0
    				//TS3
    				TX_3Byte[0] = 0xFF; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0B;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    				//TS1
    				TX_3Byte[0] = 0xFD; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0B;
    				I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    				I2C_WriteReg(0x60, TX_2Byte, 2);
    				delayUS(1000);
    #endif
    
    #endif
    #if 0
    //******** Manufacturing Status******//
    		 TX_4Byte[0] = 0x43; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x50; TX_4Byte[3] = 0x00;
    		  I2C_WriteReg(0x3E, TX_4Byte, 4);
    			delayUS(1000);
    		 // HAL_Delay(1);
    			TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    		  I2C_WriteReg(0x61, TX_2Byte, 2);
    		  delayUS(1000);
    //*********************************//
    //******Fet options***************//
    		  TX_3Byte[0] = 0x08; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x1F;
    		  	  I2C_WriteReg(0x3E, TX_3Byte, 3);
    		  		delayUS(1000);
    		  		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    		  	  I2C_WriteReg(0x60, TX_2Byte, 2);
    		  	  delayUS(1000);
    //*********************************//
    //**************All fets On*************//
    		  	TX_2Byte[0] = 0x96; TX_2Byte[1] = 0x00;
    		  		I2C_WriteReg(0x3E,TX_2Byte,2);
    		  		 delayUS(1000);
    //***************************************//
    		  		AFE_ReadFETStatus();
    #endif
    	// Exit CONFIGUPDATE mode  - Subcommand 0x0092
    	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    	delayUS(1000);
    }
    
    void Enable_REG1()
    {
    	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    		// 'REG0 Config' - set REG0_EN bit to enable pre-regulator
    			TX_3Byte[0] = 0x37; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x01;
    		  I2C_WriteReg(0x3E, TX_3Byte, 3);
    			delayUS(1000);
    			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    		  I2C_WriteReg(0x60, TX_2Byte, 2);
    			delayUS(1000);
    
    			// 'REG12 Config' - Enable REG1 with 3.3V output
    			TX_3Byte[0] = 0x36; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x0D;
    		  I2C_WriteReg(0x3E, TX_3Byte, 3);
    			delayUS(1000);
    			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    		  I2C_WriteReg(0x60, TX_2Byte, 2);
    			delayUS(1000);
    		  // Exit CONFIGUPDATE mode  - Subcommand 0x0092
    		  	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
    		  	I2C_WriteReg(0x3E,TX_2Byte,2);
    		  	//delayUS(1000);
    
    }
    
    // ************************** Functions Written by Rohith********************//
    void AFE_FETOptions(){
    	TX_3Byte[0] = 0x08; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x1F;
    	  I2C_WriteReg(0x3E, TX_3Byte, 3);
    		delayUS(1000);
    		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	  I2C_WriteReg(0x60, TX_2Byte, 2);
    	  delayUS(1000);
    }
    
    void AFE_ManufacturingStatus(){
    
    	 TX_4Byte[0] = 0x43; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x50; TX_4Byte[3] = 0x00;
    	  I2C_WriteReg(0x3E, TX_4Byte, 4);
    		delayUS(1000);
    	 // HAL_Delay(1);
    		TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    	  I2C_WriteReg(0x61, TX_2Byte, 2);
    	  delayUS(1000);
    
    }
    void Manufacturing_Status_Read(){
    
    }
    void PDSG_TEST(){
    	TX_2Byte[0] = 0x1C; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    void PCHG_TEST(){
    	TX_2Byte[0] = 0x1E; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    void CHG_TEST(){
    	TX_2Byte[0] = 0x1F; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    void DSG_TEST(){
    	TX_2Byte[0] = 0x20; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    void Charge_Pump(){
    	TX_3Byte[0] = 0x09; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x01;
    		  I2C_WriteReg(0x3E, TX_3Byte, 3);
    			delayUS(1000);
    			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    		  I2C_WriteReg(0x60, TX_2Byte, 2);
    		  delayUS(1000);
    }
    
    void Comm_Type(){
    	TX_3Byte[0] = 0x39; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x12;
    			  I2C_WriteReg(0x3E, TX_3Byte, 3);
    				delayUS(1000);
    				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    			  I2C_WriteReg(0x60, TX_2Byte, 2);
    }
    
    void Swap_Comm_Mode(){
    	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    
    
    	TX_3Byte[0] = 0x39; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x12;
    	I2C_WriteReg(0x3E, TX_3Byte, 3);
    	//delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    
    	TX_2Byte[0] = 0xBC; TX_2Byte[1] = 0x29;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    
    	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    void Dfet_off(){
    
    	TX_3Byte[0] = 0xFB; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
    	I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    
    }
    
    void Cfet_off(){
    
    	TX_3Byte[0] = 0xFA; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
    	I2C_WriteReg(0x3E, TX_3Byte, 3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
    	I2C_WriteReg(0x60, TX_2Byte, 2);
    
    }
    void Status_Read(){
    	uint8_t rd_data;
    	TX_2Byte[0] = 0x57; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    		delayUS(2000);
    		I2C_ReadReg(0x40, RX_2Byte, 2);
    		rd_data = (RX_2Byte[1]*256 + RX_2Byte[0]);
    }
    void Vcell(){
    	 TX_4Byte[0] = 0x04; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x00; TX_4Byte[3] = 0x00;
    	  I2C_WriteReg(0x3E, TX_4Byte, 4);
    		delayUS(1000);
    		TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
    	  I2C_WriteReg(0x60, TX_2Byte, 2);
    }
    //**************** End *************//
    //  ********************************* FET Control Commands  ***************************************
    
    void AFE_FET_ENABLE() {
    	// Toggles the FET_EN bit in the Manufacturing Status register. So this command can be used to enable or disable the FETs.
    	TX_2Byte[0] = 0x22; TX_2Byte[1] = 0x00;   //0x22
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_FET_Control(uint8_t FET_states) {  // Bit3 = PCHG_OFF, Bit 2 = CHG_OFF, Bit1 = PDSG_OFF, Bit 0 = DSG_OFF
    	TX_3Byte[0] = 0x97; TX_3Byte[1] = 0x00; TX_3Byte[2] = FET_states;
    	I2C_WriteReg(0x3E,TX_3Byte,3);
    	delayUS(1000);
    	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
      I2C_WriteReg(0x60, TX_2Byte, 2);
    }
    
    void DSG_PDSG_OFF() {
    	// Disable discharge (and pre-discharge) FETs
    	// Subcommand 0x0093  See TRM Table 5-8  (DSG_PDSG_OFF())
    	TX_2Byte[0] = 0x93; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void CHG_PCHG_OFF() {
    	// Disable charge (and pre-charge) FETs
    	// Subcommand 0x0094  See TRM Table 5-8  (CHG_PCHG_OFF())
    	TX_2Byte[0] = 0x94; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_ALL_FETS_OFF() {
    	// Disable all FETs with command 0x0095  See TRM Table 5-8
    	TX_2Byte[0] = 0x95; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_ALL_FETS_ON() {
    	// All all FETs to be enabled with command 0x0096  See TRM Table 5-8
    	TX_2Byte[0] = 0x96; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_BOTHOFF () {
    	// Disables all FETs using the DFETOFF (BOTHOFF) pin
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);  // DFETOFF pin (BOTHOFF) set low
    }
    
    void AFE_RESET_BOTHOFF () {
    	// Resets DFETOFF (BOTHOFF) pin
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);  // DFETOFF pin (BOTHOFF) set low
    }
    
    void AFE_ReadFETStatus() {
    	// Read FET Status to see which FETs are enabled
    	I2C_ReadReg(0x7F, RX_2Byte, 2);
      FET_Status = (RX_2Byte[1]*256 + RX_2Byte[0]);
    	DCHG = 0x4 & RX_2Byte[0];   // discharge FET state
    	CHG = 0x1 & RX_2Byte[0];   // charge FET state
    	PCHG = 0x2 & RX_2Byte[0];  // pre-charge FET state
    	PDSG = 0x8 & RX_2Byte[0];  // pre-discharge FET state
    }
    
    
    // ********************************* End of FET Control Commands *********************************
    
    
    // ********************************* AFE Cell Balancing Commands   *****************************************
    
    void CB_ACTIVE_CELLS() {
    	// Check status of which cells are balancing
    	TX_2Byte[0] = 0x83; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    	I2C_ReadReg(0x40, RX_2Byte, 2);
      CB_ActiveCells = (RX_2Byte[1]*256 + RX_2Byte[0]);
    }
    
    void CFET_OFF_LO(){
    	TX_2Byte[0] = 0x28; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E, TX_2Byte, 2);
    }
    void DFET_OFF_LO(){
    	TX_2Byte[0] = 0x28; TX_2Byte[1] = 0x01;
    		I2C_WriteReg(0x3E, TX_2Byte, 2);
    }
    // ********************************* End of AFE Cell Balancing Commands   *****************************************
    
    
    // ********************************* AFE Power Commands   *****************************************
    void AFE_DeepSleep() {
    	// Puts the device into DEEPSLEEP mode. See TRM section 7.4
    	TX_2Byte[0] = 0x0F; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_ExitDeepSleep() {
    	// Exits DEEPSLEEP mode. See TRM section 7.4
    	TX_2Byte[0] = 0x0E; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_ShutdownCommand() {
    	// Puts the device into SHUTDOWN mode. See TRM section 7.5
    	TX_2Byte[0] = 0x10; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_ShutdownPin() {
    	// Puts the device into SHUTDOWN mode using the RST_SHUT pin
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);  // Sets RST_SHUT pin
    }
    
    void AFE_ReleaseShutdownPin() {
    	// Releases the RST_SHUT pin
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);  // Resets RST_SHUT pin
    }
    
    void AFE_SLEEP_ENABLE() { // SLEEP_ENABLE 0x0099
    	// Allows the device to enter Sleep mode if current is below Sleep Current. See TRM section 7.3
    	TX_2Byte[0] = 0x99; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void AFE_SLEEP_DISABLE() { // SLEEP_DISABLE 0x009A
    	// Takes the device out of sleep mode. See TRM section 7.3
    	TX_2Byte[0] = 0x9A; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    // ********************************* End of AFE Power Commands   *****************************************
    
    
    // ********************************* AFE Status and Fault Commands   *****************************************
    
    uint16_t AFE_ReadAlarmStatus() {
    	// Read this register to find out why the Alert pin was asserted. See section 6.6 of the TRM for full description.
    	I2C_ReadReg(0x62, RX_2Byte, 2);
    	return (RX_2Byte[1]*256 + RX_2Byte[0]);
    }
    
    void AFE_ReadSafetyStatus() {
    	// Read Safety Status A/B/C and find which bits are set
    	// This shows which primary protections have been triggered
    	I2C_ReadReg(0x03, RX_2Byte, 2);
    	SafetyStatusA = (RX_2Byte[1]*256 + RX_2Byte[0]);
    	UV_Fault = 0x4 & RX_2Byte[0];
    	OV_Fault = 0x8 & RX_2Byte[0];
    	SCD_Fault = 0x8 & RX_2Byte[1];
    	OCD_Fault = 0x2 & RX_2Byte[1];
    	I2C_ReadReg(0x05, RX_2Byte, 2);
    	SafetyStatusB = (RX_2Byte[1]*256 + RX_2Byte[0]);
    	I2C_ReadReg(0x07, RX_2Byte, 2);
    	SafetyStatusC = (RX_2Byte[1]*256 + RX_2Byte[0]);
    }
    
    void AFE_ReadPFStatus() {
    	// Read Permanent Fail Status A/B/C and find which bits are set
    	// This shows which permanent failures have been triggered
    	I2C_ReadReg(0x0B, RX_2Byte, 2);
    	PFStatusA = (RX_2Byte[1]*256 + RX_2Byte[0]);
    	I2C_ReadReg(0x0D, RX_2Byte, 2);
    	PFStatusB = (RX_2Byte[1]*256 + RX_2Byte[0]);
    	I2C_ReadReg(0x0F, RX_2Byte, 2);
    	PFStatusC = (RX_2Byte[1]*256 + RX_2Byte[0]);
    }
    
    
    void AFE_ControlStatus() {
    	// Control status register - Bit0 - LD_ON (load detected)
    	// See TRM Table 6-1
    	I2C_ReadReg(0x00, RX_2Byte, 2);
      LD_ON = 0x1 & RX_2Byte[0];
    }
    
    void AFE_BatteryStatus() {
    	// Battery status register - See TRM Table 6-2
    	I2C_ReadReg(0x12, RX_2Byte, 2);
    }
    
    void AFE_ClearFaults() {
    	TX_2Byte[0] = 0x00; TX_2Byte[1] = 0xF8;
    	I2C_WriteReg(0x62,TX_2Byte,2);
    }
    
    void AFE_ClearScanBits() {
    	TX_2Byte[0] = 0x82; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x62,TX_2Byte,2);
    }
    
    void AFE_PFReset() {
    	TX_2Byte[0] = 0x29; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    uint16_t AFE_DeviceID() {
    	// Read Device ID using Subcommand 0x0001
    	TX_2Byte[0] = 0x01; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    	delayUS(500);
    	I2C_ReadReg(0x40, RX_2Byte, 2);
    	return (RX_2Byte[1]*256 + RX_2Byte[0]);
    }
    void AFE_STATUS(){
    
    	TX_2Byte[0] = 0x75; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    	delayUS(1000);
    	I2C_ReadReg(0x40, RX_32Byte, 32);
    	Max_cell = (RX_32Byte[5]<<8) + (RX_32Byte[4]);
    	Min_cell = (RX_32Byte[7]<<8) + (RX_32Byte[6]);
    	Battery_voltage_sum = (RX_32Byte[9]<<8) + (RX_32Byte[8]);
    	Avg_cell_temp = (RX_32Byte[11]<<8) + (RX_32Byte[10]);
    	Fet_temp = (RX_32Byte[13]<<8) + (RX_32Byte[12]);
    	Max_cell_temp = (RX_32Byte[15]<<8) + (RX_32Byte[14]);
    	Min_cell_temp = (RX_32Byte[17]<<8) + (RX_32Byte[16]);
    	Avg_min_max_temp = (RX_32Byte[19]<<8) + (RX_32Byte[18]);
    	CC3_Current = (RX_32Byte[21]<<8) + (RX_32Byte[20]);
    	CC1_Current = (RX_32Byte[23]<<8) + (RX_32Byte[22]);
    	Raw_CC2_Count = ((RX_32Byte[27]<<24) + (RX_32Byte[26]<<16) + (RX_32Byte[25]<<8) + RX_32Byte[24]);
    	Raw_CC3_Count = ((RX_32Byte[31]<<24) + (RX_32Byte[30]<<16) + (RX_32Byte[29]<<8) + RX_32Byte[28]);
    
    	delayUS(1000);
    }
    // ********************************* End of AFE Status and Fault Commands   *****************************************
    
    
    // ********************************* AFE Measurement Commands   *****************************************
    
    uint16_t AFE_ReadCellVoltage(uint8_t channel) {
    	I2C_ReadReg(channel*2+0x14, RX_2Byte, 2);
    	return (RX_2Byte[1]*256 + RX_2Byte[0]);     // cell voltage is reported in mV
    }
    
    uint16_t AFE_ReadStackVoltage() {
    	I2C_ReadReg(0x34, RX_2Byte, 2);
    	return 10 * (RX_2Byte[1]*256 + RX_2Byte[0]);  // voltage is reported in 0.01V units
    }
    
    uint16_t AFE_ReadPackVoltage() {
    	I2C_ReadReg(0x36, RX_2Byte, 2);
    	return 10 * (RX_2Byte[1]*256 + RX_2Byte[0]);  // voltage is reported in 0.01V units
    }
    
    uint16_t AFE_ReadLDVoltage() {
    	I2C_ReadReg(0x38, RX_2Byte, 2);
    	return 10 * (RX_2Byte[1]*256 + RX_2Byte[0]);  // voltage is reported in 0.01V units
    }
    
    uint16_t AFE_ReadCurrent() {
    	//uint8_t cure = 0;
    	I2C_ReadReg(0x3A, RX_2Byte, 2);
    	return (RX_2Byte[1]*256 + RX_2Byte[0]);  // current is reported in mA
    }
    
    
    
    float AFE_ReadTemperature(uint8_t channel) {
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
    	switch(channel)
    	{
    		case 0:
    			I2C_ReadReg(0x70, RX_2Byte, 2);  // TS1 pin
    			break;
    		case 1:
    			I2C_ReadReg(0x74, RX_2Byte, 2);  // TS3 pin, FET temperature
    			break;
    		case 2:
    			I2C_ReadReg(0x76, RX_2Byte, 2);  // HDQ, FET temperature
    			break;
    		case 3:
    			I2C_ReadReg(0x78, RX_2Byte, 2);  // DCHG pin, FET temperature
    			break;
    		default: break;
    	}
    	return (0.1 * (float)(RX_2Byte[1]*256 + RX_2Byte[0])) - 273.15;  // convert from 0.1K to Celcius
    }
    
    
    void AFE_ReadPassQ() {
    	// Read Accumulated Charge and Time from DASTATUS6 (See TRM Table 4-6)
    	TX_2Byte[0] = 0x76; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    	delayUS(1000);
    	I2C_ReadReg(0x40, RX_12Byte, 12);
    	AccumulatedCharge_Int = ((RX_12Byte[3]<<24) + (RX_12Byte[2]<<16) + (RX_12Byte[1]<<8) + RX_12Byte[0]);
    	AccumulatedCharge_Frac = ((RX_12Byte[7]<<24) + (RX_12Byte[6]<<16) + (RX_12Byte[5]<<8) + RX_12Byte[4]);
    	AccumulatedCharge_Time = ((RX_12Byte[11]<<24) + (RX_12Byte[10]<<16) + (RX_12Byte[9]<<8) + RX_12Byte[8]);
    }
    
    void AFE_ClearPassQ() {
    	// Clear Accumulated Charge and Time, command 0x0082
    	TX_2Byte[0] = 0x82; TX_2Byte[1] = 0x00;
    	I2C_WriteReg(0x3E,TX_2Byte,2);
    }
    
    void config_mode(){
    	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    
    }
    void Exit_config_mode(){
    	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
    		I2C_WriteReg(0x3E,TX_2Byte,2);
    
    }
    // ********************************* End of AFE Measurement Commands   *****************************************
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    	volatile int i = 0;
    	char uart_buf[50];
    	int uart_buf_len;
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_I2C1_Init();
      MX_TIM1_Init();
      MX_USART1_UART_Init();
      MX_TIM2_Init();
      /* USER CODE BEGIN 2 */
      //DFET PIN fetofff(low)
      HAL_TIM_Base_Start(&htim1);
    
    	//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET); // DEFET PIN
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
    
    	delayUS(10000);
    
    	AFE_Reset();
    	delayUS(60000);
    	result_bin = decToBinary(6);
    	AFE_Init();
    	delayUS(10000);
    	//AFE_FET_ENABLE();
    	//delayUS(10000);
    	AFE_ALL_FETS_ON();
    	AFE_ReadFETStatus();
    	delayUS(10000);
    	AFE_SLEEP_DISABLE();
    
    	delayUS(60000); delayUS(60000); delayUS(60000); delayUS(60000);  //wait to start measurements after FETs close
    	CellVoltage[1] = AFE_ReadCellVoltage(1);
    	CellVoltage[5] = AFE_ReadCellVoltage(5);
    	CellVoltage[10] = AFE_ReadCellVoltage(10);
    	Stack_Voltage = AFE_ReadStackVoltage();
    	PACK_Voltage = AFE_ReadPackVoltage();
    	LD_Voltage = AFE_ReadLDVoltage();
    	//PACK_Current = AFE_ReadCurrent();
    	Temperature[0] = AFE_ReadTemperature(0);
    	FET_Temperature = AFE_ReadTemperature(1);
    	HDQ_Temp = AFE_ReadTemperature(2);
    	DCHG_Temp = AFE_ReadTemperature(3);
    	//DDSG_Temp = AFE_ReadTemperature(4);
    
    #if 0
      AFE_SLEEP_DISABLE();
      AFE_ManufacturingStatus();
      AFE_ReadFETStatus();
      Charge_Pump();
      AFE_FETOptions();
     // AFE_FET_ENABLE();
      AFE_FET_Control(0x00);
      AFE_ReadFETStatus();
      AFE_ALL_FETS_ON();
      AFE_ReadFETStatus();
    #endif
    
    
    
      HAL_StatusTypeDef stat = HAL_OK;
      	stat = HAL_I2C_IsDeviceReady(&hi2c1,0x10,2,10);
      	if(stat == HAL_OK)
      	{
    
    
      	}
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    	  AFE_STATUS();
    	  PACK_Current = AFE_ReadCurrent();
    	 // Current = PACK_Current * 14.9538;
    	  AFE_ReadFETStatus();
    	//  HAL_GPIO_WritePin(RS485_1_RO_DO_UC_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 1);  //Enable uart1
    	 	//	HAL_GPIO_WritePin(UC_DI_DO_RS485_1_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 1); // Enable UART1
    	 	//	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, 1); // Enable UART1
    	  HAL_GPIO_WritePin(DEBUG_RX_DO_GPIO_Port, DEBUG_RDE_DO_Pin, 1);
    	 		for(int i = 0 ;i <=15; i++)
    	 	  {
    	 			CellVoltage[i] = AFE_ReadCellVoltage(i);
    	 			printf("cell voltages [%d] =  %d",i,CellVoltage);
    
    	 	  }
    	 	 Temperature[0] = AFE_ReadTemperature(0) * 10;
    	 	 printf("Temperature ambient : %d",Temperature[0]);
    	 	 	FET_Temperature = AFE_ReadTemperature(1) * 10;
    	 	 printf("Temperature Mosfet : %d",FET_Temperature);
    	 	 HDQ_Temp = AFE_ReadTemperature(2) * 10;
    	 	 printf("HDQ Temperature : %d",HDQ_Temp );
    	 	 DCHG_Temp = AFE_ReadTemperature(3) * 10;
    	 	printf("DCHG Temperature : %d",DCHG_Temp );
    	 	// DDSG_Temp = AFE_ReadTemperature(4);
    	 	  //pa10 port,pa8 pin,1
    	 	 HAL_GPIO_WritePin(DEBUG_RX_DO_GPIO_Port, DEBUG_RDE_DO_Pin, 1);
    		//  HAL_GPIO_WritePin(RS485_1_RO_DO_UC_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 1);  //Enable uart1
    	 	//  HAL_GPIO_WritePin(RDE_DO_GPIO_Port, RDE_DO_Pin, 0);  //Disable uart2
    	 	//	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, 1); // Enable UART1
    	 	 // 	HAL_GPIO_WritePin(RS485_1_RO_DO_UC_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 0); //Disable UART1
    #if 1
    	 	AFE_ReadSafetyStatus();
    	 	  	if (AlarmBits & 0x82) {
    	 	  				AFE_ClearScanBits();
    	 	  			}
    
    	 	  			if (AlarmBits & 0xC000) {
    	 	  				AFE_ReadSafetyStatus();
    	 	  				AFE_ReadPFStatus();
    	 	  				AFE_ClearFaults();
    	 	  				AFE_PFReset();
    	 	  			}
    
    #endif
      }
      /* USER CODE END 3 */
    }
    
    /**
      * @brief System Clock Configuration
      * @retval None
      */
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
      RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
      RCC_OscInitStruct.MSIState = RCC_MSI_ON;
      RCC_OscInitStruct.MSICalibrationValue = 0;
      RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
      RCC_OscInitStruct.PLL.PLLM = 1;
      RCC_OscInitStruct.PLL.PLLN = 36;
      RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
      RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
      RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
      {
        Error_Handler();
      }
      PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1;
      PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
      PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
      if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure the main internal regulator output voltage
      */
      if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    /**
      * @brief I2C1 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_I2C1_Init(void)
    {
    
      /* USER CODE BEGIN I2C1_Init 0 */
    
      /* USER CODE END I2C1_Init 0 */
    
      /* USER CODE BEGIN I2C1_Init 1 */
    
      /* USER CODE END I2C1_Init 1 */
      hi2c1.Instance = I2C1;
      hi2c1.Init.Timing = 0x10808DD3;
      hi2c1.Init.OwnAddress1 = 0;
      hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
      hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
      hi2c1.Init.OwnAddress2 = 0;
      hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
      hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
      hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
      if (HAL_I2C_Init(&hi2c1) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Analogue filter
      */
      if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Digital filter
      */
      if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN I2C1_Init 2 */
    
      /* USER CODE END I2C1_Init 2 */
    
    }
    
    /**
      * @brief TIM1 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_TIM1_Init(void)
    {
    
      /* USER CODE BEGIN TIM1_Init 0 */
    
      /* USER CODE END TIM1_Init 0 */
    
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
    
      /* USER CODE BEGIN TIM1_Init 1 */
    
      /* USER CODE END TIM1_Init 1 */
      htim1.Instance = TIM1;
      htim1.Init.Prescaler = 63;
      htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim1.Init.Period = 65535;
      htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim1.Init.RepetitionCounter = 0;
      htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN TIM1_Init 2 */
    
      /* USER CODE END TIM1_Init 2 */
    
    }
    
    /**
      * @brief TIM2 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_TIM2_Init(void)
    {
    
      /* USER CODE BEGIN TIM2_Init 0 */
    
      /* USER CODE END TIM2_Init 0 */
    
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
      TIM_OC_InitTypeDef sConfigOC = {0};
    
      /* USER CODE BEGIN TIM2_Init 1 */
    
      /* USER CODE END TIM2_Init 1 */
      htim2.Instance = TIM2;
      htim2.Init.Prescaler = 63;
      htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim2.Init.Period = 65535;
      htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sConfigOC.OCMode = TIM_OCMODE_TIMING;
      sConfigOC.Pulse = 0;
      sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
      sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
      if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN TIM2_Init 2 */
    
      /* USER CODE END TIM2_Init 2 */
    
    }
    
    /**
      * @brief USART1 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_USART1_UART_Init(void)
    {
    
      /* USER CODE BEGIN USART1_Init 0 */
    
      /* USER CODE END USART1_Init 0 */
    
      /* USER CODE BEGIN USART1_Init 1 */
    
      /* USER CODE END USART1_Init 1 */
      huart1.Instance = USART1;
      huart1.Init.BaudRate = 115200;
      huart1.Init.WordLength = UART_WORDLENGTH_8B;
      huart1.Init.StopBits = UART_STOPBITS_1;
      huart1.Init.Parity = UART_PARITY_NONE;
      huart1.Init.Mode = UART_MODE_TX_RX;
      huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      huart1.Init.OverSampling = UART_OVERSAMPLING_16;
      huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
      huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
      if (HAL_UART_Init(&huart1) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN USART1_Init 2 */
    
      /* USER CODE END USART1_Init 2 */
    
    }
    
    /**
      * @brief GPIO Initialization Function
      * @param None
      * @retval None
      */
    static void MX_GPIO_Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(RST_SHUT_B_UC_GPIO_Port, RST_SHUT_B_UC_Pin, GPIO_PIN_RESET);
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(DFETOFF_B_UC_GPIO_Port, DFETOFF_B_UC_Pin, GPIO_PIN_RESET);
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOA, DEBUG_RDE_DO_Pin|UC_TEMP_EN_DO_M_Pin, GPIO_PIN_SET);
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(RDE_DO_GPIO_Port, RDE_DO_Pin, GPIO_PIN_RESET);
    
      /*Configure GPIO pins : RST_SHUT_B_UC_Pin DEBUG_RDE_DO_Pin UC_TEMP_EN_DO_M_Pin */
      GPIO_InitStruct.Pin = RST_SHUT_B_UC_Pin|DEBUG_RDE_DO_Pin|UC_TEMP_EN_DO_M_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /*Configure GPIO pin : DFETOFF_B_UC_Pin */
      GPIO_InitStruct.Pin = DFETOFF_B_UC_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(DFETOFF_B_UC_GPIO_Port, &GPIO_InitStruct);
    
      /*Configure GPIO pin : RDE_DO_Pin */
      GPIO_InitStruct.Pin = RDE_DO_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(RDE_DO_GPIO_Port, &GPIO_InitStruct);
    
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */
    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
      __disable_irq();
      while (1)
      {
      }
      /* USER CODE END Error_Handler_Debug */
    }
    
    #ifdef  USE_FULL_ASSERT
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t *file, uint32_t line)
    {
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    

    请提供帮助、

    谢谢、此致、

    罗希思西

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

    您好、

    关于电流测量、

    我可以在不发生波动的情况下读取电流从数据状态(0x0075)读取 CC3电流读数、 我是否可以将该值视为我的原始电流、以便进一步处理、如果我想打印十进制的读数而不是有符号位和二进制补码、则有任何代码用于转换二进制补码和有符号位以获取原始值并打印它。

    如果是,请共享要转换的代码。

    谢谢、此致、

    罗希思西

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

    您好、Rohith、

    根据电压测试值、我开始怀疑可能存在硬件问题、而不是软件问题。 当 CHG 和 DSG 都打开时、PACK 引脚应约为59V。 由于这不是您得到的结果、因此它可能表示电路板损坏。 您是否曾尝试更换过 BQ76952或 DSG FET 等任何器件?  

    我能够浏览您的代码、我没有发现任何与 FET 相关的问题。

    为了打开预放电 FET、您正在正确执行此操作、但您需要为预放电超时和/或预放电停止增量输入大于零的值。 这会告诉 PDSG FET 在关断之前保持导通一段时间、以允许 DSG FET 导通。 PDSG FET 和 DSG FET 不应同时导通、这是通用设计布局。  

    CC3值是一个范围内 CC2的平均值。 默认为80个样本。  

    对于二进制补码函数、您可能会在线找到示例代码或快速编写一个示例代码。 转换是采用十六进制数0xFFBB 并按位不= 0x0044、加1、= 0x0045。 十进制的这个数字是69。 因此、转换后的十进制值为-69。  

    希望您能够取得进步。

    最棒的

    Andrew