STM32板上只有3.3V为何还不能接USB调试器
STM32 的供电脚旁写着 3.3V,调试器也支持 3.3V。两边电平一致,四根线插上就行?
在带市电输入的控制板上,还差一个关键问题——这 3.3V 是相对谁说的。
电压表跨接 3.3V 和 GND,回答的是两点之间的差值。电脑、示波器以及人所处的环境,却可能把另一套参考引进电路。低压供电与低压可触及,是两件需要分别核实的事。

下面沿一块风扇台灯主控板的真实工程检查这件事。只做断电图纸审查和离线代码验证,不提供带电连接步骤。它适合家电控制、灯具和电源辅助控制板的审图,也能解释为什么换一个“同电平”的调试器仍解决不了问题。
先找整流负端,再看它去了哪里
原理图第 2 页里,D1~D4 构成桥式整流。D2、D3 汇合的一侧标为 NET+,D1、D4 汇合的一侧直接命名为 GND。22µF 的 C8 跨在这两条母线上,C8.2 也接 GND。
因此,这个 GND 首先是整流电路的负端。名字里没有“高压”两个字,并不改变它的电气连接。

这里容易犯的错误,是把整流负端当成固定的零线电位。桥式整流在交流两个半周切换导通路径,负端不是保护地。更不能仅凭 N 的网络名,认定插头方向、布线和现场接地均已得到保证。
若只算正弦交流的峰值,220V 有效值乘以 √2 约为 311V。这个数字说明需要考虑的电位尺度;它不是这块板 GND 对地的实测波形,也不是接地后的故障电流。C8 的储能、负载、二极管、寄生参数和外部接线都会改变实际过程,不能用一条理想整流曲线代替。
降到了3.3V,并没有建立隔离边界
同页下方,U4 使用 BP2525D 封装与器件定义,DRAIN 连接 NET+。这属于 BP2525X 非隔离降压系列。原厂 Rev.1.0 手册将其列为非隔离 AC/DC,SEL 接 VCC 时选择 3.3V 输出。
图里的 U4.2 与 U4.3 共网,3.3V 网络位于 L1 的输出一侧;C12 的负端仍然回到整流负端 GND。功能上完成降压,不等于把 MCU 侧从市电侧隔开。

还有个值得停下来的细节。U4 符号上写着 GND 的 1 脚,实际连接的是包含 L1.1、D7.1 和 R21.2 的局部网络,并非全局 GND。这类浮动降压结构里,芯片引脚名和整板网络名不能混为一谈。审图应沿连线追踪,不能见到同一个英文单词就认定已经共地。
对 MCU 来说,V(3.3V) - V(GND) = 3.3V 可以成立;与此同时,V(GND) - V(保护地) 仍然需要另行判断。这两个式子描述不同的关系。
四针接口把参考地一起带出去了
第 1 页给出的 SWD 接口 U12 很完整。1 脚为 3.3V,2 脚 SWCLK,3 脚 SWDIO,4 脚 GND。旁边的 U13 串口也是 1 脚 3.3V、4 脚 GND,中间是 TX1 和 RX1。

这时,问题已不只是 GPIO 能否承受电平。普通非隔离 USB 调试器或 USB 转串口,往往把目标地与 USB 侧地相连;是否直连以及能承受多大的共模电压,要看具体设备的原理图和额定规格。电脑接上电源、显示器、网线或其他仪器,还可能引入新的对地通路。
普通台式示波器也不能当作隔离设备。泰克的浮地测量应用说明指出,常规接地示波器的公共端与机壳地相关,错误地夹接探头公共端会造成短路。拆掉仪器保护地不是解决办法;电池供电也不自动保证输入通道隔离。
所以,支持 3.3V 只是接口条件之一。还需要明确目标地相对仪器、电脑和保护地的关系,以及隔离器件、探头的工作电压、共模范围与使用类别。本文不据图纸给任何现成接线方案作安全背书。
有一只AC/DC模块,也不能只看外壳标签
第 3 页还有 U7,符号名为 220AC_12DC,3 脚为正输出,4 脚为负输出。它看上去像另一套电源,但 U7.4 在工程中仍接全局 GND。

工程没有给出可核实的 U7 完整型号与隔离规格,不能先替它补上“隔离模块”的结论。即使模块本身具备隔离能力,只要输出负端又接回整流负端,整板外设参考地也没有因此获得独立的隔离边界。
PCB 能帮助定位这个问题,却不能单靠外观完成判定。下面是对应主控板的实际 EDA 顶底面导出。顶面便于找 U12、U13 和电源器件,底面便于看 GND 铜皮与接口分布。底面图已经翻到从底面观察的方向,不能把左右位置照搬到顶面。


这两张图用于定位和复核连线,不用于宣布爬电距离、绝缘耐压或整机安规合格。此类结论需要明确材料、结构、工作环境与适用标准,截图量一下距离远远不够。
把共地检查做成能重复运行的工具
手工追线可以找到问题,修改工程后却容易漏查。因此这里补了一段独立的 Python 工具,直接读取嘉立创 EDA 导出的 Allegro/TEL 网表,用实际引脚查询共网关系。
本例选 D1.2、D4.2、C8.2 作为整流负端锚点,查询调试与外设地脚。三个锚点必须全部存在且属于同一网络;缺引脚、重复引脚或锚点分裂都会明确报错,不会把解析失败误判为安全。
程序只检查导线的直接共网,不穿越电阻、二极管、变压器或隔离器。因此 SAME_NET 可以证明直接相连,OTHER_NET 仅说明网名不同,不能证明电气隔离。这项边界比一个简单的绿色“通过”更有用。
将下面完整代码保存为 net_reference.py。使用 Python 3.11 或更新版本,无第三方依赖。网表在工程编辑器中从对应原理图版本导出;不要拿另一版 PCB 或原理图混用。
"""Audit direct net membership in an EDA Allegro/TEL export. Python 3.11+."""
import argparse
import hashlib
import re
from pathlib import Path
def parse_tel(text):
sections = text.split("$NETS", 1)
if len(sections) != 2:
raise ValueError("missing $NETS")
body = re.split(r"(?m)^\$", sections[1], maxsplit=1)[0]
records = re.split(r"(?m)^(?=\S[^\n;]*;)", body)
pin_net = {}
for record in records:
if not record.strip():
continue
if ";" not in record:
raise ValueError("malformed net record")
name, pins = record.split(";", 1)
name = name.strip().strip("'")
tokens = pins.replace(",", " ").split()
if not name or not tokens:
raise ValueError("empty net or pin list")
for pin in tokens:
if not re.fullmatch(r"[^\s.;]+\.[^\s.;]+", pin):
raise ValueError("invalid pin: " + pin)
if pin in pin_net:
raise ValueError("duplicate pin: " + pin)
pin_net[pin] = name
if not pin_net:
raise ValueError("empty netlist")
return pin_net
def audit(pin_net, anchors, probes):
missing = sorted(set(anchors + probes) - pin_net.keys())
if missing:
raise ValueError("missing pins: " + ", ".join(missing))
reference_nets = {pin_net[pin] for pin in anchors}
if len(reference_nets) != 1:
raise ValueError("anchors do not share one net")
reference = reference_nets.pop()
return reference, [(pin, pin_net[pin], pin_net[pin] == reference)
for pin in probes]
def main():
cli = argparse.ArgumentParser(description=__doc__)
cli.add_argument("file", type=Path)
cli.add_argument("--anchor", action="append", required=True)
cli.add_argument("--probe", action="append", required=True)
args = cli.parse_args()
data = args.file.read_bytes()
try:
pins = parse_tel(data.decode("utf-8-sig"))
reference, rows = audit(pins, args.anchor, args.probe)
except (ValueError, UnicodeError) as exc:
cli.exit(2, "UNRESOLVED: " + str(exc) + "\n")
print("SHA256", hashlib.sha256(data).hexdigest())
print("REFERENCE", reference)
for pin, net, same in rows:
print(pin, net, "SAME_NET" if same else "OTHER_NET")
print("OTHER_NET is not proof of isolation; components are not traversed.")
if __name__ == "__main__":
main()
本文工具的完整源码已经内嵌,不依赖原项目固件。本例运行命令如下,路径可换成自己的导出文件。
python net_reference.py Netlist_Schematic1_2026-11-04.tel --anchor D1.2 --anchor D4.2 --anchor C8.2 --probe U12.4 --probe U13.4 --probe U7.4 --probe U11.1 --probe U10.8 --probe H1.3 --probe U1.8
实际导出网表包含 48 个网络、207 个引脚。上述七个查询点全部返回 GND SAME_NET,其中 U12.4 是 SWD 地,U13.4 是串口地,U7.4 是 12V 支路负端,U11.1、U10.8、H1.3 分别是显示、按键和风扇控制接口地,U1.8 是 MCU 地脚之一。

验证并未停在一次正常输出。本地执行了 9 项检查,覆盖实际网表、3.3V 与 SWD 信号映射、合成改网、未知引脚、锚点分裂、重复引脚、缺少网表段、空网表段和非法引脚格式。合成输入把 U12.4 改到另一网络后,结果变为 OTHER_NET,没有输出“已隔离”。这只是工具的异常路径测试,不是已实施的硬件改板。
以后换版,保存导出文件的 SHA256,再跑同一组锚点和接口引脚,就能知道“原来以为已经断开的地”是否仍然共网。若要审查真正的隔离边界,还须继续检查跨边界器件、信号回路、屏蔽层与所有外接端口。
真正该改的是调试边界
这块板的图纸已经足以否定“看见 3.3V 就能直连电脑”的推断,但还不足以支持一套新的带电调试接法。
工程修订应先分清带市电参考的功率侧与可接触、可调试侧,再逐项核实电源和信号如何跨越边界。仅换隔离电源、仅断一根 GND、仅加一个光耦,都可能被串口、显示屏、屏蔽层或另一条公共线重新连通。离线审查表应列出每一个跨边界连接,型号、额定值和实际接线均有依据后,才进入下一阶段。
对这份工程,本文完成的是重新导出图纸、追踪参考地、实现并验证共网审查工具。没有修改原始云工程,没有给市电板上电,也没有完成隔离改版或安规测试。读者现在可以重复检查的是网表结论,而不是照图去接一根地线试试看。
资料与验证范围
工程取自 zhangshuning 的《无叶风扇台灯》,项目与 EDA 页面标注 Public Domain。使用 Schematic1 V0.1,图框日期 2022-10-17,以及对应主控 PCB;PCB 丝印上的旧日期保留,不作为工程导出日期。原文照片、说明和固件未复用。
项目与上游工程资料入口 https://oshwhub.com/zhangshuning/wu-xie-feng-shan-tai-deng
实际 EDA 工程 https://pro.lceda.cn/editor#id=5d423eb319f04f439b0f810bb90f0490
芯片依据为 BPS《BP2525X_CN_DS_Rev.1.0》第 1~2 页,数据手册入口 https://item.szlcsc.com/3007033.html
仪器接地依据 https://www.tek.com.cn/documents/application-note/three-facets-floating-measurement-solutions
原理图由实际 EDA 导出 SVG 后以 4800px 渲染,中文字体替换为微软雅黑;PCB 为实际 2160px 导出,正文按可读性缩放并保留器件和连线,没有补绘细节。参考关系图和运行摘要为本文独立绘制;代码为本文独立实现,可按 MIT 许可使用。验证限于原理图、网表及离线程序,不包含实板测试和安全认证。
技术交流,欢迎关注微信公众号:美男子玩编程。



