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:在实现保护的同时出现充电 MOSFET 问题。

Guru**** 2589245 points
Other Parts Discussed in Thread: BQ76952EVM

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

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1018636/bq76952-issues-in-charge-mosfet-while-enabling-protection

器件型号:BQ76952

您好!

我正在启用保护、Chg 保护、DSG 保护和配置与 OCC 相关的阈值,同时超出阈值,除非从电源断开连接,否则充电 MOSFET 将持续关闭和打开, 当我们断开与电源的连接时、充电和放电 MOSFET 会打开、我们不会观察到充电 MOSFET 会持续关闭、而充电 FET 会继续切换。

  • 在 COV 情况下、即使超出保护范围、我们也会观察到电荷 MOSFET 将会导通、因此我们怀疑电荷 MOSFET、并通过将该位设置为关断充电 FET 来调用 CHG_PCHG_OFF ()和 FET_CONTROL ()、但我们不观察关断情况 当我们当时尝试调用 all_FETs_off 函数时,充电 FET 被关闭,我们假设充电 FET 正常运行。
  • 分别打开预充电、充电和其他 MOSFET 需要采取哪些必要措施。
  • 我已附加 C 代码、并希望确保以正确的方式写入阈值和寄存器。

/* 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_1Byte_P[14] = {0x78, 0x7B, 0x75, 0x7c, 0x82, 0x84, 0x8A, 0x80, 0x86, 0x87, 0xA0, 0xA2, 0xA3, 0xA5};
uint8_t TX_Byte_data[14] = {0x51, 0x4F, 0x44, 0x55, 0x12, 0x15, 0x38, 0x07, 0x46, 0x21, 0x5A, 0x4B, 0x2D, 0x28};
                              //COV  0x51            //COVR            //CUV 0x44 0x48  //CUV release      //OCD1            //OCD2             //OCD3           //OCC              //SCD             //SCD Delay   //OT Fet           //OT Fet rec       //OT Init      //OT Init release
uint8_t TX_Byte_arr[15][3] ={{0x78,0x92,0x51}, {0x7B,0x92,0x02}, {0x75,0x92,0x3D}, {0x7C,0x92,0x02}, {0x82,0x92,0x12}, {0x84,0x92,0x15}, {0x8A,0x92,0x38}, {0x80,0x92,0x02}, {0x86,0x92,0x46}, {0x87,0x92,0x21}, {0xA0,0x92,0x5A}, {0xA2,0x92,0x4B}, {0xA3,0x92,0x2D},{0xA1,0x92,0x02}, {0xA5,0x92,0x28}} ;
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;
char hex_num[10];
char Val[100];
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
uint8_t Alert_B;
uint8_t OTF = 0;
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 OCC_Fault = 0;
uint8_t OTF_Fault = 0;
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
uint8_t DDSG = 0;
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 */
#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
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 Dec_to_Bin(int n){
	int binaryNum[32];
	 int Convert_Num[32];
	    // 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--)
	    {

	    	Convert_Num[j] = binaryNum[j];
	    }
	    	int k;
	    	    for (k = 16-1 ; k >= 0 ; k--)
	    	        if (Convert_Num[k] == '1')
	    	            break;

	    	    // If there exists no '1' concatenate 1 at the
	    	    // starting of string
	    	    if (k == -1)
	    	        return '1' + Convert_Num;

	    	    // Continue traversal after the position of
	    	    // first '1'
	    	    for (int j = k-1 ; j >= 0; j--)
	    	    {
	    	        //Just flip the values
	    	        if (Convert_Num[j] == '1')
	    	        	Convert_Num[j] = '0';
	    	        else
	    	        	Convert_Num[j] = '1';
	    	    }

	    	return Convert_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] = 0xFC;  //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] = 0xF7;  //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);

	//Charge fet protection A
			TX_3Byte[0] = 0x65; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x98;  //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);

		//Charge fet protection B
		TX_3Byte[0] = 0x66; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xD5;  //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 0
	// 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);
#endif
#if 0
	//CUV
	TX_3Byte[0] = 0x75; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x3D;
			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);
	//CUV recovery hystersis
			TX_3Byte[0] = 0x7B; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x02;
						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);

						//OCC
						TX_3Byte[0] = 0x80; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x03; //; 0x4B;
						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);

						//OCC delay
						TX_3Byte[0] = 0x81; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x7F;
						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);

						//Recovery Common
						TX_3Byte[0] = 0xAF; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x09; //; 0x4B;
						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
						//OCD1
						TX_3Byte[0] = 0x82; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x02; //; 0x4B;
						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);

						//OCD Recovery
						TX_4Byte[0] = 0x8D; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0xE8; TX_4Byte[3] = 0x03;
						  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);
#endif
							//SCD
							TX_3Byte[0] = 0x86; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00; //; 0x4B;
							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
	// 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] = 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(0x60, TX_2Byte, 2);
	delayUS(1000);

//Fet options
	TX_3Byte[0] = 0x08; TX_3Byte[1] = 0x93; 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);

	//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] = 0xE4;
		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);
//COVL
		TX_3Byte[0] = 0x7E; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x02;
			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] = 0xE6;
		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] = 0x0F; //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] = 0x0F; //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);
#if 1
				//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);

#endif
#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


#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);
}
#if 0
void AFE_Protection_Thresholds()
{
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	//Cell OV
	TX_3Byte[0] = 0x78; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x51;
	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);

	//Cell ov Release
	TX_3Byte[0] = 0x7B; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x4F;
	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);

	//Cell UV
	TX_3Byte[0] = 0x75; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x44;
	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);

	//Cell UV Release
	TX_3Byte[0] = 0x7C; 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);

	//OCD1
	TX_3Byte[0] = 0x82; 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);
	delayUS(1000);

	//OCD2
	TX_3Byte[0] = 0x84; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x15;
	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);

	//OCD3
	TX_4Byte[0] = 0x8A; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x38; 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);

	//OCC
	TX_3Byte[0] = 0x80; 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);

	//SCD
	TX_3Byte[0] = 0x86; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x46;
	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);

	//SCD Delay
	TX_3Byte[0] = 0x87; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x21;
	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);

	//Fet temp
	TX_3Byte[0] = 0xA0; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x5A;
	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);

	//Fet temp release
	TX_3Byte[0] = 0xA2; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x4B;
	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);

	//Internal temp
	TX_3Byte[0] = 0xA3; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x2D;
	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);

	//Internal temp release
	TX_3Byte[0] = 0xA5; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x28;
	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

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

	for(int i=0; i<15; i++)
	{
	TX_3Byte[0] = TX_1Byte_P[i]; TX_3Byte[1] = 0x92 ,TX_3Byte[2] = TX_Byte_data[i];
	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);
	}

	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
			I2C_WriteReg(0x3E,TX_2Byte,2);
}
void Temp_protection(){
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
				delayUS(1000);
	//Fet temp
		TX_3Byte[0] = 0x75; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x48;
		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
		//Fet temp release
		TX_3Byte[0] = 0xA2; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x4B;
		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
		TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
						I2C_WriteReg(0x3E,TX_2Byte,2);


}
void alert_protection_B(){
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
				delayUS(1000);

	I2C_ReadReg(0x04, RX_2Byte, 2);
	Alert_B = (RX_2Byte[1]*256 + RX_2Byte[0]);
	OTF = 0x8 & RX_2Byte[0];
	delayUS(1000);
	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
}
void protect_AFE(){

	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
			I2C_WriteReg(0x3E,TX_2Byte,2);
			delayUS(1000);
	for(int i=0; i<16; i++)
	{
		for(int j =0 ; j<4 ; j++)
		{
			TX_3Byte[j] = TX_Byte_arr[i][j];
		}
		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);

	}
	delayUS(1000);
	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
}


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
	DDSG = 0x4 & RX_2Byte[1];
}


// ********************************* 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.
	uint8_t Status = 0;
	I2C_ReadReg(0x62, RX_2Byte, 2);
	Status = (RX_2Byte[1]*256 + RX_2Byte[0]);
	return Status;
}

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];
	OCC_Fault = 0x1 & RX_2Byte[1];
	I2C_ReadReg(0x05, RX_2Byte, 2);
	SafetyStatusB = (RX_2Byte[1]*256 + RX_2Byte[0]);
	OTF_Fault =  0x8 & RX_2Byte[1];
	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);  //0x14
	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 */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */

 // HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
/* 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);
 // Protections_AFE();
	//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);
	//Temp_protection();
	protect_AFE();
	delayUS(10000);
	 // Dec_to_Hex(65521);
	Dec_to_Bin(65521);
	 AFE_Init();

	delayUS(10000);
#if 0 //Test mode
	AFE_FET_Control(0x00);
		AFE_ReadFETStatus();
			delayUS(10000);
		DSG_TEST();
		AFE_ReadFETStatus();
		delayUS(10000);

		CHG_TEST();
		AFE_ReadFETStatus();
			delayUS(10000);
		 PDSG_TEST();
		 AFE_ReadFETStatus();
		 	delayUS(10000);
		 PCHG_TEST();
		 AFE_ReadFETStatus();
		 	delayUS(10000);
#endif
#if 1
	//AFE_FET_ENABLE();
	//delayUS(10000);
	AFE_ALL_FETS_ON();
	delayUS(10000);
	AFE_ReadFETStatus();
	delayUS(10000);
	//AFE_ALL_FETS_OFF();
	//delayUS(10000);
	AFE_ReadFETStatus();
	AFE_SLEEP_DISABLE();
#endif
	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 */
	//  alert_protection_B();
	  AFE_ReadAlarmStatus() ;
	//  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);
	  printf("CV \n");
	 		for(int i = 0 ;i <=15; i++)
	 	  {
	 			CellVoltage[i] = AFE_ReadCellVoltage(i);
	 			printf("[%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****/

Andrew

谢谢、此致、

罗希思西  

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

    您好、Rohith、  

    我注意到昨天你们中的另一篇文章与此类似、因此我将在这里作出回应。 我仍在浏览您的代码、但目前最突出的一点是在 PROTECT_AFE ()函数中、'for'循环具有"j<4"、但这会将4字节数据放入 TX_3Byte 数组中、因此您需要将其更改为"j<3"。 这是一个开始、但如果我注意到其他问题、我会回来。

    对于配置 COV 和其他参数时的值、这些值是正确的且在规格范围内、因此不会出现问题。  

    我建议专注于一次测试一个保护、例如、仅 启用过压保护并确保 FET 正常运行、然后继续进行下一个保护。 这将有助于隔离问题区域。  

    此外、您是否使用 BQ76952EVM 或您自己的电路板设计? 如果您使用自己的电路板设计、您是否会考虑与我共享该设计、以查看电路板中是否存在问题?  

    最棒的

    Andrew

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

    感谢 的回复、

    我已将循环更改为 j<3,并且还在 AFE_Init()函数中单独配置阈值,我还会单独配置阈值并测试违反值,但我仍然有与充电 MSOFET 相关的单独配置,请建议其他一些方法

    与热湿器读数有关的问题

    • 当我尝试读取热敏电阻读数时、我将获得负值、例如(-0.207632)、如果我尝试添加 thw 偏移、则该值将在连接热敏电阻的情况下添加到此数字、同时我将使用 HDQ、TS3、TS1、DCHG 引脚作为代码中提到的热敏电阻
    •  在发生温度泄漏时、我无法找到任何变化的地方、我的温度配置是否正确?

    关于电荷 MOSFET、

    • 如何单独启用 MOSFET 和单独禁用 MOSFET。

    由于某些隐私限制、最好共享您的邮件 ID 以共享我的板设计。

    请参阅之前随附的代码。

    谢谢、此致、

    罗希思西

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

    您好、Rohith、

    有子命令 PCHGTEST、CHGTEST、DSDTEST、PDSGTEST (0x001E、0x001F、 0x0020、0x001C 分别是子命令)、您可以在其中测试和观察 FET 是否导通。 为了使用这些子命令,您将不需要设置制造状态来启用 FET (在您的情况下,请不要调用 AFE_FET_ENABLE())。

    CHGTEST 子命令的//示例
    TX_2Byte[0] =  0x1F; TX_2Byte[1] =  0x00;  
    I2C_WriteReg (0x3E、TX_2Byte、2);
    delayUS(1000);
     
    这将切换 FET、因此请使用它一次来打开、然后再次使用它来关闭。 请告诉我、这是否有助于向您展示 FET 是否正常工作。
    看起来您的代码中已经有这些函数(即 PDSG_TEST())  
     
    对于温度读数、即使未校准、也应仍然接近预期值。 但是、我注意到在您的代码中、您使用了带有%d 标识 符的 printf、但在 Temperature[]中计算的温度是浮点值、因此如果这是获取温度数据的方式、您需要将%f 用于标识符。 您还可以使用调试器工具单步进入它计算温度的部分、并查看存储在数组中的值。
    使用0x0F 时、您的 temp 引脚配置看起来正确。

    最棒的
    Andrew