## 一、电源监控的核心挑战 在嵌入式产品中,电源监控不仅是读取几个电压值那么简单。电池供电设备面临三大痛点: - **精度不足**:ADC参考电压漂移、分压电阻误差导致电压测量偏差超过5%。 - **动态响应慢**:负载突变时,电压跌落无法及时捕获,可能触发误复位。 - **电量估算不准**:简单电压查表法在锂电池放电平台期误差极大,而纯库仑计法又受温度、老化影响。 因此,一个实用的电源监控方案需要硬件采样电路、高精度ADC/传感器、以及智能估算算法三者协同。 ## 二、硬件采样电路设计 ### 电压采样:分压电阻与高阻输入 对于MCU内置ADC(通常0~3.3V),需将电池电压(如4.2V~3.0V)分压到安全范围。 ```c // 分压计算:Vout = Vin * R2 / (R1+R2) // 例:R1=100kΩ, R2=100kΩ,则Vout = Vin/2,最大2.1V(安全) // 注意:选用1%精度电阻,并联0.1uF电容滤除高频噪声 ``` **关键点**: - 分压电阻阻值不宜过小(避免漏电),也不宜过大(增加ADC源阻抗,导致采样误差)。建议10k~100kΩ。 - 若MCU ADC输入阻抗较低,需加运放跟随器(如OPA333)隔离。 ### 电流采样:低侧与高侧检测 - **低侧检测**:采样电阻串联在GND回路,简单但会抬高GND电位,影响系统。 - **高侧检测**:采样电阻在电源正极,需差分放大器或专用电流检测芯片(如INA226)。 推荐使用**INA226**(TI),它集成16位ADC、I2C接口,支持0~36V共模电压,可同时测量电压和电流,非常适合嵌入式系统。 ```c // INA226关键寄存器 #define INA226_ADDR 0x40 // A0=0, A1=0 #define REG_CONFIG 0x00 #define REG_SHUNT 0x01 // 电流采样电压(uV) #define REG_BUS 0x02 // 总线电压(mV) #define REG_CALIB 0x05 ``` ## 三、软件配置与数据读取(STM32示例) ### 初始化I2C并配置INA226 ```c #include "stm32f1xx_hal.h" I2C_HandleTypeDef hi2c1; void INA226_Init(void) { uint16_t config = 0x4127; // AVG=16次平均, VSHUNT=1100us, VBUS=1100us, 连续模式 uint8_t data[2] = {config >> 8, config & 0xFF}; HAL_I2C_Mem_Write(&hi2c1, INA226_ADDR<<1, REG_CONFIG, 1, data, 2, 100); // 校准:设置电流LSB。假设采样电阻Rshunt=0.01Ω,最大电流5A // 电流LSB = 5A / 32768 ≈ 0.1526mA,取0.1mA,则CALIB = 0.00512 / (LSB * Rshunt) // 0.00512 / (0.0001 * 0.01) = 5120 uint16_t calib = 5120; data[0] = calib >> 8; data[1] = calib & 0xFF; HAL_I2C_Mem_Write(&hi2c1, INA226_ADDR<<1, REG_CALIB, 1, data, 2, 100); } // 读取电压(mV)和电流(mA) void INA226_Read(float *voltage_mV, float *current_mA) { uint8_t buf[2]; uint16_t raw; // 读总线电压 HAL_I2C_Mem_Read(&hi2c1, INA226_ADDR<<1, REG_BUS, 1, buf, 2, 100); raw = (buf[0] << 8) | buf[1]; *voltage_mV = raw * 1.25f; // 每个LSB=1.25mV // 读分流电压 HAL_I2C_Mem_Read(&hi2c1, INA226_ADDR<<1, REG_SHUNT, 1, buf, 2, 100); raw = (buf[0] << 8) | buf[1]; // 电流 = 分流电压 / 采样电阻,但已通过校准寄存器换算,直接读电流寄存器? // 实际上电流值需通过计算:电流 = 分流电压(uV) / Rshunt(mΩ) / 1000 (mA) // 但更简单:读取功率寄存器或直接计算。这里用分流电压计算 float shunt_uV = (int16_t)raw * 2.5f; // 每个LSB=2.5uV *current_mA = shunt_uV / 10.0f; // Rshunt=0.01Ω=10mΩ,uV/10 = mA } ``` ### 电池电量估算:从库仑计到EKF **方法1:开路电压法(OCV)** - 原理:电池静置后电压与SOC有固定曲线。 - 缺点:需静置1小时以上,无法动态更新。 **方法2:库仑计法(电流积分)** - 原理:SOC = SOC0 + (1/Q_total) * ∫I dt。 - 实现简单,但存在累积误差,需定期校准。 ```c // 库仑计实现(基于定时器中断,每100ms累加) float soc_percent = 100.0f; float battery_capacity_mAh = 2000.0f; // 电池容量 float current_mA; void Timer_ISR(void) { // 假设每100ms调用一次 float dt_h = 0.1f / 3600.0f; // 小时 soc_percent -= (current_mA * dt_h) / battery_capacity_mAh * 100.0f; if (soc_percent < 0) soc_percent = 0; if (soc_percent > 100) soc_percent = 100; } ``` **方法3:扩展卡尔曼滤波(EKF)** - 融合OCV和库仑计,动态估计SOC和电池内阻。 - 适合高精度场景,但计算量大,需浮点运算。 ```c // EKF简化模型(状态:SOC,观测:电压) // 状态方程:SOC(k+1) = SOC(k) - (I*dt)/Q // 观测方程:V(k) = OCV(SOC) - I*R0 - V_RC // 实际工程中需查表拟合OCV曲线 ``` 对于大多数嵌入式应用,**库仑计+定期OCV校准**是性价比最高的方案。建议在系统空闲时(电流接近0)测量电压,查OCV表修正SOC。 ## 四、工程实践与注意事项 ### 1. 采样噪声抑制 - 硬件:在采样电阻两端并联100nF电容,但注意影响带宽。 - 软件:使用滑动平均滤波或中值滤波,INA226内置16次平均已足够。 ### 2. 温度补偿 - 锂电池容量随温度下降,库仑计需乘以温度系数(如-0.5%/℃)。 - 使用NTC测量电池温度,修正SOC计算。 ### 3. 低功耗设计 - 在待机模式关闭INA226(通过配置寄存器或断开电源),仅保留MCU的RTC唤醒。 - 采样频率自适应:负载变化快时提高采样率,稳定时降低。 ### 4. 校准流程 - 出厂前用精密电源校准分压系数和采样电阻值。 - 软件中存储校准系数,如电压增益和偏移。 ```c // 校准示例:实际电压 = 读取值 * gain + offset float voltage_real = voltage_mV * 1.0012f + 0.3f; // 通过万用表比对得出 ``` ## 五、总结 电源监控设计需平衡精度、成本和复杂度。对于大多数产品,采用INA226等专用芯片配合库仑计算法即可满足需求。若追求极致精度,可引入EKF,但需评估MCU算力。最后,务必在真实负载下测试动态响应和电量估算误差,并根据结果调整滤波参数和校准系数。 希望本文能为你构建可靠的电源监控系统提供参考。如有疑问,欢迎在评论区交流。