主题中讨论的其他器件:、 EV2400、 BQSTUDIO
工具与软件:
主题:BQ25731的电池充电控制、状态更新、电池电压和 I2C 通信问题
我在使用时目前面临几个问题 BQ25731 I2C 上的电池管理系统。 这些问题阻碍了系统正常运行、我需要帮助解决这些问题。
1.充电未启用
我无法通过 I2C 命令启用充电。 以下命令:
sudo i2cset -y 1 0x6b 0x10 0x01 #启用充电
始终失败并显示错误消息:
错误:写入失败
尽管进行了多次尝试并验证了寄存器地址和数据是否正确、但仍然不启用充电。
2.充电在一段时间后被禁用
即使我设法启用充电、它也会在一段时间后被禁用、没有任何明确的指示或触发信号。 这表明寄存器设置或硬件配置可能出现问题、从而可能导致系统自动禁用充电。
3.无法读取电池状态和电压更新
尝试读取电池电压和状态寄存器时、我始终会遇到以下问题:
电池电压和电量百分比未按预期更新。
电池状态和电压寄存器要么返回不正确的值、要么根本不提供更新。
0x2C (电池电压)等特定寄存器会返回恒定值(例如0x00)、这可能表明存在通信问题或寄存器设置不正确。
4.连续远程 I/O 错误
我在尝试读取或写入 I2C 总线时遇到持续远程 I/O 错误、尤其是在访问与电池状态和电压相关的某些寄存器时。 这些错误发生在基本 I2C 操作(例如读取或写入电池管理 IC)期间。
这是代码
#include
#include
#include
#include //切换到 pigpio 以实现更好的 GPIO 控制
#include
#include
#include
#define BQ25731_ADDR 0x6b // BQ25731的 I2C 地址
#define BQ25731_CHARGE_ON 0x01 //开启充电
#define BQ25731_CHARGE_OFF 0x00 //关闭充电
#define BQ25731_STATUS 0x20 //电池状态寄存器
#define BQ25731_CONTROL 0x23 //电池控制寄存器
#define BQ25731_INPUTVOLTAGE 0x0A //输入电压寄存器
#define BQ25731_CHARGE_CURRENT 0x03 //电池充电电流寄存器
#define BQ25731_CHARGE_VOLTAGE 0x05 //电池充电电压寄存器
#define BQ25731_OTGVOLTAGE 0x07 //过压保护寄存器
#define BQ25731_OTGCURRENT 0x09 //过流保护寄存器
#define MAX_BATTERY_PERSISTENT 100 //最大电池百分比
#define LOW_BATTERY_THRESHOLD 20 //低电池警告阈值(以百分比表示)
#define MIN_BATTERY_VOLTAGE 10.5 //关闭前的最低电压(适用于铅酸电池)
#define LEAD_ACID_MAX_VOLTAGE 14.4 //铅酸电池的最大充电电压
#define LEAD_ACID_MIN_VOLTAGE 10.5 //关闭前的最小电压(适用于铅酸电池)
#define LEAD_ACID_CHARGE_CURRENT 1.0 //充电电流(例如、10Ah 电池为1A)
#define LEAD_ACID_OVER_VOLTAGE 14.7 //过压保护阈值(对于铅酸电池)
#define LEAD_ACID_OVER_CURRENT 2.0 //过流保护阈值(单位为安培)
int fd;// I2C 的文件描述符
int battery_per;//电池百分比
float battery_voltage;//电池电压(根据 IC 寄存器计算)
char buffer[3];//用于 I2C 通信的缓冲器
void initBQ25731 (void);
int battery_status (float battery_voltage);
void monitor_battery_status (void);
void enable_charging (void);
void disable_charging (void);
悬空 READ_BATTERY_VOLTAGE (void);
void set_battery_charge_voltage (float voltage);
void SET_BATTERY_CHARGE_CURRENT (float current);
void SET_VOLTAGE_PROTECTION (浮动电压);
void set_overCurrent_protection (浮点电流);
void initBQ25731 (){
如果((FD = open ("/dev/i2c-1、O_RDWR))< 0){
perror ("Failed to open the I2C bus");
退出(1);
}
如果(ioctl (FD、I2C_SLAVE、BQ25731_ADDR)< 0){
perror ("Failed to access BQ25731 IC (访问 BQ25731电源失败)");
退出(1);
}
}
int battery_status (float battery_voltage){
INT soc = 0;
if (battery_voltage >= 12.7){
soc = 100;
否则、如果(BATTERY_VOLTAGE >= 12.5 && BATTERY_VOLTAGE < 12.7){
soc = 75;
否则、如果(BATTERY_VOLTAGE >=12.3 && BATTERY_VOLTAGE <12.5)
soc = 50;
否则、如果(BATTERY_VOLTAGE >=12.0 & BATTERY_VOLTAGE >12.3)
soc = 25;
否则、如果(BATTERY_VOLTAGE < 11.0){
soc = 0;
}
返回 soc;
}
void monitor_battery_status (){
BATTERY_STATUS (BATTERY_VOLTAGE);
如果(BATTERY_PER < LOW_BATTERY_THRESHOLD){
printf ("警告:电池低于%d%%\n"、LOW_BATTERY_THRESHOLD);
enable_charging();
}否则、如果(BATTERY_PER >= MAX_BATTERY_PERSISTENT){
printf ("电池已充满电。\n");
disable_charging();
}
}
void enable_charging(){
Buffer[0]= BQ25731_control;
Buffer[1]= BQ25731_Charge_on;
如果(write (fd、buffer、2)!= 2){
perror ("无法启用充电");
其他{
printf ("已启用充电。\n");
}
}
void disable_charging(){
Buffer[0]= BQ25731_control;
Buffer[1]= BQ25731_CHARGE_OFF;
如果(write (fd、buffer、2)!= 2){
perror ("无法禁用充电");
其他{
printf ("已禁用充电。\n");
}
}
void set_battery_charge_voltage (float voltage){
int voltage_value =(int)(voltage * 10);
Buffer[0]= BQ25731_CHARGE_VOLTAGE;
Buffer[1]=(VOLTAGE_VALUE >> 8)和0xFF;
Buffer[2]= VOLTAGE_VALUE & 0xFF;
如果(write (fd、buffer、3)!= 3){
perror ("未能设置充电电压");
其他{
printf ("充电电压设置为%.2fv\n"、电压);
}
}
void set_battery_charge_current (float current){
int current_value =(int)(current * 10);
Buffer[0]= BQ25731_Charge_Current;
Buffer[1]= Current_Value;
如果(write (fd、buffer、2)!= 2){
perror ("未能设置充电电流");
其他{
printf ("充电电流设置为%.2fa\n"、Current);
}
}
void SET_VOLTAGE_PROTECTION (浮动电压){
int voltage_value =(int)(voltage * 10);
Buffer[0]= BQ25731_OTGVOLTAGE;
Buffer[1]=(VOLTAGE_VALUE >> 8)和0xFF;
Buffer[2]= VOLTAGE_VALUE & 0xFF;
如果(write (fd、buffer、3)!= 3){
perror ("未能设置过压保护");
其他{
printf ("过压保护设置为%.2fv\n"、电压);
}
}
void set_overCurrent_protection (浮点电流){
int current_value =(int)(current * 10);
Buffer[0]= BQ25731_OTGCURRENT;
Buffer[1]= Current_Value;
如果(write (fd、buffer、2)!= 2){
perror ("未能设置过流保护");
其他{
printf ("过流保护设置为%.2fa\n"、current);
}
}
float read_battery_voltage(){
Buffer[0]= 0x2C;// VBAT 寄存器地址(低字节)
如果(write (fd、buffer、1)!= 1){
perror ("写入电池电压寄存器失败");
返回-1.0;
}
if (read (fd、buffer、2)!= 2){
perror ("读取电池电压失败");
返回-1.0;
}
INT VOLTAGE_mV =(BUFFER[1]<< 8)| BUFFER[0];//高字节<< 8 |低字节
return voltage_mV/1000.0;//以伏特为单位的返回电压
}
int main(){
if (gpioInitialize ()< 0){//初始化 pigpio 库
fprintf (stderr、"pigpio 初始化失败\n");
返回1;
}
initBQ25731 ();
SET_BATTERY_CHARGE_VOLTAGE (LEAD_ACID_MAX_VOLTAGE);
SET_BATTERY_CHARGE_CURRENT (LEAD_ACID_CHARGE_CURRENT);
SET_VOLTAGE_PROTECTION (LEAD_ACID_OVER_VOLTAGE);
SET_OVERRIDA_PROTECTION (LEAD_ACID_OVER_CURRENT);
unsigned long last_check_time = gpioTick ();
while (1){
unsigned long current_time = gpioTick ();
if (current_time - last_check_time >= 1000000){
MONITOR_BATTERY_STATUS();
last_check_time = current_time;
}
BATTERY_PER = BATTERY_STATUS (BATTERY_VOLTAGE);
printf ("电池百分比:%d%%\n"、battery_per);
BATTERY_VOLTAGE = READ_BATTERY_VOLTAGE ();
如果(BATTERY_VOLTAGE!=-1){
printf ("电池电压:%.2fv\n"、battery_voltage);
如果(BATTERY_VOLTAGE < LEAD_ACID_MIN_VOLTAGE){
printf ("警告:电池电压过低! 禁用充电。\n");
disable_charging();
}
}
usleep(500000 );//休眠0.5秒以避免高 CPU 使用率
}
gpioTerminate();
返回0;
}
///这里我们主要面临着 Read_battery_voltage()、enable_charging,disable_charging 的问题