PCB网表导入AI编程工具遇到的问题与思考
PCB网表导入AI编程工具遇到的问题与思考
背景
在使用 AI 编程工具(Claude Code)辅助 STM32 嵌入式开发时,尝试让 AI 根据 PCB 网表文件自动生成硬件驱动代码(LED、按键等)。这个过程中遇到了一个典型问题:AI 无法从网表中正确推导核心板模块的 MCU 引脚映射,导致生成的驱动代码引脚配置错误。
本文记录了问题的发现、分析和解决过程,并对比了两种不同的 PCB 原理图绘制方式对网表可读性的影响。
为什么要导入网表
操作过程
在嵌入式开发中,软件工程师需要知道 PCB 板上每个外设(LED、按键、传感器等)连接到 MCU 的哪个 GPIO 引脚,才能编写正确的驱动代码。传统做法是查阅硬件原理图,手动查找每个连接。
使用 AI 编程工具时,我们希望通过以下流程实现自动化:
PCB 工程 (立创EDA/Altium/KiCad)│▼导出网表文件 (.tel)│▼AI 读取网表 → 解析连接关系 → 生成 PCB 连接关系表│▼AI 根据关系表 → 自动生成驱动代码 (LED.c, KEY.c 等)│▼编译 → 烧录 → 验证
具体操作步骤:
- 在 PCB 设计软件中导出网表
:在立创EDA中,选择 文件→导出→导出网表,生成.tel格式的网表文件 - 将网表文件放入项目目录
:放到 Doc/文件夹下,供 AI 读取 - AI 解析网表
:读取 $PACKAGES(元器件清单)和$NETS(网络连接)两个关键段落 - 生成连接关系表
:将二进制/文本格式的网表转换为人类可读的 Markdown 表格 - 基于关系表生成驱动代码
:AI 根据引脚映射关系自动编写 GPIO 初始化和控制代码
将 PCB 工程转换为纯文本连接关系的意义
PCB 工程文件(如立创EDA的 .epro 文件)是二进制格式,只能用对应的 EDA 软件打开。将其导出为纯文本网表并进一步整理为 Markdown 连接关系表,有以下意义:
|
|
|
|---|---|
| AI 可读 |
|
| 跨工具共享 |
|
| 快速检索 |
grep 等工具快速查找某个引脚或网络的连接关系 |
| 文档化 |
|
问题发现
一切看起来都很顺利——我把 PCB 网表文件交给 Claude Code,让它自动解析并生成 LED 和按键的驱动代码。编译通过,烧录成功,没有报错。
然而,当我把开发板接到电源上,期待地看着那几颗 LED 时,发现 LED1 和 LED2 死活不亮。我检查了代码,确认 GPIO 初始化没问题;我又检查了硬件,确认 LED 本身是好的。那问题出在哪?
我带着疑惑去核对了网表文件和 AI 生成的代码,才发现问题的根源:AI 对 U14 核心板引脚的 MCU 映射完全是猜测的,而且猜错了。
具体来说,网表里写的是:
D1 ; J1.10 LED1.1 U14.11
这一行告诉 AI:LED1 连接到了 U14 的第 11 号引脚。但 U14 是一个核心板模块,它的 11 号引脚对应 MCU 的哪个 GPIO?网表里没有说。AI 只能根据 STM32F103C8T6 的引脚排列去猜——结果猜成了 PA8,而实际上是 PB3。
我对比了一下 AI 猜测的结果和实际引脚:
|
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
PB3 |
|
|
|
|
|
PA15 |
|
|
|
|
|
|
|
|
|
|
|
PA11 |
|
4 个 LED 引脚,AI 猜错了 3 个,只有 LED3 碰巧蒙对了。这就是为什么 LED1 和 LED2 不亮的原因——代码初始化的是 PA8 和 PA11,而 LED 实际接在 PB3 和 PA15 上。
问题根因分析
U14 是什么
U14 是一个 STM32F103C8T6 核心板模块(封装名为 CONN-TH_L53.3-W22.9_STM32F103C8T6-CARD),它是一个集成了 MCU、晶振、复位电路等的最小系统板,通过 40 个引脚的排针与底板连接。
关键问题:U14 的引脚编号(1-40)是核心板排针的物理排列顺序,与 STM32F103C8T6 芯片的引脚号(PA0-PA15, PB0-PB15, PC13-PC15 等)没有直接对应关系。
U14 核心板(俯视图,示意)┌─────────────────────────┐│ STM32F103C8T6 ││ ┌───────────┐ ││ │ MCU芯片 │ ││ └───────────┘ ││ │└──┬──┬──┬──┬──┬──┬──┬──┬─┘1 2 3 4 5 6 7 8 ← 排针引脚编号对应哪个MCU引脚?需要查手册!
网表中有什么
原始网表文件中,对于 U14 的每个引脚,只记录了:
-
连接到了哪个网络(如 D1、KEY1、3N763 ; J1.9 U14.12 ← 自动生成名称,无法推导MCU引脚$3N768 ; J1.8 U14.13$3N919 ; J2.20 U14.213N763 ; J1.9 U14.12— 自动生成的名称,完全无法推导 U14.12 对应 PB4 -
AI 只能根据 STM32F103C8T6 的标准引脚排列猜测映射关系,结果猜错了
修改后网表:MCU 引脚名优先
后来我修改了原理图,对于一些没有自定义功能名的网络,先从 U14 核心板引脚引出网络并命名为 MCU 引脚名。

导出的网表片段(修改版物联网竞赛板网表文件-修改版.tel):
; --- LED 网络(仍然是功能名) ---D1 ; J1.10 LED1.1 U14.11D2 ; J1.11 LED2.1 U14.10D3 ; J1.12 LED3.1 U14.9D4 ; J1.13 LED4.1 U14.8; --- KEY 网络(仍然是功能名) ---KEY1 ; C21.2 J2.11 R8.2 SW1.3 U14.30KEY2 ; C22.2 J2.12 R9.2 SW2.3 U14.29KEY3 ; C23.2 J2.16 R10.2 SW3.3 U14.25KEY4 ; C24.2 J1.4 R11.2 SW4.3 U14.17; --- 其他网络(现在是MCU引脚名) ---PB4 ; J1.9 U14.12 ← 原来叫 $3N763,现在直接标 PB4PB5 ; J1.8 U14.13 ← 原来叫 $3N768,现在直接标 PB5PB6 ; H2.2 J1.7 U8.3 U14.14 ← 原来叫 SCL,现在直接标 PB6PB7 ; H2.1 J1.6 U8.4 U14.15 ← 原来叫 SDA,现在直接标 PB7PB8 ; J1.5 U14.16 ← 原来叫 3N921,现在直接标 PC13PC14 ; J2.18 U14.23 ← 原来叫 $3N923,现在直接标 PC14PC15 ; J2.17 U14.24 ← 原来叫 $3N925,现在直接标 PC15RESET ; J2.4 U14.37 ← 原来叫 $3N951,现在直接标 RESETVBAT ; J2.20 U14.21 ← 原来叫 $3N919,现在直接标 VBAT
为什么 LED/KEY 网络名没变?
我后来尝试给 LED1 的网络也添加 PB3 标签,但网表中仍然显示为 D1。这是因为 立创EDA 有一个特性:网络名由第一个连接到该网络的网络标签决定。
当我最初绘制原理图时:
-
LED1 网络:我先放置了 D1标签,然后连到 U14.11 → 网表显示D1 -
U14.12 网络:没有放置任何标签,EDA 自动生成 $3N763→ 网表显示$3N763
当我修改原理图时:
-
LED1 网络:再添加 PB3标签已经晚了,D1已经是”全局网络名” → 网表仍显示D1 -
U14.12 网络:我先从 U14.12 引脚引出网络并放置 PB4标签 → 网表显示PB4
立创EDA 网络名优先级规则
通过这次实践,我发现立创EDA 的网络名遵循以下规则:
|
|
|
|
|---|---|---|
D1,再连线 |
|
D1 |
PB3 |
|
|
先从引脚引出并放标签 PB3 |
第一个标签 | PB3
|
关键结论: 网络名取决于第一个放置并连接到该网络的标签。一旦确定,后续添加的标签不会改变网表中的显示。
正确的绘制方法
基于这个特性,正确的做法是:
在绘制原理图的最初阶段,就从主控芯片/核心板的引脚引出网络,并用 MCU 引脚名命名,使其成为全局网络名。

正确的绘制顺序:1. 放置 U14 核心板符号2. 从 U14.11 引脚引出导线3. 立即放置网络标签 "PB3"4. 再连接到 LED1、R15 等器件错误的绘制顺序:1. 放置 LED12. 从 LED1 引出导线3. 放置网络标签 "D1" ← 此时 "D1" 已成为全局网络名4. 再连接到 U14.115. 后续再添加 "PB3" 标签 ← 无效,网表仍显示 "D1"
如果按正确顺序绘制,网表就会显示:
PB3 ; J1.10 LED1.1 U14.11 ← MCU 引脚名优先PA5 ; C21.2 J2.11 R8.2 SW1.3 U14.30...
这样 AI 就能直接从网表读出每个外设对应的 MCU 引脚,无需猜测或反推。
核心区别总结
|
|
|
|
|
|---|---|---|---|
D1) |
|
|
|
先从 MCU 引脚端命名(如 PB3) |
MCU 引脚名优先 | 高 — 直接可读 | 低 — 直接可解析 |
对 LED 和 KEY 的影响
在我的原始原理图中,LED 和 KEY 网络是先从外设端命名(D1–D4、KEY1–KEY4),所以网表显示的是功能名而非 MCU 引脚名。
问题关键:D1 ; J1.10 LED1.1 U14.11 这一行只告诉你 LED1 连到了 U14.11,不告诉你 U14.11 = PB3。
由于我在修改时才添加 MCU 引脚名标签,此时 D1 已经是”全局网络名”,无法再改变。如果我在绘制最初就从 U14.11 引出网络并命名为 PB3,网表就会直接显示 MCU 引脚名。
最终确认的 U14 引脚映射表
结合方式二网表 + 用户手动确认,得到完整映射:
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
经验教训
对硬件工程师
-
绘制原理图时,优先从主控芯片/核心板引脚端命名网络:在立创EDA 中,网络名由第一个连接到该网络的标签决定。如果先从外设端命名为
D1,后续再添加PB3标签也不会改变网表中的显示。正确做法是从一开始就从 MCU 引脚端引出网络,并用引脚名(如PB3)命名。 -
核心板模块的引脚编号 ≠ MCU 引脚号:这是一个常见的坑,尤其在使用第三方核心板时。网表只能告诉你”连到了模块的第几脚”,不能告诉你”对应 MCU 的哪个 GPIO”。
-
考虑软件开发的便利性:如果原理图是为软硬件协同开发或 AI 辅助开发设计的,网络命名应优先使用 MCU 引脚名,而非功能描述名。
对 AI 辅助开发
-
AI 无法”知道”硬件设计意图:网表中没有的信息,AI 只能猜测。在涉及硬件引脚映射时,必须提供明确的引脚对应关系。
-
纯文本格式是 AI 与硬件之间的桥梁:将 PCB 工程转换为 AI 可读的文本格式,是实现 AI 辅助嵌入式开发的关键步骤。
-
验证环节不可省略:AI 生成的驱动代码必须经过实际硬件验证,不能仅依赖编译通过。本次问题就是编译通过但硬件不亮的典型案例。
夜雨聆风