BQ76942配置:与MCU通信选择软件I2C还是硬件I2C?

AFE系列文章

德州仪器TI作为AFE龙头老大,具有多款功能强大的AFE,国产AFE的设计基本也是对标TI。本系列文章旨在对TI的一款AFE BQ76942容易踩坑的地方进行总结,希望对使用这款AFE的工程师们有所帮助。

第一章 BQ76942配置:使用AFE FET寄存器来控MOS
第二章 BQ76942配置:与MCU通信——软件I2C or 硬件I2C?
第三章 BQ76942配置:电流采样配置
第四章 BQ76942配置:过压保护(SOV)配置
第五章 BQ76942配置:采样断线对MOS的影响
第六章 BQ76942配置:充电时AFE自行休眠现象


文章目录

  • AFE系列文章
  • 前言
  • 一、两种I2C的区别
  • 二、参考代码

  • 前言

    BQ76952 器件集成了三个串行通信接口: I2C 总线, 其支持 100kHz 和 400kHz 模式, 可选 CRC 校验; SPI 总线, 可选 CRC 校验, 支持高达 2MHz 的时钟速率; 以及单线 HDQ 接口。 BQ76952 器件默认配置为 I2C 模式( 其他版本的器件, 例如 BQ7695201, 可能默认配置为不同的模式), 并且可以通过对寄存器或 OTP 配置进行相应编程来更改为 SPI 或 HDQ 模式。客户可以在生产线上对器件的集成 OTP 进行编程, 以设置在运行中加电时使用的所需通信速度和协议。


    一、两种I2C的区别

    我们都知道I2C分为软件I2C和硬件I2C,软件I2C是通过模拟电平的时序来实现和器件之间的通信,硬件I2C则是直接通过MCU内置的I2C模块进行通信。

    BQ76942这款AFE有个问题,MCU使用软件I2C的方式与AFE进行通信时,SDA时序间需要加大量的延时否则通信失败,而硬件I2C则不需要加延时

    如果大家使用STM32的硬件I2C会发现经常在while循环里进行了死锁,ST貌似在已修复这个问题,但是一些国产的MCU厂家没修复这个bug,目前使用NXP的MCU与BQ76942进行硬件I2C的通信比较合适,不存在通信方面的问题。

    二、参考代码

    <main.c> 代码如下:

    /******************************************************************************
      * @file           : main.c
      * @brief          : Main program body 
      * (Non-USER sections generated from STM32CubeMX software)
      ******************************************************************************/
      
      
      
    //  BQ76952EVM 代码例程 
    //
    //  引脚接线描述: The I2C SCL and SDA pins are the only pin connections required between the NUCLEO board and the BQ76952EVM for this demo code. Also a ground connection should be made between the 2 boards.The ALERT, RST_SHUT, and DFETOFF pins are also configured on the MCU and can be used as shown.
    //I2C的SCL和SDA引脚是该演示代码在NUCLEO板和BQ76952EVM之间所需的唯一引脚连接。另外,两个板子之间也要接地。ALERT, RST_SHUT和DFETOFF引脚也在MCU上配置,可以如下所示使用。
    //
    //                                     /|\ /|\ 
    //                   STM32             5k |
    //                 -----------------    |  5k
    //                |             PB8 |---+---|-- I2C Clock (SCL)
    //                |                 |       |
    //                |		        PB9 |-------+-- I2C Data (SDA)
    //                |                 |
    //     DFETOFF ---| PA8             |
    //                |                 |
    //   RST_SHUT  ---| PA9        		|--- Green LED
    //                |                 |
    //      ALERT  ---|	PA10            |
    //                |                 |
    
    
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include <stdio.h>
    #include "BQ769x2Header.h"
    
    #define DEV_ADDR  0x10  // BQ769x2 address is 0x10 including R/W bit or 0x8 as 7-bit address
    #define CRC_Mode 0  // 0 for disabled, 1 for enabled
    #define MAX_BUFFER_SIZE 10
    #define R 0 // Read; Used in DirectCommands and Subcommands functions
    #define W 1 // Write; Used in DirectCommands and Subcommands functions
    #define W2 2 // Write data with two bytes; Used in Subcommands function
    
    
    
    /* Private variables ---------------------------------------------------------*/
    I2C_HandleTypeDef hi2c1;
    
    TIM_HandleTypeDef htim1;
    
    UART_HandleTypeDef huart2;
    
    /* USER CODE BEGIN PV */
    uint8_t RX_data [2]    = {0x00, 0x00}; // used in several functions to store data read from BQ769x2
    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};
    	//used in Subcommands read function
    // Global Variables for cell voltages, temperatures, Stack voltage, PACK Pin voltage, LD Pin voltage, CC2 current
    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};
    uint16_t Stack_Voltage = 0x00;
    uint16_t Pack_Voltage = 0x00;
    uint16_t LD_Voltage = 0x00;
    uint16_t Pack_Current = 0x00;
    
    uint16_t AlarmBits = 0x00;
    uint8_t value_SafetyStatusA;  // Safety Status Register A
    uint8_t value_SafetyStatusB;  // Safety Status Register B
    uint8_t value_SafetyStatusC;  // Safety Status Register C
    uint8_t value_PFStatusA;   // Permanent Fail Status Register A
    uint8_t value_PFStatusB;   // Permanent Fail Status Register B
    uint8_t value_PFStatusC;   // Permanent Fail Status Register C
    uint8_t FET_Status;  // FET Status register contents  - Shows states of FETs
    uint16_t CB_ActiveCells;  // Cell Balancing Active Cells
    
    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 ProtectionsTriggered = 0; // Set to 1 if any protection triggers
    
    uint8_t LD_ON = 0;	// Load Detect status bit
    uint8_t DSG = 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; // in BQ769x2_READPASSQ func
    uint32_t AccumulatedCharge_Frac;// in BQ769x2_READPASSQ func
    uint32_t AccumulatedCharge_Time;// in BQ769x2_READPASSQ func
    /* 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_USART2_UART_Init(void);
    static void MX_TIM1_Init(void);
    /* USER CODE BEGIN PFP */
    void delayUS(uint32_t us) {   // Sets the delay in microseconds.
    	__HAL_TIM_SET_COUNTER(&htim1,0);  // set the counter value a 0
    	while (__HAL_TIM_GET_COUNTER(&htim1) < us);  // wait for the counter to reach the us input in the parameter
    }
    
    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)
    //Calculates CRC8 for passed bytes. Used in i2c read and write functions 
    {
    	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)
    {
    	uint8_t TX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    #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, crc_count, 1000);
    	}
    #else 
    	HAL_I2C_Mem_Write(&hi2c1, DEV_ADDR, reg_addr, 1, reg_data, count, 1000);
    #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.
    	uint8_t RX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    #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);
    	}
    #else
    	HAL_I2C_Mem_Read(&hi2c1, DEV_ADDR, reg_addr, 1, reg_data, count, 1000);
    #endif
    	return 0;
    }
    
    void BQ769x2_SetRegister(uint16_t reg_addr, uint32_t reg_data, uint8_t datalen)
    {
    	uint8_t TX_Buffer[2] = {0x00, 0x00};
    	uint8_t TX_RegData[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
    	//TX_RegData in little endian format
    	TX_RegData[0] = reg_addr & 0xff; 
    	TX_RegData[1] = (reg_addr >> 8) & 0xff;
    	TX_RegData[2] = reg_data & 0xff; //1st byte of data
    
    	switch(datalen)
        {
    		case 1: //1 byte datalength
          		I2C_WriteReg(0x3E, TX_RegData, 3);
    			delayUS(2000);
    			TX_Buffer[0] = Checksum(TX_RegData, 3); 
    			TX_Buffer[1] = 0x05; //combined length of register address and data
          		I2C_WriteReg(0x60, TX_Buffer, 2); // Write the checksum and length
    			delayUS(2000);
    			break;
    		case 2: //2 byte datalength
    			TX_RegData[3] = (reg_data >> 8) & 0xff;
    			I2C_WriteReg(0x3E, TX_RegData, 4);
    			delayUS(2000);
    			TX_Buffer[0] = Checksum(TX_RegData, 4); 
    			TX_Buffer[1] = 0x06; //combined length of register address and data
          		I2C_WriteReg(0x60, TX_Buffer, 2); // Write the checksum and length
    			delayUS(2000);
    			break;
    		case 4: //4 byte datalength, Only used for CCGain and Capacity Gain
    			TX_RegData[3] = (reg_data >> 8) & 0xff;
    			TX_RegData[4] = (reg_data >> 16) & 0xff;
    			TX_RegData[5] = (reg_data >> 24) & 0xff;
    			I2C_WriteReg(0x3E, TX_RegData, 6);
    			delayUS(2000);
    			TX_Buffer[0] = Checksum(TX_RegData, 6); 
    			TX_Buffer[1] = 0x08; //combined length of register address and data
          		I2C_WriteReg(0x60, TX_Buffer, 2); // Write the checksum and length
    			delayUS(2000);
    			break;
        }
    }
    
    void CommandSubcommands(uint16_t command) //For Command only Subcommands
    // See the TRM or the BQ76952 header file for a full list of Command-only subcommands
    {	//For DEEPSLEEP/SHUTDOWN subcommand you will need to call this function twice consecutively
    	
    	uint8_t TX_Reg[2] = {0x00, 0x00};
    
    	//TX_Reg in little endian format
    	TX_Reg[0] = command & 0xff;
    	TX_Reg[1] = (command >> 8) & 0xff;
    
    	I2C_WriteReg(0x3E,TX_Reg,2); 
    	delayUS(2000);
    }
    
    void Subcommands(uint16_t command, uint16_t data, uint8_t type)
    // See the TRM or the BQ76952 header file for a full list of Subcommands
    {
    	//security keys and Manu_data writes dont work with this function (reading these commands works)
    	//max readback size is 32 bytes i.e. DASTATUS, CUV/COV snapshot
    	uint8_t TX_Reg[4] = {0x00, 0x00, 0x00, 0x00};
    	uint8_t TX_Buffer[2] = {0x00, 0x00};
    
    	//TX_Reg in little endian format
    	TX_Reg[0] = command & 0xff;
    	TX_Reg[1] = (command >> 8) & 0xff; 
    
    	if (type == R) {//read
    		I2C_WriteReg(0x3E,TX_Reg,2);
    		delayUS(2000);
    		I2C_ReadReg(0x40, RX_32Byte, 32); //RX_32Byte is a global variable
    	}
    	else if (type == W) {
    		//FET_Control, REG12_Control
    		TX_Reg[2] = data & 0xff; 
    		I2C_WriteReg(0x3E,TX_Reg,3);
    		delayUS(1000);
    		TX_Buffer[0] = Checksum(TX_Reg, 3);
    		TX_Buffer[1] = 0x05; //combined length of registers address and data
    		I2C_WriteReg(0x60, TX_Buffer, 2);
    		delayUS(1000); 
    	}
    	else if (type == W2){ //write data with 2 bytes
    		//CB_Active_Cells, CB_SET_LVL
    		TX_Reg[2] = data & 0xff; 
    		TX_Reg[3] = (data >> 8) & 0xff;
    		I2C_WriteReg(0x3E,TX_Reg,4);
    		delayUS(1000);
    		TX_Buffer[0] = Checksum(TX_Reg, 4); 
    		TX_Buffer[1] = 0x06; //combined length of registers address and data
    		I2C_WriteReg(0x60, TX_Buffer, 2);
    		delayUS(1000); 
    	}
    }
    
    void DirectCommands(uint8_t command, uint16_t data, uint8_t type)
    // See the TRM or the BQ76952 header file for a full list of Direct Commands
    {	//type: R = read, W = write
    	uint8_t TX_data[2] = {0x00, 0x00};
    
    	//little endian format
    	TX_data[0] = data & 0xff;
    	TX_data[1] = (data >> 8) & 0xff;
    
    	if (type == R) {//Read
    		I2C_ReadReg(command, RX_data, 2); //RX_data is a global variable
    		delayUS(2000);
    	}
    	if (type == W) {//write
        //Control_status, alarm_status, alarm_enable all 2 bytes long
    		I2C_WriteReg(command,TX_data,2);
    		delayUS(2000);
    	}
    }
    
    void BQ769x2_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
    	CommandSubcommands(SET_CFGUPDATE);
    
    	// 'Power Config' - 0x9234 = 0x2D80
    	// 置位DPSLP_LDO :进入休眠模式,让LDOs保持激活状态
      	// 设置 wake speed bits to 00 : 全速模式
    	BQ769x2_SetRegister(PowerConfig, 0x2D80, 2);
    
    	// 'REG0 Config' - set REG0_EN bit : 启用前置稳压器
    	BQ769x2_SetRegister(REG0Config, 0x01, 1);
    
    	// 'REG12 Config' - 使能 REG1 输出3.3V
    	BQ769x2_SetRegister(REG12Config, 0x0D, 1);
    
    	// Set DFETOFF pin to control BOTH CHG and DSG FET 输出 - 0x92FB = 0x42 (set to 0x00 to disable)
    	BQ769x2_SetRegister(DFETOFFPinConfig, 0x42, 1);
    
    	// Set up ALERT Pin - 0x92FC = 0x2A
    	// This configures the ALERT pin to drive high (REG1 voltage) when enabled.
    	//在 ALERT 引脚上生成警报信号的功能, 该信号可用作主机处理器的中断。
    	BQ769x2_SetRegister(ALERTPinConfig, 0x2A, 1);
    
    	// Set TS1 to measure Cell Temperature - 0x92FD = 0x07
    	BQ769x2_SetRegister(TS1Config, 0x07, 1);
    
    	// Set TS3 to measure FET Temperature - 0x92FF = 0x0F
    	BQ769x2_SetRegister(TS3Config, 0x0F, 1);
    
    	// Set HDQ to measure Cell Temperature - 0x9300 = 0x07
    	BQ769x2_SetRegister(HDQPinConfig, 0x00, 1);  // No thermistor热敏电阻 installed on EVM评估版 HDQ pin, so set to 0x00
    
    	// 'VCell Mode' - Enable 16 cells - 0x9304 = 0x0000; Writing 0x0000 sets the default of 16 cells
    	BQ769x2_SetRegister(VCellMode, 0x0000, 2);
    
    	// 使能保护功能: 'Enabled Protections A' 0x9261 = 0xBC
    	// Enables SCD (short-circuit), OCD1 (over-current in discharge), OCC (over-current in charge),
    	// COV (over-voltage), CUV (under-voltage)
    	BQ769x2_SetRegister(EnabledProtectionsA, 0xBC, 1);
    
    	// 使能所有保护: 'Enabled Protections B' 0x9262 = 0xF7
    	// 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)
    	BQ769x2_SetRegister(EnabledProtectionsB, 0xF7, 1);
    
    	// 'Default Alarm Mask' - 0x..82 Enables the FullScan and ADScan bits, default value = 0xF800
    	BQ769x2_SetRegister(DefaultAlarmMask, 0xF882, 2);
    
    	//设置 Balancing Configuration - 0x9335 = 0x03   -  Automated balancing while in Relax or Charge modes
    	// Also see "Cell Balancing with BQ769x2 Battery Monitors" document on ti.com
    	BQ769x2_SetRegister(BalancingConfiguration, 0x03, 1);
    
    	// Set up CUV (under-voltage) Threshold - 0x9275 = 0x31 (2479 mV)
    	// CUV Threshold is this value multiplied by 50.6mV
    	BQ769x2_SetRegister(CUVThreshold, 0x31, 1);
    
    	// Set up COV (over-voltage) Threshold - 0x9278 = 0x55 (4301 mV)
    	// COV Threshold is this value multiplied by 50.6mV
    	BQ769x2_SetRegister(COVThreshold, 0x55, 1);
    
    	// Set up OCC (over-current in charge) Threshold - 0x9280 = 0x05 (10 mV = 10A across 1mOhm sense resistor) Units in 2mV
    	BQ769x2_SetRegister(OCCThreshold, 0x05, 1);
    
    	// Set up OCD1 Threshold - 0x9282 = 0x0A (20 mV = 20A across 1mOhm sense resistor) units of 2mV
    	BQ769x2_SetRegister(OCD1Threshold, 0x0A, 1);
    
    	// Set up SCD Threshold - 0x9286 = 0x05 (100 mV = 100A across 1mOhm sense resistor)  0x05=100mV
    	BQ769x2_SetRegister(SCDThreshold, 0x05, 1);
    
    	// Set up SCD Delay - 0x9287 = 0x03 (30 us) Enabled with a delay of (value - 1) * 15 µs; min value of 1    
    	BQ769x2_SetRegister(SCDDelay, 0x03, 1);
    
    	// 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).
    	BQ769x2_SetRegister(SCDLLatchLimit, 0x01, 1);
    
    	// Exit CONFIGUPDATE mode  - Subcommand 0x0092
    	CommandSubcommands(EXIT_CFGUPDATE);
    }
    
    //  ********************************* FET Control Commands  ***************************************
    
    void BQ769x2_BOTHOFF () {
    	// Disables all FETs using the DFETOFF (BOTHOFF) pin
    	// The DFETOFF pin on the BQ76952EVM should be connected to the MCU board to use this function
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);  // DFETOFF pin (BOTHOFF) set high
    }
    
    void BQ769x2_RESET_BOTHOFF () {
    	// Resets DFETOFF (BOTHOFF) pin
    	// The DFETOFF pin on the BQ76952EVM should be connected to the MCU board to use this function
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);  // DFETOFF pin (BOTHOFF) set low
    }
    
    void BQ769x2_ReadFETStatus() { 
    	// Read FET Status to see which FETs are enabled
    	DirectCommands(FETStatus, 0x00, R);
    	FET_Status = (RX_data[1]*256 + RX_data[0]);
    	DSG = ((0x4 & RX_data[0])>>2);// discharge FET state
      	CHG = (0x1 & RX_data[0]);// charge FET state
      	PCHG = ((0x2 & RX_data[0])>>1);// pre-charge FET state
      	PDSG = ((0x8 & RX_data[0])>>3);// pre-discharge FET state
    }
    
    // ********************************* End of FET Control Commands *********************************
    
    // ********************************* BQ769x2 Power Commands   *****************************************
    
    void BQ769x2_ShutdownPin() {
    	// Puts the device into SHUTDOWN mode using the RST_SHUT pin
    	// The RST_SHUT pin on the BQ76952EVM should be connected to the MCU board to use this function	
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);  // Sets RST_SHUT pin
    }
    
    void BQ769x2_ReleaseShutdownPin() {
    	// Releases the RST_SHUT pin
    	// The RST_SHUT pin on the BQ76952EVM should be connected to the MCU board to use this function	
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);  // Resets RST_SHUT pin
    }
    
    // ********************************* End of BQ769x2 Power Commands   *****************************************
    
    
    // ********************************* BQ769x2 Status and Fault Commands   *****************************************
    
    uint16_t BQ769x2_ReadAlarmStatus() { 
    	// Read this register to find out why the ALERT pin was asserted
    	DirectCommands(AlarmStatus, 0x00, R);
    	return (RX_data[1]*256 + RX_data[0]);
    }
    
    void BQ769x2_ReadSafetyStatus() { //good example functions
    	// Read Safety Status A/B/C and find which bits are set
    	// This shows which primary protections have been triggered
    	DirectCommands(SafetyStatusA, 0x00, R);
    	value_SafetyStatusA = (RX_data[1]*256 + RX_data[0]);
    	//Example Fault Flags
    	UV_Fault = ((0x4 & RX_data[0])>>2); 
    	OV_Fault = ((0x8 & RX_data[0])>>3);
    	SCD_Fault = ((0x8 & RX_data[1])>>3);
    	OCD_Fault = ((0x2 & RX_data[1])>>1);
    	DirectCommands(SafetyStatusB, 0x00, R);
    	value_SafetyStatusB = (RX_data[1]*256 + RX_data[0]);
    	DirectCommands(SafetyStatusC, 0x00, R);
    	value_SafetyStatusC = (RX_data[1]*256 + RX_data[0]);
    	if ((value_SafetyStatusA + value_SafetyStatusB + value_SafetyStatusC) > 1) {
    		ProtectionsTriggered = 1; }
    	else {
    		ProtectionsTriggered = 0; }
    }
    
    void BQ769x2_ReadPFStatus() {
    	// Read Permanent Fail Status A/B/C and find which bits are set
    	// This shows which permanent failures have been triggered
    	DirectCommands(PFStatusA, 0x00, R);
    	value_PFStatusA = (RX_data[1]*256 + RX_data[0]);
    	DirectCommands(PFStatusB, 0x00, R);
    	value_PFStatusB = (RX_data[1]*256 + RX_data[0]);
    	DirectCommands(PFStatusC, 0x00, R);
    	value_PFStatusC = (RX_data[1]*256 + RX_data[0]);
    }
    
    // ********************************* End of BQ769x2 Status and Fault Commands   *****************************************
    
    
    // ********************************* BQ769x2 Measurement Commands   *****************************************
    
    
    uint16_t BQ769x2_ReadVoltage(uint8_t command)
    // This function can be used to read a specific cell voltage or stack / pack / LD voltage
    {
    	//RX_data is global var
    	DirectCommands(command, 0x00, R);
    	if(command >= Cell1Voltage && command <= Cell16Voltage) {//Cells 1 through 16 (0x14 to 0x32)
    		return (RX_data[1]*256 + RX_data[0]); //voltage is reported in mV
    	}
    	else {//stack, Pack, LD
    		return 10 * (RX_data[1]*256 + RX_data[0]); //voltage is reported in 0.01V units
    	}
    
    }
    void BQ769x2_ReadAllVoltages()
    // Reads all cell voltages, Stack voltage, PACK pin voltage, and LD pin voltage
    {
      int cellvoltageholder = Cell1Voltage; //Cell1Voltage is 0x14
      for (int x = 0; x < 16; x++){//Reads all cell voltages
        CellVoltage[x] = BQ769x2_ReadVoltage(cellvoltageholder);
        cellvoltageholder = cellvoltageholder + 2;
      }
      Stack_Voltage = BQ769x2_ReadVoltage(StackVoltage);
      Pack_Voltage = BQ769x2_ReadVoltage(PACKPinVoltage);
      LD_Voltage = BQ769x2_ReadVoltage(LDPinVoltage);
    }
    
    uint16_t BQ769x2_ReadCurrent() 
    // Reads PACK current 
    {
    	DirectCommands(CC2Current, 0x00, R);
    	return (RX_data[1]*256 + RX_data[0]);  // current is reported in mA
    }
    
    float BQ769x2_ReadTemperature(uint8_t command) 
    {
    	DirectCommands(command, 0x00, R);
    	//RX_data is a global var
    	return (0.1 * (float)(RX_data[1]*256 + RX_data[0])) - 273.15;  // converts from 0.1K to Celcius
    }
    
    void BQ769x2_ReadPassQ(){ // Read Accumulated Charge and Time from DASTATUS6 
    	Subcommands(DASTATUS6, 0x00, R);
    	AccumulatedCharge_Int = ((RX_32Byte[3]<<24) + (RX_32Byte[2]<<16) + (RX_32Byte[1]<<8) + RX_32Byte[0]); //Bytes 0-3
    	AccumulatedCharge_Frac = ((RX_32Byte[7]<<24) + (RX_32Byte[6]<<16) + (RX_32Byte[5]<<8) + RX_32Byte[4]); //Bytes 4-7
    	AccumulatedCharge_Time = ((RX_32Byte[11]<<24) + (RX_32Byte[10]<<16) + (RX_32Byte[9]<<8) + RX_32Byte[8]); //Bytes 8-11
    }
    
    // ********************************* End of BQ769x2 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 */
    
      /* 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_USART2_UART_Init();
      	MX_TIM1_Init();
      /* USER CODE BEGIN 2 */
    	// Start timer
    	HAL_TIM_Base_Start(&htim1);
    
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);  // RST_SHUT复位引脚 pin set low
    	//主机可以通过使 CFETOFF 或 DFETOFF 引脚生效或发送 FET 控制子命令来禁用 FET( 表5-8) 。
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);  // DFETOFF pin (BOTHOFF) set low
      	delayUS(10000);
    
    	CommandSubcommands(BQ769x2_RESET);  // Resets the BQ769x2 registers
    	delayUS(60000);
    	BQ769x2_Init();  // Configure all of the BQ769x2 register settings
    	delayUS(10000);
    	CommandSubcommands(FET_ENABLE); // Enable the CHG and DSG FETs
    	delayUS(10000);
    	CommandSubcommands(SLEEP_DISABLE); // Sleep mode is enabled by default. For this example, Sleep is disabled to 
    									   // demonstrate full-speed measurements in Normal mode. 
    
    	delayUS(60000); delayUS(60000); delayUS(60000); delayUS(60000);  //wait to start measurements after FETs close
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    	
        //Reads Cell, Stack, Pack, LD Voltages, Pack Current and TS1/TS3 Temperatures in a loop
    	//This basic example polls the Alarm Status register to see if protections have triggered or new measurements are ready
    	//The ALERT pin can also be used as an interrupt to the microcontroller for fastest response time instead of polling
    	//In this example the LED on the microcontroller board will be turned on to indicate a protection has triggered and will 
    	//be turned off if the protection condition has cleared.
    
    		AlarmBits = BQ769x2_ReadAlarmStatus();
    		if (AlarmBits & 0x80)   // Check if FULLSCAN is complete. If set, new measurements are available
    		{  
          		BQ769x2_ReadAllVoltages();
          		Pack_Current = BQ769x2_ReadCurrent();
          		Temperature[0] = BQ769x2_ReadTemperature(TS1Temperature);
          		Temperature[1] = BQ769x2_ReadTemperature(TS3Temperature);
    			DirectCommands(AlarmStatus, 0x0080, W);  // Clear the FULLSCAN bit
    		}
    				
    		if (AlarmBits & 0xC000) // If Safety Status bits are showing in AlarmStatus register
    		{  
    			BQ769x2_ReadSafetyStatus(); // Read the Safety Status registers to find which protections have triggered
    			if (ProtectionsTriggered & 1) 
    			{
    				// Turn on the LED to indicate Protection has triggered
    				HAL_GPIO_WritePin(GPIOA, LD2_Pin, GPIO_PIN_SET); 
    			}
    			DirectCommands(AlarmStatus, 0xF800, W); // Clear the Safety Status Alarm bits.
    		}
    		else
    		{
    			if (ProtectionsTriggered & 1) 
    			{
    				BQ769x2_ReadSafetyStatus();
    				if (!(ProtectionsTriggered & 1)) 
    				{
    					// Turn off the LED if Safety Status has cleared which means the protection condition is no longer present
    					HAL_GPIO_WritePin(GPIOA, LD2_Pin, GPIO_PIN_RESET);
    				} 
    			} 
    		}
    		delayUS(20000);  // repeat loop every 20 ms
      }
      /* USER CODE END 3 */
    }
    
    /**
      * @brief System Clock Configuration
      * @retval None
      */
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;
      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_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != 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.ClockSpeed = 400000;
      hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
      hi2c1.Init.OwnAddress1 = 0;
      hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
      hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
      hi2c1.Init.OwnAddress2 = 0;
      hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
      hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
      if (HAL_I2C_Init(&hi2c1) != 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.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 USART2 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_USART2_UART_Init(void)
    {
    
      /* USER CODE BEGIN USART2_Init 0 */
    
      /* USER CODE END USART2_Init 0 */
    
      /* USER CODE BEGIN USART2_Init 1 */
    
      /* USER CODE END USART2_Init 1 */
      huart2.Instance = USART2;
      huart2.Init.BaudRate = 115200;
      huart2.Init.WordLength = UART_WORDLENGTH_8B;
      huart2.Init.StopBits = UART_STOPBITS_1;
      huart2.Init.Parity = UART_PARITY_NONE;
      huart2.Init.Mode = UART_MODE_TX_RX;
      huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      huart2.Init.OverSampling = UART_OVERSAMPLING_16;
      if (HAL_UART_Init(&huart2) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN USART2_Init 2 */
    
      /* USER CODE END USART2_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_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOA, LD2_Pin|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_RESET);
    
      /*Configure GPIO pin : B1_Pin */
      GPIO_InitStruct.Pin = B1_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
    
      /*Configure GPIO pins : LD2_Pin PA8 PA9 PA10 */
      GPIO_InitStruct.Pin = LD2_Pin|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
      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);
    
      /* EXTI interrupt init*/
      HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
    
    }
    
    /* 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 */
    
      /* 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,
         tex: 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****/
    

    <BQ769x2Header.h> 代码如下:

    //BQ769x2 General Program Header File
    typedef unsigned char		uint8_t;
    typedef unsigned short int  uint16_t;
    typedef unsigned long int   uint32_t;
    
    //Data	Memory	registers	Name in TRM
    #define Cell1Gain 0x9180      //Calibration:Voltage:Cell 1 Gain			
    #define Cell2Gain 0x9182      //Calibration:Voltage:Cell 2 Gain			
    #define Cell3Gain 0x9184      //Calibration:Voltage:Cell 3 Gain			
    #define Cell4Gain 0x9186      //Calibration:Voltage:Cell 4 Gain			
    #define Cell5Gain 0x9188      //Calibration:Voltage:Cell 5 Gain			
    #define Cell6Gain 0x918A      //Calibration:Voltage:Cell 6 Gain			
    #define Cell7Gain 0x918C      //Calibration:Voltage:Cell 7 Gain			
    #define Cell8Gain 0x918E      //Calibration:Voltage:Cell 8 Gain			
    #define Cell9Gain 0x9190      //Calibration:Voltage:Cell 9 Gain			
    #define Cell10Gain 0x9192      //Calibration:Voltage:Cell 10 Gain			
    #define Cell11Gain 0x9194      //Calibration:Voltage:Cell 11 Gain			
    #define Cell12Gain 0x9196      //Calibration:Voltage:Cell 12 Gain			
    #define Cell13Gain 0x9198      //Calibration:Voltage:Cell 13 Gain			
    #define Cell14Gain 0x919A      //Calibration:Voltage:Cell 14 Gain			
    #define Cell15Gain 0x919C      //Calibration:Voltage:Cell 15 Gain			
    #define Cell16Gain 0x919E      //Calibration:Voltage:Cell 16 Gain			
    #define PackGain 0x91A0      //Calibration:Voltage:Pack Gain			
    #define TOSGain 0x91A2      //Calibration:Voltage:TOS Gain			
    #define LDGain 0x91A4      //Calibration:Voltage:LD Gain			
    #define ADCGain 0x91A6      //Calibration:Voltage:ADC Gain			
    #define CCGain 0x91A8      //Calibration:Current:CC Gain			
    #define CapacityGain 0x91AC      //Calibration:Current:Capacity Gain			
    #define VcellOffset 0x91B0      //Calibration:Vcell Offset:Vcell Offset			
    #define VdivOffset 0x91B2      //Calibration:V Divider Offset:Vdiv Offset			
    #define CoulombCounterOffsetSamples 0x91C6      //Calibration:Current Offset:Coulomb Counter Offset Samples			
    #define BoardOffset 0x91C8      //Calibration:Current Offset:Board Offset			
    #define InternalTempOffset 0x91CA      //Calibration:Temperature:Internal Temp Offset			
    #define CFETOFFTempOffset 0x91CB      //Calibration:Temperature:CFETOFF Temp Offset			
    #define DFETOFFTempOffset 0x91CC      //Calibration:Temperature:DFETOFF Temp Offset			
    #define ALERTTempOffset 0x91CD      //Calibration:Temperature:ALERT Temp Offset			
    #define TS1TempOffset 0x91CE      //Calibration:Temperature:TS1 Temp Offset			
    #define TS2TempOffset 0x91CF      //Calibration:Temperature:TS2 Temp Offset			
    #define TS3TempOffset 0x91D0      //Calibration:Temperature:TS3 Temp Offset			
    #define HDQTempOffset 0x91D1      //Calibration:Temperature:HDQ Temp Offset			
    #define DCHGTempOffset 0x91D2      //Calibration:Temperature:DCHG Temp Offset			
    #define DDSGTempOffset 0x91D3      //Calibration:Temperature:DDSG Temp Offset			
    #define IntGain 0x91E2      //Calibration:Internal Temp Model:Int Gain			
    #define Intbaseoffset 0x91E4      //Calibration:Internal Temp Model:Int base offset			
    #define IntMaximumAD 0x91E6      //Calibration:Internal Temp Model:Int Maximum AD			
    #define IntMaximumTemp 0x91E8      //Calibration:Internal Temp Model:Int Maximum Temp			
    #define T18kCoeffa1 0x91EA      //Calibration:18K Temperature Model:Coeff a1			
    #define T18kCoeffa2 0x91EC      //Calibration:18K Temperature Model:Coeff a2			
    #define T18kCoeffa3 0x91EE      //Calibration:18K Temperature Model:Coeff a3			
    #define T18kCoeffa4 0x91F0      //Calibration:18K Temperature Model:Coeff a4			
    #define T18kCoeffa5 0x91F2      //Calibration:18K Temperature Model:Coeff a5			
    #define T18kCoeffb1 0x91F4      //Calibration:18K Temperature Model:Coeff b1			
    #define T18kCoeffb2 0x91F6      //Calibration:18K Temperature Model:Coeff b2			
    #define T18kCoeffb3 0x91F8      //Calibration:18K Temperature Model:Coeff b3			
    #define T18kCoeffb4 0x91FA      //Calibration:18K Temperature Model:Coeff b4			
    #define T18kAdc0 0x91FE      //Calibration:18K Temperature Model:Adc0			
    #define T180kCoeffa1 0x9200      //Calibration:180K Temperature Model:Coeff a1			
    #define T180kCoeffa2 0x9202      //Calibration:180K Temperature Model:Coeff a2			
    #define T180kCoeffa3 0x9204      //Calibration:180K Temperature Model:Coeff a3			
    #define T180kCoeffa4 0x9206      //Calibration:180K Temperature Model:Coeff a4			
    #define T180kCoeffa5 0x9208      //Calibration:180K Temperature Model:Coeff a5			
    #define T180kCoeffb1 0x920A      //Calibration:180K Temperature Model:Coeff b1			
    #define T180kCoeffb2 0x920C      //Calibration:180K Temperature Model:Coeff b2			
    #define T180kCoeffb3 0x920E      //Calibration:180K Temperature Model:Coeff b3			
    #define T180kCoeffb4 0x9210      //Calibration:180K Temperature Model:Coeff b4			
    #define T180kAdc0 0x9214      //Calibration:180K Temperature Model:Adc0			
    #define CustomCoeffa1 0x9216      //Calibration:Custom Temperature Model:Coeff a1			
    #define CustomCoeffa2 0x9218      //Calibration:Custom Temperature Model:Coeff a2			
    #define CustomCoeffa3 0x921A      //Calibration:Custom Temperature Model:Coeff a3			
    #define CustomCoeffa4 0x921C      //Calibration:Custom Temperature Model:Coeff a4			
    #define CustomCoeffa5 0x921E      //Calibration:Custom Temperature Model:Coeff a5			
    #define CustomCoeffb1 0x9220      //Calibration:Custom Temperature Model:Coeff b1			
    #define CustomCoeffb2 0x9222      //Calibration:Custom Temperature Model:Coeff b2			
    #define CustomCoeffb3 0x9224      //Calibration:Custom Temperature Model:Coeff b3			
    #define CustomCoeffb4 0x9226      //Calibration:Custom Temperature Model:Coeff b4			
    #define CustomRc0 0x9228      //Calibration:Custom Temperature Model:Rc0			
    #define CustomAdc0 0x922A      //Calibration:Custom Temperature Model:Adc0			
    #define CoulombCounterDeadband 0x922D      //Calibration:Current Deadband:Coulomb Counter Deadband			
    #define CUVThresholdOverride 0x91D4      //Calibration:CUV:CUV Threshold Override			
    #define COVThresholdOverride 0x91D6      //Calibration:COV:COV Threshold Override			
    #define MinBlowFuseVoltage 0x9231      //Settings:Fuse:Min Blow Fuse Voltage			
    #define FuseBlowTimeout 0x9233      //Settings:Fuse:Fuse Blow Timeout			
    #define PowerConfig 0x9234      //Settings:Configuration:Power Config			
    #define REG12Config 0x9236      //Settings:Configuration:REG12 Config			
    #define REG0Config 0x9237      //Settings:Configuration:REG0 Config			
    #define HWDRegulatorOptions 0x9238      //Settings:Configuration:HWD Regulator Options			
    #define CommType 0x9239      //Settings:Configuration:Comm Type			
    #define I2CAddress 0x923A      //Settings:Configuration:I2C Address			
    #define SPIConfiguration 0x923C      //Settings:Configuration:SPI Configuration			
    #define CommIdleTime 0x923D      //Settings:Configuration:Comm Idle Time			
    #define CFETOFFPinConfig 0x92FA      //Settings:Configuration:CFETOFF Pin Config			
    #define DFETOFFPinConfig 0x92FB      //Settings:Configuration:DFETOFF Pin Config			
    #define ALERTPinConfig 0x92FC      //Settings:Configuration:ALERT Pin Config			
    #define TS1Config 0x92FD      //Settings:Configuration:TS1 Config			
    #define TS2Config 0x92FE      //Settings:Configuration:TS2 Config			
    #define TS3Config 0x92FF      //Settings:Configuration:TS3 Config			
    #define HDQPinConfig 0x9300      //Settings:Configuration:HDQ Pin Config			
    #define DCHGPinConfig 0x9301      //Settings:Configuration:DCHG Pin Config			
    #define DDSGPinConfig 0x9302      //Settings:Configuration:DDSG Pin Config			
    #define DAConfiguration 0x9303      //Settings:Configuration:DA Configuration			
    #define VCellMode 0x9304      //Settings:Configuration:Vcell Mode			
    #define CC3Samples 0x9307      //Settings:Configuration:CC3 Samples			
    #define ProtectionConfiguration 0x925F      //Settings:Protection:Protection Configuration			
    #define EnabledProtectionsA 0x9261      //Settings:Protection:Enabled Protections A			
    #define EnabledProtectionsB 0x9262      //Settings:Protection:Enabled Protections B			
    #define EnabledProtectionsC 0x9263      //Settings:Protection:Enabled Protections C			
    #define CHGFETProtectionsA 0x9265      //Settings:Protection:CHG FET Protections A			
    #define CHGFETProtectionsB 0x9266      //Settings:Protection:CHG FET Protections B			
    #define CHGFETProtectionsC 0x9267      //Settings:Protection:CHG FET Protections C			
    #define DSGFETProtectionsA 0x9269      //Settings:Protection:DSG FET Protections A			
    #define DSGFETProtectionsB 0x926A      //Settings:Protection:DSG FET Protections B			
    #define DSGFETProtectionsC 0x926B      //Settings:Protection:DSG FET Protections C			
    #define BodyDiodeThreshold 0x9273      //Settings:Protection:Body Diode Threshold			
    #define DefaultAlarmMask 0x926D      //Settings:Alarm:Default Alarm Mask			
    #define SFAlertMaskA 0x926F      //Settings:Alarm:SF Alert Mask A			
    #define SFAlertMaskB 0x9270      //Settings:Alarm:SF Alert Mask B			
    #define SFAlertMaskC 0x9271      //Settings:Alarm:SF Alert Mask C			
    #define PFAlertMaskA 0x92C4      //Settings:Alarm:PF Alert Mask A			
    #define PFAlertMaskB 0x92C5      //Settings:Alarm:PF Alert Mask B			
    #define PFAlertMaskC 0x92C6      //Settings:Alarm:PF Alert Mask C			
    #define PFAlertMaskD 0x92C7      //Settings:Alarm:PF Alert Mask D			
    #define EnabledPFA 0x92C0      //Settings:Permanent Failure:Enabled PF A			
    #define EnabledPFB 0x92C1      //Settings:Permanent Failure:Enabled PF B			
    #define EnabledPFC 0x92C2      //Settings:Permanent Failure:Enabled PF C			
    #define EnabledPFD 0x92C3      //Settings:Permanent Failure:Enabled PF D			
    #define FETOptions 0x9308      //Settings:FET:FET Options			
    #define ChgPumpControl 0x9309      //Settings:FET:Chg Pump Control			
    #define PrechargeStartVoltage 0x930A      //Settings:FET:Precharge Start Voltage			
    #define PrechargeStopVoltage 0x930C      //Settings:FET:Precharge Stop Voltage			
    #define PredischargeTimeout 0x930E      //Settings:FET:Predischarge Timeout			
    #define PredischargeStopDelta 0x930F      //Settings:FET:Predischarge Stop Delta			
    #define DsgCurrentThreshold 0x9310      //Settings:Current Thresholds:Dsg Current Threshold			
    #define ChgCurrentThreshold 0x9312      //Settings:Current Thresholds:Chg Current Threshold			
    #define CheckTime 0x9314      //Settings:Cell Open-Wire:Check Time			
    #define Cell1Interconnect 0x9315      //Settings:Interconnect Resistances:Cell 1 Interconnect			
    #define Cell2Interconnect 0x9317      //Settings:Interconnect Resistances:Cell 2 Interconnect			
    #define Cell3Interconnect 0x9319      //Settings:Interconnect Resistances:Cell 3 Interconnect			
    #define Cell4Interconnect 0x931B      //Settings:Interconnect Resistances:Cell 4 Interconnect			
    #define Cell5Interconnect 0x931D      //Settings:Interconnect Resistances:Cell 5 Interconnect			
    #define Cell6Interconnect 0x931F      //Settings:Interconnect Resistances:Cell 6 Interconnect			
    #define Cell7Interconnect 0x9321      //Settings:Interconnect Resistances:Cell 7 Interconnect			
    #define Cell8Interconnect 0x9323      //Settings:Interconnect Resistances:Cell 8 Interconnect			
    #define Cell9Interconnect 0x9325      //Settings:Interconnect Resistances:Cell 9 Interconnect			
    #define Cell10Interconnect 0x9327      //Settings:Interconnect Resistances:Cell 10 Interconnect			
    #define Cell11Interconnect 0x9329      //Settings:Interconnect Resistances:Cell 11 Interconnect			
    #define Cell12Interconnect 0x932B      //Settings:Interconnect Resistances:Cell 12 Interconnect			
    #define Cell13Interconnect 0x932D      //Settings:Interconnect Resistances:Cell 13 Interconnect			
    #define Cell14Interconnect 0x932F      //Settings:Interconnect Resistances:Cell 14 Interconnect			
    #define Cell15Interconnect 0x9331      //Settings:Interconnect Resistances:Cell 15 Interconnect			
    #define Cell16Interconnect 0x9333      //Settings:Interconnect Resistances:Cell 16 Interconnect			
    #define MfgStatusInit 0x9343      //Settings:Manufacturing:Mfg Status Init			
    #define BalancingConfiguration 0x9335      //Settings:Cell Balancing Config:Balancing Configuration			
    #define MinCellTemp 0x9336      //Settings:Cell Balancing Config:Min Cell Temp			
    #define MaxCellTemp 0x9337      //Settings:Cell Balancing Config:Max Cell Temp			
    #define MaxInternalTemp 0x9338      //Settings:Cell Balancing Config:Max Internal Temp			
    #define CellBalanceInterval 0x9339      //Settings:Cell Balancing Config:Cell Balance Interval			
    #define CellBalanceMaxCells 0x933A      //Settings:Cell Balancing Config:Cell Balance Max Cells			
    #define CellBalanceMinCellVCharge 0x933B      //Settings:Cell Balancing Config:Cell Balance Min Cell V (Charge)			
    #define CellBalanceMinDeltaCharge 0x933D      //Settings:Cell Balancing Config:Cell Balance Min Delta (Charge)			
    #define CellBalanceStopDeltaCharge 0x933E      //Settings:Cell Balancing Config:Cell Balance Stop Delta (Charge)			
    #define CellBalanceMinCellVRelax 0x933F      //Settings:Cell Balancing Config:Cell Balance Min Cell V (Relax)			
    #define CellBalanceMinDeltaRelax 0x9341      //Settings:Cell Balancing Config:Cell Balance Min Delta (Relax)			
    #define CellBalanceStopDeltaRelax 0x9342      //Settings:Cell Balancing Config:Cell Balance Stop Delta (Relax)			
    #define ShutdownCellVoltage 0x923F      //Power:Shutdown:Shutdown Cell Voltage			
    #define ShutdownStackVoltage 0x9241      //Power:Shutdown:Shutdown Stack Voltage			
    #define LowVShutdownDelay 0x9243      //Power:Shutdown:Low V Shutdown Delay			
    #define ShutdownTemperature 0x9244      //Power:Shutdown:Shutdown Temperature			
    #define ShutdownTemperatureDelay 0x9245      //Power:Shutdown:Shutdown Temperature Delay			
    #define FETOffDelay 0x9252      //Power:Shutdown:FET Off Delay			
    #define ShutdownCommandDelay 0x9253      //Power:Shutdown:Shutdown Command Delay			
    #define AutoShutdownTime 0x9254      //Power:Shutdown:Auto Shutdown Time			
    #define RAMFailShutdownTime 0x9255      //Power:Shutdown:RAM Fail Shutdown Time			
    #define SleepCurrent 0x9248      //Power:Sleep:Sleep Current			
    #define VoltageTime 0x924A      //Power:Sleep:Voltage Time			
    #define WakeComparatorCurrent 0x924B      //Power:Sleep:Wake Comparator Current			
    #define SleepHysteresisTime 0x924D      //Power:Sleep:Sleep Hysteresis Time			
    #define SleepChargerVoltageThreshold 0x924E      //Power:Sleep:Sleep Charger Voltage Threshold			
    #define SleepChargerPACKTOSDelta 0x9250      //Power:Sleep:Sleep Charger PACK-TOS Delta			
    #define ConfigRAMSignature 0x91E0      //System Data:Integrity:Config RAM Signature			
    #define CUVThreshold 0x9275      //Protections:CUV:Threshold			
    #define CUVDelay 0x9276      //Protections:CUV:Delay			
    #define CUVRecoveryHysteresis 0x927B      //Protections:CUV:Recovery Hysteresis			
    #define COVThreshold 0x9278      //Protections:COV:Threshold			
    #define COVDelay 0x9279      //Protections:COV:Delay			
    #define COVRecoveryHysteresis 0x927C      //Protections:COV:Recovery Hysteresis			
    #define COVLLatchLimit 0x927D      //Protections:COVL:Latch Limit			
    #define COVLCounterDecDelay 0x927E      //Protections:COVL:Counter Dec Delay			
    #define COVLRecoveryTime 0x927F      //Protections:COVL:Recovery Time			
    #define OCCThreshold 0x9280      //Protections:OCC:Threshold			
    #define OCCDelay 0x9281      //Protections:OCC:Delay			
    #define OCCRecoveryThreshold 0x9288      //Protections:OCC:Recovery Threshold			
    #define OCCPACKTOSDelta 0x92B0      //Protections:OCC:PACK-TOS Delta			
    #define OCD1Threshold 0x9282      //Protections:OCD1:Threshold			
    #define OCD1Delay 0x9283      //Protections:OCD1:Delay			
    #define OCD2Threshold 0x9284      //Protections:OCD2:Threshold			
    #define OCD2Delay 0x9285      //Protections:OCD2:Delay			
    #define SCDThreshold 0x9286      //Protections:SCD:Threshold			
    #define SCDDelay 0x9287      //Protections:SCD:Delay			
    #define SCDRecoveryTime 0x9294      //Protections:SCD:Recovery Time			
    #define OCD3Threshold 0x928A      //Protections:OCD3:Threshold			
    #define OCD3Delay 0x928C      //Protections:OCD3:Delay			
    #define OCDRecoveryThreshold 0x928D      //Protections:OCD:Recovery Threshold			
    #define OCDLLatchLimit 0x928F      //Protections:OCDL:Latch Limit			
    #define OCDLCounterDecDelay 0x9290      //Protections:OCDL:Counter Dec Delay			
    #define OCDLRecoveryTime 0x9291      //Protections:OCDL:Recovery Time			
    #define OCDLRecoveryThreshold 0x9292      //Protections:OCDL:Recovery Threshold			
    #define SCDLLatchLimit 0x9295      //Protections:SCDL:Latch Limit			
    #define SCDLCounterDecDelay 0x9296      //Protections:SCDL:Counter Dec Delay			
    #define SCDLRecoveryTime 0x9297      //Protections:SCDL:Recovery Time			
    #define SCDLRecoveryThreshold 0x9298      //Protections:SCDL:Recovery Threshold			
    #define OTCThreshold 0x929A      //Protections:OTC:Threshold			
    #define OTCDelay 0x920B      //Protections:OTC:Delay			
    #define OTCRecovery 0x929C      //Protections:OTC:Recovery			
    #define OTDThreshold 0x929D      //Protections:OTD:Threshold			
    #define OTDDelay 0x929E      //Protections:OTD:Delay			
    #define OTDRecovery 0x929F      //Protections:OTD:Recovery			
    #define OTFThreshold 0x92A0      //Protections:OTF:Threshold			
    #define OTFDelay 0x92A1      //Protections:OTF:Delay			
    #define OTFRecovery 0x92A2      //Protections:OTF:Recovery			
    #define OTINTThreshold 0x92A3      //Protections:OTINT:Threshold			
    #define OTINTDelay 0x92A4      //Protections:OTINT:Delay			
    #define OTINTRecovery 0x92A5      //Protections:OTINT:Recovery			
    #define UTCThreshold 0x92A6      //Protections:UTC:Threshold			
    #define UTCDelay 0x92A7      //Protections:UTC:Delay			
    #define UTCRecovery 0x92A8      //Protections:UTC:Recovery			
    #define UTDThreshold 0x92A9      //Protections:UTD:Threshold			
    #define UTDDelay 0x92AA      //Protections:UTD:Delay			
    #define UTDRecovery 0x92AB      //Protections:UTD:Recovery			
    #define UTINTThreshold 0x92AC      //Protections:UTINT:Threshold			
    #define UTINTDelay 0x92AD      //Protections:UTINT:Delay			
    #define UTINTRecovery 0x92AE      //Protections:UTINT:Recovery			
    #define ProtectionsRecoveryTime 0x92AF      //Protections:Recovery:Time			
    #define HWDDelay 0x92B2      //Protections:HWD:Delay			
    #define LoadDetectActiveTime 0x92B4      //Protections:Load Detect:Active Time			
    #define LoadDetectRetryDelay 0x92B5      //Protections:Load Detect:Retry Delay			
    #define LoadDetectTimeout 0x92B6      //Protections:Load Detect:Timeout			
    #define PTOChargeThreshold 0x92BA      //Protections:PTO:Charge Threshold			
    #define PTODelay 0x92BC      //Protections:PTO:Delay			
    #define PTOReset 0x92BE      //Protections:PTO:Reset			
    #define CUDEPThreshold 0x92C8      //Permanent Fail:CUDEP:Threshold			
    #define CUDEPDelay 0x92CA      //Permanent Fail:CUDEP:Delay			
    #define SUVThreshold 0x92CB      //Permanent Fail:SUV:Threshold			
    #define SUVDelay 0x92CD      //Permanent Fail:SUV:Delay			
    #define SOVThreshold 0x92CE      //Permanent Fail:SOV:Threshold			
    #define SOVDelay 0x92D0      //Permanent Fail:SOV:Delay			
    #define TOSSThreshold 0x92D1      //Permanent Fail:TOS:Threshold			
    #define TOSSDelay 0x92D3      //Permanent Fail:TOS:Delay			
    #define SOCCThreshold 0x92D4      //Permanent Fail:SOCC:Threshold			
    #define SOCCDelay 0x92D6      //Permanent Fail:SOCC:Delay			
    #define SOCDThreshold 0x92D7      //Permanent Fail:SOCD:Threshold			
    #define SOCDDelay 0x92D9      //Permanent Fail:SOCD:Delay			
    #define SOTThreshold 0x92DA      //Permanent Fail:SOT:Threshold			
    #define SOTDelay 0x92DB      //Permanent Fail:SOT:Delay			
    #define SOTFThreshold 0x92DC      //Permanent Fail:SOTF:Threshold			
    #define SOTFDelay 0x92DD      //Permanent Fail:SOTF:Delay			
    #define VIMRCheckVoltage 0x92DE      //Permanent Fail:VIMR:Check Voltage			
    #define VIMRMaxRelaxCurrent 0x92E0      //Permanent Fail:VIMR:Max Relax Current			
    #define VIMRThreshold 0x92E2      //Permanent Fail:VIMR:Threshold			
    #define VIMRDelay 0x92E4      //Permanent Fail:VIMR:Delay			
    #define VIMRRelaxMinDuration 0x92E5      //Permanent Fail:VIMR:Relax Min Duration			
    #define VIMACheckVoltage 0x92E7      //Permanent Fail:VIMA:Check Voltage			
    #define VIMAMinActiveCurrent 0x92E9      //Permanent Fail:VIMA:Min Active Current			
    #define VIMAThreshold 0x92EB      //Permanent Fail:VIMA:Threshold			
    #define VIMADelay 0x92ED      //Permanent Fail:VIMA:Delay			
    #define CFETFOFFThreshold 0x92EE      //Permanent Fail:CFETF:OFF Threshold			
    #define CFETFOFFDelay 0x92F0      //Permanent Fail:CFETF:OFF Delay			
    #define DFETFOFFThreshold 0x92F1      //Permanent Fail:DFETF:OFF Threshold			
    #define DFETFOFFDelay 0x92F3      //Permanent Fail:DFETF:OFF Delay			
    #define VSSFFailThreshold 0x92F4      //Permanent Fail:VSSF:Fail Threshold			
    #define VSSFDelay 0x92F6      //Permanent Fail:VSSF:Delay			
    #define PF2LVLDelay 0x92F7      //Permanent Fail:2LVL:Delay			
    #define LFOFDelay 0x92F8      //Permanent Fail:LFOF:Delay			
    #define HWMXDelay 0x92F9      //Permanent Fail:HWMX:Delay			
    #define SecuritySettings 0x9256      //Security:Settings:Security Settings			
    #define UnsealKeyStep1 0x9257      //Security:Keys:Unseal Key Step 1			
    #define UnsealKeyStep2 0x9259      //Security:Keys:Unseal Key Step 2			
    #define FullAccessKeyStep1 0x925B      //Security:Keys:Full Access Key Step 1			
    #define FullAccessKeyStep2 0x925D      //Security:Keys:Full Access Key Step 2			
    
    //Direct Commands 
    #define ControlStatus 0x00
    #define SafetyAlertA 0x02
    #define SafetyStatusA 0x03
    #define SafetyAlertB 0x04
    #define SafetyStatusB 0x05
    #define SafetyAlertC 0x06
    #define SafetyStatusC 0x07
    #define PFAlertA 0x0A
    #define PFStatusA 0x0B
    #define PFAlertB 0x0C
    #define PFStatusB 0x0D
    #define PFAlertC 0x0E
    #define PFStatusC 0x0F
    #define PFAlertD 0x10
    #define PFStatusD 0x11
    #define BatteryStatus 0x12
    #define Cell1Voltage 0x14
    #define Cell2Voltage 0x16
    #define Cell3Voltage 0x18
    #define Cell4Voltage 0x1A
    #define Cell5Voltage 0x1C
    #define Cell6Voltage 0x1E
    #define Cell7Voltage 0x20
    #define Cell8Voltage 0x22
    #define Cell9Voltage 0x24
    #define Cell10Voltage 0x26
    #define Cell11Voltage 0x28
    #define Cell12Voltage 0x2A
    #define Cell13Voltage 0x2C
    #define Cell14Voltage 0x2E
    #define Cell15Voltage 0x30
    #define Cell16Voltage 0x32
    #define StackVoltage 0x34
    #define PACKPinVoltage 0x36
    #define LDPinVoltage 0x38
    #define CC2Current 0x3A
    #define AlarmStatus 0x62
    #define AlarmRawStatus 0x64
    #define AlarmEnable 0x66
    #define IntTemperature 0x68
    #define CFETOFFTemperature 0x6A
    #define DFETOFFTemperature 0x6C
    #define ALERTTemperature 0x6E
    #define TS1Temperature 0x70
    #define TS2Temperature 0x72
    #define TS3Temperature 0x74
    #define HDQTemperature 0x76
    #define DCHGTemperature 0x78
    #define DDSGTemperature 0x7A
    #define FETStatus 0x7F
    
    //Subcommands 
    #define DEVICE_NUMBER 0x0001
    #define FW_VERSION 0x0002
    #define HW_VERSION 0x0003
    #define IROM_SIG 0x0004
    #define STATIC_CFG_SIG 0x0005
    #define PREV_MACWRITE 0x0007
    #define DROM_SIG 0x0009
    #define SECURITY_KEYS 0x0035
    #define SAVED_PF_STATUS 0x0053
    #define MANUFACTURINGSTATUS 0x0057
    #define MANU_DATA 0x0070
    #define DASTATUS1 0x0071
    #define DASTATUS2 0x0072
    #define DASTATUS3 0x0073
    #define DASTATUS4 0x0074
    #define DASTATUS5 0x0075
    #define DASTATUS6 0x0076
    #define DASTATUS7 0x0077
    #define CUV_SNAPSHOT 0x0080
    #define COV_SNAPSHOT 0X0081
    #define CB_ACTIVE_CELLS 0x0083
    #define CB_SET_LVL 0x0084
    #define CBSTATUS1 0x0085
    #define CBSTATUS2 0x0086
    #define CBSTATUS3 0x0087
    #define FET_CONTROL 0x0097
    #define REG12_CONTROL 0x0098
    #define OTP_WR_CHECK 0x00A0
    #define OTP_WRITE 0x00A1
    #define READ_CAL1 0xF081
    #define CAL_CUV 0xF090
    #define CAL_COV 0xF091
    
    // Command Only Subcommands 
    #define EXIT_DEEPSLEEP 0x000E
    #define DEEPSLEEP 0x000F
    #define SHUTDOWN 0x0010
    #define BQ769x2_RESET 0x0012 //"RESET" in documentation
    #define PDSGTEST 0x001C
    #define FUSE_TOGGLE 0x001D
    #define PCHGTEST 0x001E
    #define CHGTEST 0x001F
    #define DSGTEST 0x0020
    #define FET_ENABLE 0x0022
    #define PF_ENABLE 0x0024
    #define PF_RESET 0x0029
    #define SEAL 0x0030
    #define RESET_PASSQ 0x0082
    #define PTO_RECOVER 0x008A
    #define SET_CFGUPDATE 0x0090
    #define EXIT_CFGUPDATE 0x0092
    #define DSG_PDSG_OFF 0x0093
    #define CHG_PCHG_OFF 0x0094
    #define ALL_FETS_OFF 0x0095
    #define ALL_FETS_ON 0x0096
    #define SLEEP_ENABLE 0x0099
    #define SLEEP_DISABLE 0x009A
    #define OCDL_RECOVER 0x009B
    #define SCDL_RECOVER 0x009C
    #define LOAD_DETECT_RESTART 0x009D
    #define LOAD_DETECT_ON 0x009E
    #define LOAD_DETECT_OFF 0x009F
    #define CFETOFF_LO 0x2800
    #define DFETOFF_LO 0x2801
    #define ALERT_LO 0x2802
    #define HDQ_LO 0x2806
    #define DCHG_LO 0x2807
    #define DDSG_LO 0x2808
    #define CFETOFF_HI 0x2810
    #define DFETOFF_HI 0x2811
    #define ALERT_HI 0x2812
    #define HDQ_HI 0x2816
    #define DCHG_HI 0x2817
    #define DDSG_HI 0x2818
    #define PF_FORCE_A 0x2857
    #define PF_FORCE_B 0x29A3
    #define SWAP_COMM_MODE 0x29BC
    #define SWAP_TO_I2C 0x29E7
    #define SWAP_TO_SPI 0x7C35
    #define SWAP_TO_HDQ 0x7C40
    

    作者:-今晚打老虎-

    物联沃分享整理
    物联沃-IOTWORD物联网 » BQ76942配置:与MCU通信选择软件I2C还是硬件I2C?

    发表评论