[单片机框架][drivers层][cw2015/ADC] fuelgauge 硬件电量计和软件电量计(一)
接上一篇:[单片机框架][device层] fuelgauge 电量计
CW2015 是一款超紧凑、低成本、主机侧/电池组侧、无传感电阻器的电量计量系统 IC,适用于手持和便携式设备中的锂离子 (Li+) 电池。
CW2015 跟踪 Li+ 电池的运行状况,并使用最先进的算法报告非常不同的电池化学系统(LiCoOx、聚合物锂离子、LiMnOx 等)的相对充电状态 (SOC)。
CW2015 包括一个 14 位 Sigma-Delta ADC、一个精密电压基准和内置准确温度传感器。该 IC 允许最终用户消除占用大量电路板面积的昂贵感测电阻器。如果电池 SOC 水平达到预先设定的阈值,IC 也会发出警报信号。
快速启动功能提供了对电池 SOC 进行初始估计的可能性,这也使 IC 能够位于系统侧或电池组侧,为系统制造商提供灵活性关于包装选择。
CW2015 使用 2 线 I2C 兼容串行接口,可在标准 (100 kHz) 或快速 (400 kHz) 模式下运行。
功能特性
• 应用于系统侧或电池包内
• ±3%剩余电量误差
• 14-bit模数转换器进行温度和电压检测
• 无需检流电阻
• 无库伦计累积误差
• 无学习周期
• 低电量警示中断
• 功耗
• 工作模式 15μA
• 休眠模式 0.5μA
• I2C接口
fuelgauge.c
#include "log.h"
#include "errorno.h"
#include "fuelgauge.h"
int32_t fuelgauge_driver_register(const char *name, fuelgauge_driver_t *drv) {
int32_t ret;
driver_t *pdrv;
pdrv = &(drv->drv);
pdrv->drv_data = (void*)drv;
pdrv->type = DRIVER_CLASS_FULE_GAUGE;
/* register to driver manager */
ret = driver_register(pdrv, name);
return ret;
}
fuelgauge_driver_t* fuelgauge_driver_find(const char *name) {
fuelgauge_driver_t *fuelgauge;
driver_t *pdrv;
pdrv = driver_find(name);
if (pdrv == NULL || pdrv->type != DRIVER_CLASS_FULE_GAUGE)
return NULL;
fuelgauge = (fuelgauge_driver_t*)pdrv->drv_data;
return fuelgauge;
}
int32_t fuelgauge_driver_probe(fuelgauge_driver_t *drv) {
int32_t ret;
if (drv == NULL)
return RETVAL(E_NO_DEV);
ret = driver_probe(&drv->drv);
return ret;
}
int32_t fuelgauge_driver_init(fuelgauge_driver_t *drv) {
if (drv == NULL)
return RETVAL(E_NO_DEV);
if (drv->ops.init)
return drv->ops.init();
return RETVAL(E_NOT_SUPPORT);
}
int32_t fuelgauge_driver_get_info(fuelgauge_driver_t *drv, fuelgauge_info_t *info) {
if (drv == NULL)
return RETVAL(E_NO_DEV);
if (drv->ops.get_info)
return drv->ops.get_info(drv, info);
return RETVAL(E_NOT_SUPPORT);
}
int32_t fuelgauge_driver_set_work_mode(fuelgauge_driver_t *drv, fuelgauge_work_mode_t mode) {
if (drv == NULL)
return RETVAL(E_NO_DEV);
if (drv->ops.set_work_mode)
return drv->ops.set_work_mode(drv, mode);
return RETVAL(E_NOT_SUPPORT);
}
int32_t fuelgauge_driver_set_batt_type(fuelgauge_driver_t *drv, uint32_t type) {
if (drv == NULL)
return RETVAL(E_NO_DEV);
if (drv->ops.set_batt_type)
return drv->ops.set_batt_type(drv, type);
return RETVAL(E_NOT_SUPPORT);
}
int32_t fuelgauge_driver_set_charge_state(fuelgauge_driver_t *drv, fuelgauge_charge_state_t state, uint32_t current) {
if (drv == NULL)
return RETVAL(E_NO_DEV);
if (drv->ops.set_charge_state)
return drv->ops.set_charge_state(drv, state, current);
return RETVAL(E_NOT_SUPPORT);
}
fuelgauge.h
#ifndef __FUEL_GAUGE_H__
#define __FUEL_GAUGE_H__
#include "typedefs.h"
#include "driver.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
FUELGAUGE_SET_CHARGER_STATE,
FUELGAUGE_SET_CHARGER_CYCLE,
FUELGAUGE_SET_BATTERY_TYPE,
FUELGAUGE_SET_WORK_MODE,
FUELGAUGE_SET_HEALTH,
FUELGAUGE_SET_TEMPE,
} fuelgauge_cmd_t;
typedef struct
{
fuelgauge_cmd_t cmd;
uint8_t state; /* charge state */
uint8_t mode; /* work mode */
uint16_t ocv; /* open circuit voltage */
uint16_t ccv; /* closed circuit voltage */
uint16_t current; /* current */
uint8_t soc; /* state of charge */
uint8_t temp; /* temperature of battery */
uint16_t soh; /* state of health */
uint16_t cycle; /* cycle of charging */
uint16_t fcc; /* full charge capacity */
} fuelgauge_info_t;
typedef enum
{
FUELGAUGE_WORK_MODE_NORMAL,
FUELGAUGE_WORK_MODE_SLEEP,
FUELGAUGE_WORK_MODE_SHUTDOWN,
} fuelgauge_work_mode_t;
typedef enum
{
FUELGAUGE_CHARGE_STATE_DISCHARGE,
FUELGAUGE_CHARGE_STATE_CHARGE,
} fuelgauge_charge_state_t;
typedef enum
{
FUELGAUGE_IOCTRL_CMD_WORK_MODE,
FUELGAUGE_IOCTRL_CMD_CHARGE_STS,
} fuelgauge_ioctrl_cmd_t;
typedef struct fuelgauge
{
fuelgauge_ioctrl_cmd_t cmd;
uint32_t argv;
} fuelgauge_cmd_argv_t;
typedef struct fuelgauge_driver_s fuelgauge_driver_t;
typedef struct fuelgauge_ops_s
{
int32_t (*init)(void);
int32_t (*get_info)(fuelgauge_driver_t *drv, fuelgauge_info_t *data);
int32_t (*set_batt_type)(fuelgauge_driver_t *drv, uint32_t type);
int32_t (*set_charge_state)(fuelgauge_driver_t *drv, fuelgauge_charge_state_t state, uint32_t current);
int32_t (*set_work_mode)(fuelgauge_driver_t *drv, fuelgauge_work_mode_t mode);
int32_t (*set_power)(fuelgauge_driver_t *drv, fuelgauge_work_mode_t mode);
} fuelgauge_ops_t;
struct fuelgauge_driver_s
{
driver_t drv;
fuelgauge_ops_t ops;
};
int32_t fuelgauge_driver_register(const char *name, fuelgauge_driver_t *drv);
fuelgauge_driver_t* fuelgauge_driver_find(const char *name);
int32_t fuelgauge_driver_probe(fuelgauge_driver_t *drv);
int32_t fuelgauge_driver_init(fuelgauge_driver_t *drv);
int32_t fuelgauge_driver_get_info(fuelgauge_driver_t *drv, fuelgauge_info_t *info);
int32_t fuelgauge_driver_set_batt_type(fuelgauge_driver_t *drv, uint32_t type);
int32_t fuelgauge_driver_set_charge_state(fuelgauge_driver_t *drv, fuelgauge_charge_state_t state, uint32_t current);
int32_t fuelgauge_driver_set_work_mode(fuelgauge_driver_t *drv, fuelgauge_work_mode_t mode);
#ifdef __cplusplus
}
#endif
#endif // __FUEL_GAUGE_H__
下一篇:[单片机框架][drivers层][cw2015] fuelgauge 硬件电量计(二)
[单片机框架][drivers层][ADC] fuelgauge 软件电量计(二)