绝缘检测方案,绝缘检测资料。 通过使用STM32F103单片机【pp】,不平衡电桥测电阻,测高压绝缘阻值。通过隔离RS485通信芯片与主控板通信,协议使用通用协议。在充电桩上应用过,可以作为设计参考
绝缘检测方案,绝缘检测资料。
通过使用STM32F103单片机【pp】,不平衡电桥测电阻,测高压绝缘阻值。通过隔离RS485通信芯片与主控板通信,协议使用通用协议。在充电桩上应用过,可以作为设计参考。
资料包括原理图,PCB,BOM,软件源代码,设计计算公式。

这是一个基于 STM32F103 的 不平衡电桥法高压绝缘检测方案 的核心代码实现。
该方案常用于充电桩(EVSE)、储能BMS等场景。核心原理是利用两个已知阻值的精密电阻(R_1, R_2)与电池正负极对地绝缘电阻(R_{p}, R_{n})构成电桥,通过STM32的ADC采集分压点电压,解方程组计算出绝缘阻值。
📂 项目文件结构建议
Insulation_Detection/
├── Core/
│ ├── Inc/
│ │ ├── insulation_algo.h // 核心算法头文件
│ │ └── main.h
│ └── Src/
│ ├── insulation_algo.c // 核心算法实现 (公式计算)
│ ├── main.c // 主逻辑 (ADC采集 + 状态机)
│ └── rs485_comm.c // RS485通信协议 (模拟通用协议)
├── Drivers/ // STM32 HAL库
└── User_App/
└── app_config.h // 参数配置 (电桥电阻值等)
核心算法层 (insulation_algo.h & .c)
这是方案的灵魂,包含设计计算公式的代码化实现。
insulation_algo.h
ifndef __INSULATION_ALGO_H
define __INSULATION_ALGO_H
include
include
// 定义绝缘检测结果结构体
typedef struct {
float r_positive; // 正极对地绝缘电阻 (MΩ)
float r_negative; // 负极对地绝缘电阻 (MΩ)
float total_voltage; // 总母线电压 (V)
bool alarm_flag; // 报警标志 (绝缘过低)
uint8_t status; // 状态: 0-正常,1-计算中,2-故障
} Insulation_Result_t;
// 初始化算法参数
void INS_Algo_Init(float r1_val, float r2_val, float adc_ref, uint16_t adc_max);
// 核心计算函数
// 输入:
// v_mid_pos: 正极电桥中点电压 (V)
// v_mid_neg: 负极电桥中点电压 (V) (如果是单路切换采集,则传入对应时刻电压)
// v_bus: 母线总电压 (V)
// 输出: 填充 Result 结构体
void INS_Calculate_Resistor(float v_mid_pos, float v_mid_neg, float v_bus, Insulation_Result_t *Result);
endif
insulation_algo.c
include “insulation_algo.h”
include
// 全局参数:电桥上下臂电阻值 (单位: kΩ 或 Ω,需统一)
// 假设原理图中:上臂 R1, 下臂 R2
static float R_BRIDGE_HIGH = 300.0f; // 例如 300kΩ
static float R_BRIDGE_LOW = 300.0f; // 例如 300kΩ
static float ADC_REF_VOLT = 3.3f;
static uint16_t ADC_MAX_VAL = 4095;
/**
@brief 初始化算法参数
@param r1_val 电桥高臂电阻值 (kΩ)
@param r2_val 电桥低臂电阻值 (kΩ)
*/
void INS_Algo_Init(float r1_val, float r2_val, float adc_ref, uint16_t adc_max) {
R_BRIDGE_HIGH = r1_val;
R_BRIDGE_LOW = r2_val;
ADC_REF_VOLT = adc_ref;
ADC_MAX_VAL = adc_max;
}
/**
@brief 不平衡电桥法计算绝缘电阻
-
数学模型推导 (简化版):
设母线电压为 U, 正对地绝缘 Rp, 负对地绝缘 Rn
接入检测电阻 R1(接正), R2(接地) -> 测得电压 V1
接入检测电阻 R3(接负), R4(接地) -> 测得电压 V2 -
本方案采用经典双路或切换式电桥,此处以典型的“正负分别对地分压”模型为例:
实际上通常是通过继电器切换,或者双路ADC同时采样。 -
假设电路结构:
正极 --[Rp]-- GND
负极 --[Rn]-- GND -
测量正极时:R1接正,R2接地,中点电压 Va
测量负极时:R3接负,R4接地,中点电压 Vb -
根据基尔霍夫定律联立方程求解 Rp 和 Rn。
以下公式为通用解算逻辑,具体系数需根据您的原理图电阻网络调整。
*/
void INS_Calculate_Resistor(float v_mid_pos, float v_mid_neg, float v_bus, Insulation_Result_t *Result) {
if (v_bus status = 2;
Result->r_positive = 0;
Result->r_negative = 0;
return;
}Result->total_voltage = v_bus;
Result->status = 0;// — 核心计算公式开始 —
// 注意:实际公式取决于您的具体硬件连接方式。
// 这里提供一个常见的“双电阻切换法”或“双路并行法”的近似解算逻辑。
// 假设:
// Vpos_meas 是正极分压点电压 (相对于系统地)
// Vneg_meas 是负极分压点电压 (相对于系统地,通常为负值或经过运放抬升)// 为了演示,假设硬件已经做了电平移位,ADC读到的都是正电压。
// 设 K1 = (R1+R2)/R2, K2 = (R3+R4)/R4float K_pos = (R_BRIDGE_HIGH + R_BRIDGE_LOW) / R_BRIDGE_LOW;
float K_neg = (R_BRIDGE_HIGH + R_BRIDGE_LOW) / R_BRIDGE_LOW; // 假设对称// 还原未接检测电阻时的理论对地电压 (估算)
// 实际工程中常用联立方程组求解:
// (U_pos - 0)/Rp + (U_pos - U_bus)/Rn + (U_pos - U_bus)/R1 + U_pos/R2 = 0 … (复杂节点电压法)// 【简化工程公式】(适用于常见的不平衡电桥模块)
// Rp = (U_bus * R_ref * (V2 - V1)) / (V1 * (U_bus - V2) - V2 * (U_bus - V1)) … 此类形式
// 由于缺乏具体原理图,以下使用标准的节点电压法解算逻辑伪代码,请代入您的具体电阻值。// 假设场景:
// 1. 闭合S1 (正极检测): 测得 V1
// 2. 闭合S2 (负极检测): 测得 V2
// 此时系统方程为:
// V1 = U_bus * (Rn // R2) / (Rp + (Rn // R2)) 转换为 MΩ)
// 这里的公式是示意性的,真实公式需依据:
// Rp = R_ref * (U_bus - V_measure) / (2V_measure) … 类似变体
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);// 修正负值 (绝缘电阻不能为负)
if (Result->r_positive r_positive = 999.9f; // 视为无穷大
if (Result->r_negative r_negative = 999.9f;// 转换为 MΩ
Result->r_positive /= 1000.0f;
Result->r_negative /= 1000.0f;// 报警阈值判断 (例如:低于 50kΩ/V 或 固定 1MΩ)
float threshold = 1.0f; // 1 MΩ
if (Result->r_positive r_negative alarm_flag = true;
} else {
Result->alarm_flag = false;
}
}
主控逻辑层 (main.c)
负责ADC采集、RS485调度。
include “main.h”
include “insulation_algo.h”
include “rs485_comm.h”
include
// 外部变量声明 (需在 ADC 部分实现)
extern uint16_t adc_val_pos;
extern uint16_t adc_val_neg;
extern float measured_bus_voltage;
Insulation_Result_t g_ins_result;
// 配置参数
define BRIDGE_R_VAL 300.0f // 300kΩ
define ADC_REF 3.3f
define ADC_MAX 4095
void System_Init(void) {
HAL_Init();
// 初始化时钟、GPIO、ADC、UART(RS485)
// … 省略具体HAL初始化代码 …
// 初始化绝缘算法
INS_Algo_Init(BRIDGE_R_VAL, BRIDGE_R_VAL, ADC_REF, ADC_MAX);
// 初始化RS485
RS485_Init(9600);
}
void Main_Loop(void) {
float v_pos, v_neg;
while (1) {
// 1. 采集 ADC (假设已做滤波处理)
// 将 ADC 值转换为电压值
v_pos = (float)adc_val_pos * ADC_REF / ADC_MAX;
v_neg = (float)adc_val_neg * ADC_REF / ADC_MAX;
// 注意:如果硬件上有运放放大或分压,需在此处乘以倍率
// 例如:v_pos = v_pos * 10.0f;
// 2. 执行绝缘电阻计算
INS_Calculate_Resistor(v_pos, v_neg, measured_bus_voltage, &g_ins_result);
// 3. 处理报警
if (g_ins_result.alarm_flag) {
// 点亮报警LED 或 切断继电器
HAL_GPIO_WritePin(ALARM_LED_Port, ALARM_LED_Pin, GPIO_PIN_SET);
} else {
HAL_GPIO_WritePin(ALARM_LED_Port, ALARM_LED_Pin, GPIO_PIN_RESET);
}
// 4. 通过 RS485 上报数据 (通用协议示例)
// 协议帧格式示例: [Head][Len][Cmd][Data...][CRC]
uint8_t tx_buffer[64];
int len = sprintf((char*)tx_buffer,
"INS,Rp=%.2f,Rn=%.2f,Ubus=%.1f,Alarm=%drn",
g_ins_result.r_positive,
g_ins_result.r_negative,
g_ins_result.total_voltage,
g_ins_result.alarm_flag ? 1 : 0);
RS485_Send(tx_buffer, len);
// 延时,控制采样频率 (例如 1Hz)
HAL_Delay(1000);
}
}
RS485 通信协议层 (rs485_comm.c)
实现隔离通信,采用简单的通用文本协议或Modbus RTU。这里展示一个通用文本协议实现,方便调试。
include “rs485_comm.h”
include
// UART Handle 需根据实际工程定义
extern UART_HandleTypeDef huart1;
void RS485_Init(uint32_t baudrate) {
// 配置 UART1 波特率,启用 RS485 方向控制引脚 (DE/RE)
// … HAL_UART_Init …
}
void RS485_Send(uint8_t *data, uint16_t size) {
// 1. 置发送使能 (DE High)
HAL_GPIO_WritePin(RS485_DE_Port, RS485_DE_Pin, GPIO_PIN_SET);
// 2. 发送数据
HAL_UART_Transmit(&huart1, data, size, 100);
// 3. 短暂延时确保发送完成
HAL_Delay(2);
// 4. 置接收使能 (DE Low)
HAL_GPIO_WritePin(RS485_DE_Port, RS485_DE_Pin, GPIO_PIN_RESET);
}
📐 设计计算公式说明 (文档补充)
设计计算公式部分应包含以下推导(代码中已体现逻辑):
假设电路模型如下:
U: 母线总电压
R_p: 正极对地绝缘电阻
R_n: 负极对地绝缘电阻
R_1, R_2: 检测电桥电阻 (已知)
步骤 1:闭合正极检测开关 (K_1)
此时 R_1 并联在 R_p 上(或串联分压,视具体电路),测得中点电压 V_1。
根据节点电压法:
frac{V_1}{R_2} + frac{V_1 - U}{R_p // R_1} + frac{V_1}{R_n} = 0 (注:具体方程需依据原理图是“分压式”还是“注入式”)
步骤 2:闭合负极检测开关 (K_2)
测得中点电压 V_2。
同理列出方程。
步骤 3:联立求解
通过 V_1, V_2, U 和已知电阻 R_1, R_2,解二元一次方程组得到 R_p 和 R_n。
代码中的简化处理:
上述 insulation_algo.c 中的公式是基于典型对称电桥的简化版。如果您的原理图是非对称的(例如 R_1 neq R_2),请务必在 INS_Calculate_Resistor 函数中代入真实的代数解。

PCB(印刷电路板)的顶层布线图,从颜色和布局来看:
红色区域:通常是 顶层铜箔(Top Layer)
蓝色/紫色走线:可能是 底层或内层走线(Bottom/Internal Layers)
黄色圆圈/焊盘:元件焊盘、过孔或测试点
黑色背景:非导电区域(阻焊层覆盖)
四个角绿色圆孔:安装孔或定位孔
这张图是 硬件设计成果,不是“代码”,而是由 EDA 工具(如 Altium Designer、KiCad、EasyEDA 等)生成的 PCB 布局文件。
PCB 设计自动化脚本(Python + KiCad API)
用于批量生成类似结构的 PCB 布局框架(适合重复性设计)
🎯 2. Gerber 文件解析与可视化代码(Python)
用于读取和分析您这张 PCB 图对应的制造数据
🎯 3. BOM 表自动生成脚本(从原理图到 Excel)
配合您的“资料包括 BOM”需求
🎯 4. 绝缘检测模块的 FPGA/Verilog 控制逻辑(如果需要数字隔离控制)
pcb_generator.py
import sys
sys.path.append(“/usr/lib/kicad/scripting”) # KiCad Python API 路径
from pcbnew import *
def create_insulation_pcb():
board = BOARD.New()
# 设置板框尺寸 (例如 100mm x 80mm)
board.SetBoardEdgesRectangle(wxPoint(0, 0), wxPoint(100000000, 80000000))
# 创建两个对称的绝缘检测单元
for i in range(2):
offset_x = i * 50000000 # 50mm 间距
# 放置 STM32F103 封装 (QFP48)
footprint = FootprintLoad("/path/to/STM32F103C8T6.kicad_mod")
footprint.SetPosition(wxPoint(offset_x + 25000000, 40000000))
board.Add(footprint)
# 放置高压分压电阻网络 (R1, R2)
for j, res_val in enumerate(["300k", "300k"]):
res_fp = FootprintLoad("/path/to/Resistor_SMD_R0805.kicad_mod")
res_fp.SetPosition(wxPoint(offset_x + 25000000 + (j-0.5)*10000000, 20000000))
board.Add(res_fp)
# 放置 RS485 隔离芯片 (如 ADM2587)
iso_fp = FootprintLoad("/path/to/SOIC16_ADM2587.kicad_mod")
iso_fp.SetPosition(wxPoint(offset_x + 25000000, 60000000))
board.Add(iso_fp)
# 添加电源和地平面铺铜
zone = ZONE(board)
zone.SetLayer(F_Cu)
zone.Outline().AddPolygon([wxPoint(0,0), wxPoint(100000000,0), wxPoint(100000000,80000000), wxPoint(0,80000000)])
board.Add(zone)
# 保存为 .kicad_pcb 文件
board.Save("insulation_detection_board.kicad_pcb")
print("✅ PCB 已生成: insulation_detection_board.kicad_pcb")
if name == “main”:
create_insulation_pcb()
💡 注意:此代码需安装 KiCad 并配置 Python API 环境。实际使用时需替换封装路径和坐标。
📊 如果您已有 Gerber 文件 —— 可用以下代码解析并可视化
gerber_viewer.py
import matplotlib.pyplot as plt
from gerber import load_layer
加载顶层铜箔 Gerber 文件
copper_top = load_layer(‘insulation_detection.GTL’) # GTL = Gerber Top Layer
绘制
fig, ax = plt.subplots(figsize=(10, 8))
copper_top.render(ax, alpha=0.7, color=‘red’)
plt.title(“PCB Top Copper Layer Visualization”)
plt.axis(‘equal’)
plt.show()
安装依赖:
pip install gerber matplotlib
🧾 BOM 表自动生成脚本(从 CSV 到 Excel)
假设您有 bom.csv 文件:
Designator,Value,Footprint,Quantity
R1,R300k,R0805,2
R2,R300k,R0805,2
U1,STM32F103C8T6,QFP48,1
U2,ADM2587,SOIC16,1
…
bom_generator.py
import pandas as pd
df = pd.read_csv(‘bom.csv’)
按 Value 分组统计数量
grouped = df.groupby([‘Value’, ‘Footprint’]).size().reset_index(name=‘Total_Qty’)
导出为 Excel
with pd.ExcelWriter(‘BOM_Insulation_Detection.xlsx’) as writer:
grouped.to_excel(writer, sheet_name=‘Summary’, index=False)
df.to_excel(writer, sheet_name=‘Detailed’, index=False)
print(“✅ BOM 表已生成:BOM_Insulation_Detection.xlsx”)
⚙️ 进阶:Verilog 控制逻辑(如需 FPGA 实现绝缘采样时序)
如果您打算用 FPGA 替代 STM32 做高速采样控制:
// insulation_controller.v
module insulation_controller (
input clk,
input rst_n,
output reg adc_start,
output reg [1:0] mux_sel, // 选择正/负极采样
input [11:0] adc_data,
output reg [31:0] result_rp,
output reg [31:0] result_rn
);
parameter STATE_IDLE = 2’b00;
parameter STATE_SAMPLE_POS = 2’b01;
parameter STATE_SAMPLE_NEG = 2’b10;
parameter STATE_CALC = 2’b11;
reg [1:0] state;
reg [11:0] v_pos, v_neg;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= STATE_IDLE;
adc_start <= 0;
mux_sel <= 0;
end else begin
case (state)
STATE_IDLE: begin
mux_sel <= 2’b01; // 选正极
adc_start <= 1;
state <= STATE_SAMPLE_POS;
end
STATE_SAMPLE_POS: begin
adc_start <= 0;
v_pos <= adc_data;
mux_sel <= 2’b10; // 选负极
adc_start <= 1;
state <= STATE_SAMPLE_NEG;
end
STATE_SAMPLE_NEG: begin
adc_start <= 0;
v_neg <= adc_data;
state <= STATE_CALC;
end
STATE_CALC: begin
// 在此处插入绝缘电阻计算公式
// result_rp = …; result_rn = …;
state <= STATE_IDLE;
end
endcase
end
end
endmodule
功能说明
PCB 设计 pcb_generator.py 参数化生成对称布局 PCB
Gerber 分析 gerber_viewer.py 可视化制造文件
BOM 管理 bom_generator.py 自动生成 Excel 格式物料清单
数字控制逻辑 insulation_controller.v FPGA 实现采样时序控制
核心算法 insulation_algo.c/h (前文) 不平衡电桥法计算绝缘电阻
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)