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.

[参考译文] BQ27441-G1:难以写入新容量值

Guru**** 2493175 points


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

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1488406/bq27441-g1-writing-new-capacity-value-difficulties

器件型号:BQ27441-G1

工具与软件:

您好!

我们正在开发一种便携式产品、并计划使用 BQ27441作为电量监测计来监测电池健康状况。

我们没有 EV2300/2400、而是使用 Raspberry PI 对系统进行原型设计、因为它易于通过 i2c 进行通信。 我正在使用 SMBus 发送信号。

我可以读取电压、温度和电流消耗、它很准确、并且会随环境而变化。

我相信我遵循 TRM 中关于更新新产能的说法是正确的。 我有下面的原型代码、以防任何人需要代码的快速入门参考、同时让比我更了解的人更容易提供任何输入。 非常感谢您提供任何意见和反馈。 非常感谢。

import time
from smbus2 import SMBus

# Define I2C address and registers
BQ27441_I2C_ADDR = 0x55  # Default I2C address
CONTROL_REG = 0x00
FLAGS_REG = 0x06
BLOCK_DATA_CONTROL = 0x61
DATA_BLOCK_CLASS = 0x3E
DATA_BLOCK_OFFSET = 0x3F
CHECKSUM_REG = 0x60
SOFT_RESET = 0x0042

# Battery information registers
DESIGN_CAPACITY_REG = 0x4A  # Accessed via RAM update (Subclass 82)
REMAINING_CAPACITY_REG = 0x0A
STATE_OF_CHARGE_REG = 0x1C
VOLTAGE_REG = 0x04
TEMPERATURE_REG = 0x02  # Needs conversion to Celsius

# Unseal and sealing keys
UNSEAL_KEY = [0x80, 0x00, 0x80, 0x00]
SEAL_KEY = [0x20, 0x00]

# Subclass ID for Design Capacity
DESIGN_CAPACITY_CLASS = 0x52  # Subclass 82

# I2C bus number (modify as needed)
I2C_BUS = 1

def write_word(bus, reg, value):
    """Write a word (2 bytes) to a register."""
    bus.write_word_data(BQ27441_I2C_ADDR, reg, value)

def write_bytes(bus, reg, values):
    """Write multiple bytes to a register."""
    bus.write_i2c_block_data(BQ27441_I2C_ADDR, reg, values)

def read_word(bus, reg):
    """Read a word (2 bytes) from a register."""
    return bus.read_word_data(BQ27441_I2C_ADDR, reg)

def read_bytes(bus, reg, length):
    """Read multiple bytes from a register."""
    return bus.read_i2c_block_data(BQ27441_I2C_ADDR, reg, length)

def calculate_checksum(data):
    """Calculate checksum according to BQ27441 TRM."""
    checksum = 255 - (sum(data) % 256)
    return checksum & 0xFF

def read_battery_info():
    """Read and print battery parameters."""
    with SMBus(I2C_BUS) as bus:
        capacity = read_word(bus, DESIGN_CAPACITY_REG)
        remaining_capacity = read_word(bus, REMAINING_CAPACITY_REG)
        soc = read_word(bus, STATE_OF_CHARGE_REG) & 0xFF  # SOC is a percentage
        voltage = read_word(bus, VOLTAGE_REG)
        temperature = read_word(bus, TEMPERATURE_REG)  # Needs conversion

        # Convert temperature (reported in 0.1 Kelvin) to Celsius
        temperature_c = (temperature * 0.1) - 273.15

        print("\nBattery Information:")
        print(f"- Design Capacity: {capacity} mAh")
        print(f"- Remaining Capacity: {remaining_capacity} mAh")
        print(f"- Battery Percentage: {soc}%")
        print(f"- Voltage: {voltage} mV")
        print(f"- Temperature: {temperature_c:.2f} °C\n")

def update_capacity(new_capacity):
    """Update the fuel gauge capacity and read battery info."""
    with SMBus(I2C_BUS) as bus:
        print("Unsealing device...")
        write_bytes(bus, CONTROL_REG, UNSEAL_KEY[:2])
        time.sleep(0.5)
        write_bytes(bus, CONTROL_REG, UNSEAL_KEY[2:])
        time.sleep(0.5)

        print("Entering config update mode...")
        write_bytes(bus, CONTROL_REG, [0x13, 0x00])
        time.sleep(0.5)

        # Wait until bit 4 is set in FLAGS_REG
        while not (read_word(bus, FLAGS_REG) & 0x0010):
            time.sleep(0.5)

        print("Enabling block RAM update...")
        write_bytes(bus, BLOCK_DATA_CONTROL, [0x00])

        print("Selecting Design Capacity subclass...")
        write_bytes(bus, DATA_BLOCK_CLASS, [DESIGN_CAPACITY_CLASS])

        print("Selecting first 32-byte block...")
        write_bytes(bus, DATA_BLOCK_OFFSET, [0x00])

        print("Reading initial checksum...")
        old_checksum = read_bytes(bus, CHECKSUM_REG, 1)[0]

        print("Reading current settings...")
        block_data = read_bytes(bus, 0x40, 32)

        # Update design capacity (assume it's stored at offset 10-11)
        block_data[10] = new_capacity & 0xFF
        block_data[11] = (new_capacity >> 8) & 0xFF

        print("Writing new values...")
        for i in range(len(block_data)):
            write_bytes(bus, 0x4C + i, [block_data[i]])
            time.sleep(0.01)  # Small delay for stability

        print("Calculating new checksum...")
        new_checksum = calculate_checksum(block_data)
        write_bytes(bus, CHECKSUM_REG, [new_checksum])

        time.sleep(2)  # Wait 2s

        print("Verifying new checksum...")
        updated_checksum = read_bytes(bus, CHECKSUM_REG, 1)[0]
        print("Updated Checksum  "+str(updated_checksum))
        print("New Checksum " + str(new_checksum))
        if new_checksum == updated_checksum:
            print("Checksum matches. Applying soft reset...")
            write_bytes(bus, CONTROL_REG, [SOFT_RESET & 0xFF, (SOFT_RESET >> 8) & 0xFF])
        else:
            print("Checksum mismatch! Update failed.")
            return

        time.sleep(0.5)

        print("Sealing the device...")
        write_bytes(bus, CONTROL_REG, SEAL_KEY)

        print("Update complete!")

    # After updating, print battery information
    read_battery_info()

# Example usage: Set new capacity to 3000mAh
update_capacity(3000)

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

    您好、Vincens:

    此问题已分配、我们将在可能的情况下予以解答。

    谢谢!
    艾伦

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

    我已经解决了这个问题。 我可以写入适当的值和读取所需的参数、一切都是正确的。 我必须采用一些 CPU 拉伸技术、因为写入 FAST 也会导致问题。 如果您有这个问题、请随时与我们联系。