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.

[参考译文] BQ40Z50:需要有关使用 I2C 上的微控制器初始化芯片的帮助

Guru**** 2535150 points
Other Parts Discussed in Thread: BQ40Z50, BQ24074, EV2400, GPCCHEM

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

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1189534/bq40z50-need-help-initializing-the-chip-using-a-microcontroller-over-i2c

器件型号:BQ40Z50
主题中讨论的其他器件: BQ24074EV2400GPCCHEM

您好!  

我们在系统中使用 BQ40Z50、ESP32微控制器和 BQ24074充电器。  

在制造 QA/测试期间、我们将进入 BQ40Z50、所有这些都处于"永久故障"状态、不确定如何解决此问题。 例如,PFStatus()命令返回 0X1717171717 (位的十六进制表示),如果我正确读取技术参考,它几乎可以构成每个触发的 PF 保护。  

电池状态显示:  
SEC0:1
第1节:1.
禁用 CHG:0  
DSG-DISABLE:0
Perm 失败:1、
关断:1.
CHG FET:1.
DSG FET:1.


断开/重新连接电池或电源无法解决此问题  


问题:

1.我是否遗漏了一些关键的东西?  

2.在生产中、引导时应发送哪些 SBS 命令以正确初始化 BQ40Z50?  

3.在制造 /QA 测试中、在发货前应发送哪些命令来初始化 BQ40Z50?  


谢谢、
Amir

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

    Amir、您好!

    您能否将.gg 文件与配置信息共享?

    监测计为 SMBus 而不是 I2C、有时当接收到代码0x171717时、意味着您尝试使用 I2C 而不是 SMBus。

    此致、

    Wyatt Keller

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

    您好!  

    我们使用焊接芯片的定制 PCB、通过 I2C 与 ESP32进行通信  
    这些值是"i"m 从 I2C 线路上拉取的值、但我以十六进制格式共享以节省空间  

    如果您需要电路原理图、请告诉我  

    我还可以共享用于与 BQ40Z50通信的代码

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

    Amir、您好!

    您必须首先使用 EV2400配置监测计以上传包含专有信息的 CHEM ID (EV2400是获取包含 CHEM ID 的黄金映像的唯一方法)

    如果您没有完成正确的配置步骤、可能会导致监测计出现许多问题。

    1. 使用 GPCCHEM 查找您的化学 ID
    2. 上传化学 ID
    3. 执行学习周期
    4. 配置任何其他特定于应用的保护和监测设置
    5. 导出最终黄金映像以在生产中上传

    我看到有使用 ESP32的 SMBus 库、如果您使用 I2C 进行通信、您将获得错误的数据。

    请参考此应用手册、其中讨论了不兼容的原因: https://www.ti.com/lit/pdf/sloa132

    此致、

    Wyatt Keller

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

    谢谢、Wyatt

    我将在 此处使用技术参考:https://www.ti.com/lit/ug/sluua43a/sluua43a.pdf 
    哪些状态表明我可以使用 I2C 与电量监测计进行通信?  
    它指出器件提供 I2C 从器件地址和 SMBus 从器件地址?  

    1) 1)如何立即禁用保护以方便 QA 测试? 电池组本身具有冗余 BMS

    2) 2)如何调整设置寄存器? 我看到我想要更改的所有设置、例如在数据闪存值部分中禁用 TS1-4、但我不确定使用什么命令写入它们。 还是直接写入"寄存器起始地址"?  

    3) 3)当我尝试在 CHG_EN 或 DSG_EN 之后发送0x0022 (FET_EN)时、似乎不会发生任何情况、尽管 FET_EN 位翻转为1  
    下面是我从状态寄存器中读取的内容:  
    电池状态: 0X5AD7 (0110 1101 0101 0111)
    运行状态: 0XE8E86D54
    制造状态: 0X6D57
    PF 状态: 0X83836D53

    操作和制造状态建议:  

    SEC0:1
    第1节:0     
    XCHG:1  
    XDSG:1  
    PERM 失败:0
    关断:1.
    CHGFET:1.
    DSGFET:0

    FET_EN:1.

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

    更新、  

    我想我可以通过 TRM 中的说明写入 DataFlash、网址 是:www.ti.com/.../sluua43a.pdf
    12.1.60 0x4000–0x5FFF 数据闪存访问()

    通过我使用的定制 I2C 总线、健全检查器件是否按预期响应的快速方法是什么?

    作为参考、这里是我用于访问的一些代码、FuelGaugeChip 是 用于实际 i2c 通信的 Adafruit BusIO 对象  

    uint32_t FuelGauge::executeMfgrCommand(const uint8_t* desired_command, uint8_t numBytes) {
      // Create a buffer to store the command data
      uint8_t cmd_data[2] = {desired_command[1], desired_command[0]};
      LUMO_LOGD("Sending Command: %#X", cmd_data[1]);
      // Create a buffer to store the data returned from fuel gauge
      uint8_t  received_data[numBytes];
      uint32_t result{0};
    
      // Execute the command
      FuelGaugeChip.write_then_read(cmd_data, sizeof(cmd_data), received_data, sizeof(received_data), true);
      delay(500);
      // The data is returned as a 16-bit value in two bytes, with the
      // high byte in the first element of the received_data array and the low
      // byte in the second element. To combine these two bytes into a single
      // 16-bit value, we can use bit shifting and bitwise OR operations.
      if (numBytes == 2) {
        return (result |= bytesToInt16(received_data));
      } else if (numBytes == 4) {
        return bytesToInt32(received_data);
      } else if (numBytes == 1) {
        return (result |= received_data[0]);
      } else {
        LUMO_LOGD("Error parsing values from fuel_gauge");
        return 0;
      }
    }
    
    // Execute a single word command on the BQ40Z50 and read a specified number of bytes
    // Returns the data read from the BQ40Z50
    uint32_t FuelGauge::executeCommand(const uint8_t command, uint8_t numBytes) {
      // Create a buffer to hold the data read from the BQ40Z50
      uint8_t* data = new uint8_t[numBytes];
      uint32_t result{0};
      // Create a buffer to store the command data
      // TODO: support longer cmd_data for seal/unseal operations?
      uint8_t cmd_data[1] = {command};
      LUMO_LOGD("Sending Command: %#x", cmd_data[0]);
      // Use the write_then_read() method to execute the command
      FuelGaugeChip.write_then_read(cmd_data, sizeof(cmd_data), data, numBytes, 0x00);
      delay(500);
      if (numBytes == 2) {
        return (result |= bytesToInt16(data));
      } else if (numBytes == 4) {
        return bytesToInt32(data);
      } else if (numBytes == 1) {
        return (result |= data[0]);
      } else {
        LUMO_LOGE("Error parsing values from fuel_gauge!");
        return 0;
      }
    }
    
    void FuelGauge::updateTemperatureEnable(bool enable) {
      // Create a buffer to hold the command data
      uint8_t cmd_data[4] = {0x40, 0x4E, 0x49, enable ? 0x01 : 0x00};
      // Send the command
      blockWrite(cmd_data, sizeof(cmd_data));
    }
    
    void FuelGauge::blockWrite(uint8_t* data, uint8_t numBytes) {
      uint32_t block;
      if (numBytes == 2) {
        block = bytesToInt16(data);
      } else if (numBytes == 4) {
        block = bytesToInt32(data);
      } else if (numBytes == 1) {
        block = data[0];
      } else {
        LUMO_LOGE("Error parsing input values for Block Write!");
        return;
      }
      LUMO_LOGD("\n\t\t Writing %#X", block);
      FuelGaugeChip.write(data, numBytes);
    }
    // Convert a buffer of bytes into a 16-bit integer
    uint16_t FuelGauge::bytesToInt16(uint8_t* data) {
      return ((uint16_t)data[1] << 8) | (uint16_t)data[0];
    }
    
    // Convert a buffer of bytes into a 32-bit integer
    int32_t FuelGauge::bytesToInt32(uint8_t* data) {
      return ((uint32_t)data[3] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[1] << 8) | (uint32_t)data[0];
    }

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

    Amir、您好!

    您能否提供使用 I2C 参考测量仪表的部分的片段或段号? 这可能是 TRM 中的错误。

    BQ40Z50使用 SMBus 进行通信、还可以向充电器发送 SMBus 充电电压和充电电流。 它不使用 I2C、并且不会与所有命令兼容(如上一个响应中链接的应用手册中所述)。 也许对于一些更基本的命令、我相信您可以围绕 I2C 库创建包装函数以使其正常工作、但我们无法帮助编写驱动程序。

    我建议您使用通信数据包结构来调试这种类型的问题的最佳方法是使用 EV2400与逻辑分析仪、然后使用代码并比较这两者。

    此致、

    Wyatt Keller