主题中讨论的其他器件: BQSTUDIO、 EV2400
您好的支持团队、
根据 BQ40Z80的技术参考手册,我 正在尝试通过 ManufacturerBlockAccess()方法读取 Chemical ID()(0x0006)。 遗憾的是、写入命令失败、会生成超时错误。 请查看以下问题详细信息列表:
硬件信息:
BMS IC:BQ40Z80
MCU : ESP32.
方法:A
步骤1:初始化 ESP32 I2C 驱动程序
步骤2:SMBus 的对齐帧格式
步骤3:通过 smbus 写入数据:{0x44、0x02、0x06、0x00}、即使我尝试了各种超时、也会产生超时错误。
步骤4:通过 smbus 读取数据:{0x44}由于写入失败、它返回了{0x54、 0x00、0xa1、0x01、0x00、 0x00}。
方法: b.
步骤1:将 EV2400模块 与 BQ40Z80配合使用并使用 bqStudio 进行访问
步骤2: 我能够编写块请求并获得正确的响应。
我很好奇地知道、我在 C 代码中的错误发生在哪里。 我还能够读取一些具有适当值的寄存器。 在这里、我发布 c 代码供您参考:
esp_err_t smbus_write_block (const smbus_info_t * smbus_info、uint8_t 命令、uint8_t *数据、uint8_t len)
{
//协议:[s | ADDR | WR | AS |命令| AS | LEN | AS | DATA-1 | AS | DATA-2 | AS ... | DATA-LEN | AS | P]
esp_err_t err = esp_fail;
if (_Is_init (smbus_info)&& data)
{
i2C_cmd_handle_t cmd = i2c_cmd_link_create ();
I2C_MASTER_START (cmd);
i2C_MASTER_WRITE_BYTE (cmd、smbus_info->address << 1 | WRITE_BIT、ACK_CHECK);
I2C_MASTER_WRITE_BYTE (cmd、command、ACK_CHECK);
i2C_MASTER_WRITE_BYTE (cmd、len、ACK_CHECK);
对于(size_t i = 0;i < len;+i)
{
I2C_MASTER_WRITE_BYTE (cmd、DATA[i]、ACK_CHECK);
}
I2C_MASTER_STOP (cmd);
ERR =_check_i2c_error (i2c_main_cmd_begin (smbus_info->i2c_port、cmd、smbus_info->timeout));
I2C_cmd_link_delete (cmd);
}
退货错误;
}
esp_err_t smbus_read_block (const smbus_info_t * smbus_info、uint8_t 命令、uint8_t * data、uint8_t * len)
{
//协议:[s | ADDR | WR | AS |命令| AS | SR | ADDR | RD | AS |镜头| A | DATA-1 | A | DATA-2 | A ... | DATA-LEN | N | P]
esp_err_t err = esp_fail;
如果(_Is_init (smbus_info)&& data && len)
{
i2C_cmd_handle_t cmd = i2c_cmd_link_create ();
I2C_MASTER_START (cmd);
i2C_MASTER_WRITE_BYTE (cmd、smbus_info->address << 1 | WRITE_BIT、ACK_CHECK);
I2C_MASTER_WRITE_BYTE (cmd、command、ACK_CHECK);
I2C_MASTER_START (cmd);
i2C_MASTER_WRITE_BYTE (cmd、smbus_info->address << 1 | Read_bit、ACK_CHECK);
uint8_t slave_len = 0;
I2C_MASTER_READ_BYTE (cmd、&SLAVE_Len、ACK_VALUE);
ERR =_check_i2c_error (i2c_main_cmd_begin (smbus_info->i2c_port、cmd、smbus_info->timeout));
I2C_cmd_link_delete (cmd);
如果(错误!= ESP_OK)
{
*len = 0;
退货错误;
}
如果(slave_len >*len)
{
ese_lGW (TAG,"从数据长度%d 超过数据长度%d 字节",slave_len,*len);
Slave_len =* len;
}
cmd = i2c_cmd_link_create();
对于(size_t i = 0;i < slave_len - 1;+i)
{
I2C_MASTER_READ_BYTE (cmd、&DATA[i]、ACK_VALUE);
}
I2C_MASTER_READ_BYTE (cmd、&DATA[SLAVE_Len - 1]、NACK_VALUE);
I2C_MASTER_STOP (cmd);
ERR =_check_i2c_error (i2c_main_cmd_begin (smbus_info->i2c_port、cmd、smbus_info->timeout));
I2C_cmd_link_delete (cmd);
如果(错误==ESP_OK)
{
*len = slave_len;
}
其他
{
*len = 0;
}
}
退货错误;
}
调用上述 API:
INT8_t buff [2]={0x06、0x00};
uint8_t data[32U]={0U};
uint8_t 长度;
if (ESP_OK!= smbus_write_block (&smbusInfo、0x44、buff、2))
{
esg_loge (TAG、"smbus_write_word SMBus"失败);
}
长度= 6;
if (ESP_OK!= smbus_read_block (&smbusInfo、0x44、数据、长度))
{
esg_loge (TAG、"smbus_read_block SMBus"失败);
}
其他
{
print_data (数据、长度);
}
上述代码片段的输出:
E (20351) smbus:I2C 超时
E (20351) smbus:smbus_write_word SMBus 失败
I (20371) smbus:RX 数据:
I (20371) smbus:0x54
I (20371) smbus:0x00
I (20371) smbus:0xa1
I (20371) smbus:0x01
I (20371) smbus:0x00
I (20371) smbus:0x00
SMBus 代码参考: github.com/.../esp32-smbus