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自行休眠现象
文章目录
前言
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
作者:-今晚打老虎-