1. 项目概述
这个基于STM32F103的绝缘检测方案是我在充电桩项目中实际应用过的一个成熟设计。核心思路是利用不平衡电桥法测量高压系统的绝缘电阻,通过RS485与主控通信。整套方案包括硬件设计(原理图+PCB)、嵌入式软件和完整的计算公式推导,特别适合需要高压绝缘检测的场合,比如电动汽车充电桩、储能系统等。
提示:高压绝缘检测是电气安全的关键环节,国家标准GB/T 18487.1-2015对充电桩绝缘检测有明确要求,通常需要检测1MΩ以上的绝缘电阻。
2. 硬件设计解析
2.1 核心电路设计
不平衡电桥电路是这个方案的核心,我采用的典型配置是:
- 上臂电阻R1:300kΩ 1%精度
- 下臂电阻R2:300kΩ 1%精度
- 采样点电压通过运放调理后接入STM32的ADC
电路设计有几个关键点:
- 电阻耐压要足够(我选用的是1206封装的300kΩ电阻,耐压500V)
- 采样电路需要加入TVS二极管保护ADC
- 高压侧和低压侧必须用光耦或磁耦隔离
2.2 PCB布局要点
从项目中的PCB图可以看出几个重要设计考虑:
- 高压走线(红色)与低压走线(蓝色)严格分区
- 模拟信号走线尽量短,且包地处理
- 电源部分采用星型接地
- RS485接口加入ESD保护器件
实际布线时我特别注意了:
- 高压走线间距至少保持2mm以上
- ADC采样线远离数字信号线
- 铺铜时模拟地和数字地单点连接
3. 嵌入式软件实现
3.1 软件架构
项目代码采用分层设计:
code复制Insulation_Detection/
├── Core/
│ ├── Inc/
│ │ ├── insulation_algo.h // 核心算法
│ │ └── main.h
│ └── Src/
│ ├── insulation_algo.c // 算法实现
│ ├── main.c // 主逻辑
│ └── rs485_comm.c // 通信协议
├── Drivers/ // HAL库
└── User_App/
└── app_config.h // 参数配置
3.2 核心算法实现
绝缘电阻计算的关键函数在insulation_algo.c中:
c复制void INS_Calculate_Resistor(float v_mid_pos, float v_mid_neg,
float v_bus, Insulation_Result_t *Result)
{
// 输入有效性检查
if (v_bus < 10.0f) { // 假设最小母线电压10V
Result->status = 2; // 故障状态
return;
}
// 核心计算公式
Result->r_positive = (R_BRIDGE_HIGH * (v_bus - v_mid_pos * 2.0f))
/ (v_mid_pos * 2.0f);
Result->r_negative = (R_BRIDGE_HIGH * (v_bus - v_mid_neg * 2.0f))
/ (v_mid_neg * 2.0f);
// 结果处理
Result->r_positive = (Result->r_positive < 0) ? 999.9f : Result->r_positive/1000.0f;
Result->r_negative = (Result->r_negative < 0) ? 999.9f : Result->r_negative/1000.0f;
// 报警判断
Result->alarm_flag = (Result->r_positive < 1.0f || Result->r_negative < 1.0f);
}
3.3 主控逻辑流程
main.c中的主要处理流程:
- 初始化系统时钟、ADC、USART等外设
- 配置算法参数(电桥电阻值等)
- 进入主循环:
- 采集正负极电压
- 计算绝缘电阻
- 判断报警状态
- 通过RS485上报数据
c复制void Main_Loop(void) {
float v_pos, v_neg;
while (1) {
// 1. ADC采样
v_pos = ADC_GetValue(POS_CH) * ADC_REF / ADC_MAX;
v_neg = ADC_GetValue(NEG_CH) * ADC_REF / ADC_MAX;
// 2. 计算绝缘电阻
INS_Calculate_Resistor(v_pos, v_neg, measured_bus_voltage, &g_ins_result);
// 3. 处理报警
if (g_ins_result.alarm_flag) {
Alarm_Handler();
}
// 4. RS485通信
RS485_Send_Result(&g_ins_result);
HAL_Delay(1000); // 1Hz采样
}
}
4. 通信协议设计
4.1 RS485硬件配置
采用ADM2587隔离型RS485芯片,主要参数:
- 波特率:9600bps
- 数据位:8位
- 停止位:1位
- 无校验
硬件连接注意事项:
- A/B线要加120Ω终端电阻
- 建议使用双绞线传输
- 接地要处理好,避免共模干扰
4.2 通信协议格式
使用简单的ASCII协议,方便调试:
code复制[HEADER],[Rp=值],[Rn=值],[Ubus=值],[ALARM=状态]\r\n
示例:
code复制INS,Rp=1.25,Rn=0.98,Ubus=400.0,Alarm=1\r\n
协议实现关键代码:
c复制void RS485_Send_Result(Insulation_Result_t *result) {
uint8_t buffer[64];
int len = sprintf((char*)buffer,
"INS,Rp=%.2f,Rn=%.2f,Ubus=%.1f,Alarm=%d\r\n",
result->r_positive,
result->r_negative,
result->total_voltage,
result->alarm_flag ? 1 : 0);
HAL_UART_Transmit(&huart1, buffer, len, 100);
}
5. 实际应用经验
5.1 调试技巧
- 先低压测试:先用24V低压电源测试电路,确认正常后再接高压
- ADC校准:上电后先读取零点和满量程值,做软件校准
- 滤波处理:ADC采样建议采用滑动平均滤波,我通常用8次平均
c复制#define FILTER_SIZE 8
uint16_t ADC_Filter(uint32_t channel) {
static uint16_t buffer[FILTER_SIZE] = {0};
static uint8_t index = 0;
uint32_t sum = 0;
buffer[index++] = ADC_Read(channel);
if(index >= FILTER_SIZE) index = 0;
for(int i=0; i<FILTER_SIZE; i++) {
sum += buffer[i];
}
return sum / FILTER_SIZE;
}
5.2 常见问题解决
问题1:绝缘电阻测量值跳动大
- 检查电源稳定性
- 增加软件滤波
- 检查电阻温度系数(建议选用25ppm以下的)
问题2:RS485通信失败
- 检查A/B线是否接反
- 测量终端电阻是否正常
- 用示波器观察波形是否畸变
问题3:高压采样异常
- 检查隔离电源是否正常
- 确认光耦或磁耦器件工作正常
- 检查PCB爬电距离是否足够
6. 计算公式推导
6.1 电桥原理分析
不平衡电桥法的基本原理是基于分压原理。电路模型如下:
code复制正极 ----[Rp]---- GND
|
[R1]
|
V_pos
|
[R2]
|
负极 ----[Rn]---- GND
根据基尔霍夫电流定律,可以列出方程:
对于正极测量:
V_pos = Vbus × (R2 || Rn) / (R1 + (R2 || Rn))
对于负极测量:
V_neg = Vbus × (R1 || Rp) / (R2 + (R1 || Rp))
6.2 实际工程简化
在实际工程中,我采用了一种简化计算方法:
Rp = R1 × (Vbus - 2×V_pos) / (2×V_pos)
Rn = R1 × (Vbus - 2×V_neg) / (2×V_neg)
这种简化在R1=R2的情况下误差很小,计算量也小,适合在STM32上实时计算。
7. 项目优化方向
- 多量程自动切换:通过继电器切换不同阻值的电桥电阻,实现更宽范围的测量
- 温度补偿:加入温度传感器,对电阻值进行温度补偿
- 历史数据记录:加入EEPROM存储历史报警记录
- 无线传输:增加蓝牙或LoRa模块,实现无线监控
我在实际项目中尝试过第1种优化,通过增加两组不同阻值的电桥电阻(300kΩ和3MΩ),测量范围可以从10kΩ扩展到10MΩ,精度也有明显提升。
这个方案经过实际项目验证,稳定运行超过2年,检测精度达到±5%,完全满足充电桩的绝缘检测要求。关键是要做好高压隔离和信号调理,PCB布局也要特别注意安规要求。
