1. 项目概述
这个太阳能充电管理系统是我在新能源领域的一次实践探索,核心目标是为小型离网场景设计一套低成本、易实现的充电管理方案。系统以STM32F103C8T6为主控,通过ADC采样、阈值判断和继电器控制实现了完整的"采集-判断-控制-显示"闭环流程。
与传统仅显示电压的方案不同,我在人机交互上做了重点优化:采用类似手机的电量图标和动态充电速度显示,让系统状态一目了然。实测下来,这套方案在保证功能完整性的同时,确实大幅提升了使用体验,特别适合作为教学演示或小型项目原型。
2. 系统整体设计思路
2.1 硬件架构选择
选择STM32F103C8T6作为主控主要基于三点考虑:
- 内置12位ADC满足采样精度需求(实测误差<1%)
- 丰富的外设接口(I2C驱动OLED+GPIO控制继电器)
- 性价比突出(单价<20元)
硬件系统由四个模块构成:
- 采集模块:PA1采集电池电压,PA2采集太阳能板输出
- 处理模块:STM32进行数据转换和逻辑判断
- 执行模块:PB2控制继电器通断
- 显示模块:0.96寸OLED实时刷新状态
2.2 软件流程设计
主程序采用事件驱动架构:
c复制while(1){
if(采样标志){
读取ADC值();
计算电量和充电速度();
更新显示();
执行充电控制();
清除标志();
}
// 其他任务...
}
定时器每200ms触发一次ADC采样,这个间隔经过实测验证:
- 太短(<100ms)会导致OLED刷新过快出现闪烁
- 太长(>500ms)会使控制响应迟钝
3. 关键硬件实现细节
3.1 采样电路设计
电池电压采样采用电阻分压方案:
code复制电池+ → 10kΩ → PA1 → 10kΩ → GND
分压比1:2,配合STM32的3.3V参考电压,可测量0-6.6V范围。实测发现:
注意:必须在前端加入100nF滤波电容,否则ADC值会出现明显抖动
太阳能板采样直接接入PA2,因为其开路电压通常在5-18V范围,所以需要特别设计保护电路:
- 18V稳压二极管防止过压
- 1kΩ限流电阻保护ADC引脚
3.2 继电器驱动电路
选用5V常开型继电器,驱动方案如下:
code复制PB2 → 1kΩ → S8050三极管基极
发射极接地,集电极接继电器线圈
实测中遇到一个坑:继电器吸合时会产生反向电动势,必须在线圈两端并联续流二极管(1N4148),否则会导致MCU复位。
4. 软件核心算法实现
4.1 电量计算算法
采用线性映射公式:
c复制// PA1 ADC满量程0x96对应1000mAh
mAh = (adc_value * 1000) / 0x96;
但实际测试发现,锂电池的电压-容量关系是非线性的。改进方案是分段线性化:
c复制if(adc_value < 0x30) // 0-30%
mAh = adc_value * 800 / 0x30;
else if(adc_value < 0x60) // 30-60%
mAh = 800 + (adc_value-0x30)*400/0x30;
else // 60-100%
mAh = 1200 + (adc_value-0x60)*800/0x36;
4.2 充电控制逻辑
核心判断条件:
c复制if(mAh >= 1000 && !is_full){
PB2 = LOW; // 断开充电
is_full = 1;
}else if(mAh < 950 && is_full){
PB2 = HIGH; // 恢复充电
is_full = 0;
}
这里设置50mAh的回差(950-1000)是为了防止在临界点频繁切换。
5. OLED显示优化技巧
5.1 电量图标实现
使用u8g2图形库绘制电池图标:
c复制// 边框
u8g2_DrawFrame(&u8g2, x, y, 24, 12);
// 正极
u8g2_DrawBox(&u8g2, x+24, y+3, 2, 6);
// 电量填充
int fill = (mAh * 20) / 1000; // 映射到0-20像素
u8g2_DrawBox(&u8g2, x+2, y+2, fill, 8);
5.2 充电速度动画
设计了三档速度指示:
c复制if(speed > 70) // 快充
draw_3bars();
else if(speed > 30) // 中速
draw_2bars();
else // 慢充
draw_1bar();
实测发现直接刷新整个屏幕会导致闪烁,优化方案是:
- 只刷新变化部分(电量数字和图标)
- 使用双缓冲机制
6. 系统测试与问题排查
6.1 常见问题速查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| ADC值跳动大 | 滤波电容缺失 | 增加100nF电容 |
| 继电器不动作 | 三极管极性接反 | 检查EBC引脚 |
| OLED显示残影 | 刷新太快 | 降低刷新率至5Hz |
| 电量显示不准 | 分压电阻误差 | 改用1%精度电阻 |
6.2 实测数据对比
输入电压与显示电量对比:
| 输入(V) | ADC值 | 显示mAh |
|---|---|---|
| 3.0 | 0x48 | 500 |
| 3.6 | 0x6C | 750 |
| 4.2 | 0x96 | 1000 |
7. 项目优化方向
在实际使用中,我发现几个可以改进的点:
- 增加温度传感器(如DS18B20)进行温度补偿
- 改用PWM控制MOSFET实现线性充电
- 添加SD卡模块记录充放电曲线
- 开发手机APP通过蓝牙查看数据
这个项目最让我满意的就是OLED的交互设计,把枯燥的电压值转换成了直观的图形显示。有同学反馈说这种显示方式比传统数码管友好得多,特别是在户外阳光下,图形比数字更容易辨认。