This thread has been locked.

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

[参考译文] BQ76952:BQ76952 STM32:SPI 通信不工作

Guru**** 2465890 points
Other Parts Discussed in Thread: BQSTUDIO

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

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1162223/bq76952-bq76952-stm32-spi-communication-not-working

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

您好!

我一直在尝试从 STM32412RE 与 bq759521进行通信。 我们已经检查了 MOSI、CS 和 CLK、一切看起来都很好。

但 BQ 没有响应、MISO 始终为1.8V。


硬件:

1. Breg 和 VREGIN 短接

REG18为1.8V。

随函附上代码。 请帮助我们从过去的5天开始就一直坚持这一点。

/*
 * bq.c
 *
 *  Created on: 14-Oct-2022
 *      Author: Pragnesh
 */

#include "bq.h"
#include "main.h"
#include <sys_time.h>



/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#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
/* USER CODE END PD */

/* USER CODE BEGIN PV */

UINT8 rxdata [2];
UINT8 RX_data [2] = {0x00, 0x00}; // used in several functions to store data read from BQ769x2
UINT8 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 bq_cellv [16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
float Temperature [3] = {0,0,0};
UINT16 Stack_Voltage = 0x00;
UINT16 Pack_Voltage = 0x00;
UINT16 LD_Voltage = 0x00;
UINT16 Pack_Current = 0x00;

UINT16 AlarmBits = 0x00;
UINT8 value_SafetyStatusA;  // Safety Status Register A
UINT8 value_SafetyStatusB;  // Safety Status Register B
UINT8 value_SafetyStatusC;  // Safety Status Register C
UINT8 value_PFStatusA;   // Permanent Fail Status Register A
UINT8 value_PFStatusB;   // Permanent Fail Status Register B
UINT8 value_PFStatusC;   // Permanent Fail Status Register C
UINT8 FET_Status;  // FET Status register contents  - Shows states of FETs
UINT16 CB_ActiveCells;  // Cell Balancing Active Cells

UINT8	UV_Fault = 0;   // under-voltage fault state
UINT8	OV_Fault = 0;   // over-voltage fault state
UINT8	SCD_Fault = 0;  // short-circuit fault state
UINT8	OCD_Fault = 0;  // over-current fault state
UINT8 ProtectionsTriggered = 0; // Set to 1 if any protection triggers

UINT8 LD_ON = 0;	// Load Detect status bit
UINT8 DSG = 0;   // discharge FET state
UINT8 CHG = 0;   // charge FET state
UINT8 PCHG = 0;  // pre-charge FET state
UINT8 PDSG = 0;  // pre-discharge FET state

UINT32 AccumulatedCharge_Int; // in BQ769x2_READPASSQ func
UINT32 AccumulatedCharge_Frac;// in BQ769x2_READPASSQ func
UINT32 AccumulatedCharge_Time;// in BQ769x2_READPASSQ func

UINT32 bq_timer = 0;

/* USER CODE BEGIN PV */

void delayUS(uint32_t us) {   // Sets the delay in microseconds.
	bq_timer = SysTime_getUsec() ;  // set the counter value a 0
	while (!SysTime_usecIntervalElapsed(bq_timer,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 SPI_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count) {
	// SPI Write. Includes retries in case HFO has not started or if wait time is needed. See BQ76952 Software Development Guide for examples
  uint8_t addr;
	uint8_t TX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  unsigned int i;
	unsigned int match;
	unsigned int retries = 10;

	match = 0;
  addr = 0x80 | reg_addr;

  for(i=0; i<count; i++) {
		TX_Buffer[0] = addr;
		TX_Buffer[1] = reg_data[i];

		HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_RESET);
		HAL_SPI_TransmitReceive(&hspi2, TX_Buffer, rxdata, 2,5);
		//HAL_SPI_Receive(&hspi2,rxdata, 2,5);
		HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_SET);

		while ((match == 0) & (retries > 0)) {
			delayUS(500);
			HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_RESET);
			HAL_SPI_TransmitReceive(&hspi2, TX_Buffer, rxdata, 2,5);
			//HAL_SPI_Receive(&hspi2,rxdata, 2,5);
			HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_SET);
			if ((rxdata[0] == addr) & (rxdata[1] == reg_data[i]))
				match = 1;
			retries --;
		}
    match = 0;
    addr += 1;
		delayUS(500);
  }
}


void SPI_ReadReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count) {
	// SPI Read. Includes retries in case HFO has not started or if wait time is needed. See BQ76952 Software Development Guide for examples
  uint8_t addr;
	uint8_t TX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  unsigned int i;
	unsigned int match;
	unsigned int retries = 10;

	match = 0;
  addr = reg_addr;

  for(i=0; i<count; i++) {
		TX_Buffer[0] = addr;
		TX_Buffer[1] = 0xFF;

		HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_RESET);
		HAL_SPI_TransmitReceive(&hspi2, TX_Buffer, rxdata, 2,1);
		//HAL_SPI_Receive(&hspi2,rxdata, 2,5);
		HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_SET);

		while ((match == 0) & (retries > 0)) {
			delayUS(500);
			HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_RESET);
			HAL_SPI_TransmitReceive(&hspi2, TX_Buffer, rxdata, 2,1);
			//HAL_SPI_Receive(&hspi2,rxdata, 2,5);
			HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_SET);
			if (rxdata[0] == addr) {
				match = 1;
				reg_data[i] = rxdata[1];
			}
			retries --;
		}
    match = 0;
    addr += 1;
		delayUS(500);
  }
}

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
      		SPI_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
      		SPI_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;
			SPI_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
      		SPI_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;
			SPI_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
      		SPI_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;

	SPI_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
		SPI_WriteReg(0x3E,TX_Reg,2);
		delayUS(2000);
		SPI_ReadReg(0x40, RX_32Byte, 32); //RX_32Byte is a global variable
	}
	else if (type == W) {
		//FET_Control, REG12_Control
		TX_Reg[2] = data & 0xff;
		SPI_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
		SPI_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;
		SPI_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
		SPI_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
		SPI_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
		SPI_WriteReg(command,TX_data,2);
		delayUS(2000);
	}
}


// Initlisation of BQ Module
void BQ769x2_Init() {

	// Set CS Pin
	HAL_GPIO_WritePin(SD_SS_GPIO_Port, SD_SS_Pin, GPIO_PIN_SET);
	delayUS(10000);
	// Reset BQ Registers
	CommandSubcommands(BQ769x2_RESET);
	delayUS(60000);

	// Configures all parameters in device RAM

	// Enter CONFIGUPDATE mode (Subcommand 0x0090) - It is required to be in CONFIG_UPDATE mode to program the device RAM settings
	// See TRM for full description of CONFIG_UPDATE mode
	CommandSubcommands(SET_CFGUPDATE);

	// After entering CONFIG_UPDATE mode, RAM registers can be programmed. When programming RAM, checksum and length must also be
	// programmed for the change to take effect. All of the RAM registers are described in detail in the BQ769x2 TRM.
	// An easier way to find the descriptions is in the BQStudio Data Memory screen. When you move the mouse over the register name,
	// a full description of the register and the bits will pop up on the screen.

	// 'Power Config' - 0x9234 = 0x2D80
	// Setting the DSLP_LDO bit allows the LDOs to remain active when the device goes into Deep Sleep mode
  	// Set wake speed bits to 00 for best performance
	BQ769x2_SetRegister(PowerConfig, 0x2D80, 2);

	// 'REG0 Config' - set REG0_EN bit to disable pre-regulator
	BQ769x2_SetRegister(REG0Config, 0x00, 1);

	// 'REG12 Config' - Enable REG1 with 3.3V output (0x0D for 3.3V, 0x0F for 5V)
	BQ769x2_SetRegister(REG12Config, 0xDD, 1);

	// Set SPI MISO Level to 3.3V
	BQ769x2_SetRegister(SPIConfiguration,0x60,1);

	// Swap to SPI
	CommandSubcommands(SWAP_TO_SPI);
	// swap comm mode
	BQ769x2_SetRegister(SWAP_COMM_MODE,0x0F,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.
	// The ALERT pin can be used as an interrupt to the MCU when a protection has triggered or new measurements are available
	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);

	// Enable protections in '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);

	// Enable all protections in '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);

	// Set up Cell 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);

	// delay for 10sec
	delayUS(10000);
	// Sleep mode is enabled by default. For this example, Sleep is disabled to
    // demonstrate full-speed measurements in Normal mode.
	CommandSubcommands(SLEEP_DISABLE);

	delayUS(60000); delayUS(60000); delayUS(60000); delayUS(60000);  //wait to start measurements after FETs close
}


// ********************************* 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
	  bq_cellv[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
}

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]);
}

// BQ State Machine -> All measurement functions will be called here
void bq_state_machine(void)
{

	// Check if FULLSCAN is complete. If set, new measurements are available
		// Read All Cell Voltages, Stack Voltage, Pack Voltage, Load Voltage
		BQ769x2_ReadAllVoltages();
		// Read Battery Pack Current
		Pack_Current = BQ769x2_ReadCurrent();
		// Read Cell temperature
		Temperature[0] = BQ769x2_ReadTemperature(TS1Temperature);
		// Read Cell temperature
		Temperature[1] = BQ769x2_ReadTemperature(TS3Temperature);
		// Clear Full scan bit
		DirectCommands(AlarmStatus, 0x0080, W);  // Clear the FULLSCAN bit
}

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

    您好、Ankit、

    如果 您使用的是 BQ7695201、则此部件不适用于您的应用。  与使用3.3V 逻辑的 STM32412RE 搭配使用时、MISO 将仅驱动1.8V 逻辑电平。  1.8V 过低、STWM32412RE 无法将逻辑电平寄存器设置为高电平。  我建议使用 BQ7695204、其逻辑电平为3.3V

    最棒的

    Andria

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

    Andria、您好!

    根据数据表、MISO 电平可编程为 REG1、REG1可配置为3.3V、对吧?

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

    你好、Lokesha、

    该器件是可编程的;但是、由于逻辑电平不匹配、您无法与 BQ7695201进行通信、因此无法对其进行配置。  这是一个问题22。  您需要进行通信以进行配置、但要进行配置、您需要进行通信。

    最棒的

    Andria

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

    我们将与电平转换器1.8 <-> 3.3集成以进行 OTP 编程、这是否起作用?

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

    您好、Ankit、

    我建议您使用 BQ7695204。  

    如果您使用电平转换器来实现3.3V 逻辑电平、这应该起作用、但您必须考虑一些因素。  

    图5-12. EVMUG (BQ76952EVM 用户指南(修订版 A)(TI.com)中的接口原理图显示了电平转换器的实现方式、并且 VCCA 引脚需要1.8V 电源。  由于 BQ7695201上禁用了 REG1和 REG2、因此必须使用外部电源来实现1.8V 电压。  这可能会带来麻烦、因此我建议您的系统使用 BQ7695204。

    最棒的
    Andria

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

    我们尝试了与电平转换器集成、但它不起作用。 MISO 线路始终保持高电平

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

    您好、Ankit、

    如果您无法配置系统以适应电平转换器、我建议您订购  BQ7695204、因为它将具有您所需的功能。

    最棒的

    Andria

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

    Andria、您好!

    我知道、但请注意、我们已经有100个 BQ7695201、这是基于它将直接与基于 TTL 的微控制器配合使用的假设。 您能不能帮助我们使用电平转换器完成此工作、或安排使用 bq7695204替换这些器件。

    请注意、上述详细信息在器件数据表中不清楚。

    Ankit

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

    Andria、您好!

    我们实施了电平转换技术、现在所有信号都处于1.8V 电平。 Reg1和 Reg2未通电。 Reg18输出电压为1.8V。 Regin 为4.8V。 Breg 连接到 Regin。

    请参阅随附的时钟和 MISO 信号、MISO 保持高电平、并在时钟的下降沿下降、然后再次恢复为高电平。

    时钟频率:192kHz

    MISO 通道2

    时钟-通道1

    MISO vs Clock is attached here

    为了更好地理解、我还添加了 MOSI 与 MISO。  

    MISO 应该在第一个时钟边沿开始响应、为什么器件在时钟结束时做出响应?

    2.在初始问题中附上了代码,定序是否有任何问题?

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

    大家好、Lokesha 和 Ankit、

    关于您的问题:

    安试剂盒:

    很遗憾、您订购了100个不正确的器件、并且无法实现电平转换。  如果您将原理图随电平 转换发送给我、我可以帮助调试硬件问题。   图5-12. EVMUG 中的原理图接口(我在该线程的前一篇文章中已链接)显示了如何实现电平转换器。

    此外、我将联系我们营销团队的一名成员、了解我们是否有100个 BQ7695204器件可供使用、而不是 BQ7695201。

    莱克萨:

    如果您已经实现了电平转换至1.8V 而不是高达3.3V、并且您仍在使用  STWM32412RE、则由于 MCU 使用3.3V 逻辑、并且 BQ7695201使用1.8V 逻辑、恐怕您的系统无法正常工作。  BQ7695201处理3.3V 电压不是问题、但 BQ7695201使用的1.8V 逻辑对于 MCU 而言太低。  

    您包含的代码当前不是问题。

    最棒的

    Andria

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

    Andria、您好!

    我们使用 txs0108epwr 实现了双向电平转换器。 现在、控制器侧处于3.3V 电平、到 BQ 的通信线路处于1.8V 电平。

    问题出在哪呢?

    Ankit

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

    您好、Ankit、

    如果可能、您能否尝试连接到 BQStudio?  您可以将 EVM 上的 SPI 线路连接到您的电路板。

    最棒的

    Andria

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

    大家好、Lokesha 和 Ankit、  

    我是负责此器 件的产品营销工程师、如果您无法获取 BQ7695204的其他样片、则需要留意 TI store 进行补货(建议您点击"通知我"按钮)。 如果您在采购这些器件方面还有其他问题、我建议您联系您的 TI 销售代表与我们的团队联系、以便我们可以探索其他选择。   

    谢谢、

    -Luis T

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

    我们目前还没有 EVM。 您是否在波形或代码中看到任何不起作用的错误?

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

    如果可行的话,我们可以要求加快解决。 请告诉我!

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

    您好、Ankit、

    波形实际上没有显示太多信息。 MISO 引脚将保持高电平、直到第一个事务完成(请参阅 BQ769x2软件开发指南中的示例)。 我强烈建议您使用 EVM 进行实验、因为您可以使用 BQStudio 更好地了解波形、因为您遇到了很多麻烦。

    您似乎已经从示例代码开始、这很好、但您已经对其进行了一些更改。 我建议从原始工作示例开始-您可能已经删除了一些重要步骤或等待时间。

    一般而言、使用 I2C 版本的器件(BQ7695202)将会更轻松-无需电平转换、I2C 通信非常易于理解和调试。  

    此致、

    Matt  

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

    您好、Matt、

    感谢您的回答。 根据软件开发指南、MISO 在第一个事务中将处于高电平、在第二个事务中将开始响应。

    但在我们的情况下、它始终处于高电平、在事务结束时短暂地变为低电平。

    交易之间的时间是否重要?

    Ankit

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

    是的、时间非常重要。 这就是我建议从工作代码示例开始的原因。

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

    实际上、在计时方面、我们尝试的代码没有差异。 但是、无论如何、明天让我尝试完全相同的代码并更新您