乐于分享
好东西不私藏

PCB网表导入AI编程工具遇到的问题与思考

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 等)        │        ▼   编译 → 烧录 → 验证

具体操作步骤:

  1. 在 PCB 设计软件中导出网表
    :在立创EDA中,选择 文件 导出→ 导出网表,生成 .tel 格式的网表文件
  2. 将网表文件放入项目目录
    :放到 Doc/ 文件夹下,供 AI 读取
  3. AI 解析网表
    :读取 $PACKAGES(元器件清单)和 $NETS(网络连接)两个关键段落
  4. 生成连接关系表
    :将二进制/文本格式的网表转换为人类可读的 Markdown 表格
  5. 基于关系表生成驱动代码
    :AI 根据引脚映射关系自动编写 GPIO 初始化和控制代码

将 PCB 工程转换为纯文本连接关系的意义

PCB 工程文件(如立创EDA的 .epro 文件)是二进制格式,只能用对应的 EDA 软件打开。将其导出为纯文本网表并进一步整理为 Markdown 连接关系表,有以下意义:

意义
说明
AI 可读
AI 编程工具无法直接解析二进制 PCB 工程文件,但可以读取纯文本格式的网表和 Markdown 文档
跨工具共享
不依赖特定 EDA 软件,任何文本编辑器都能查看
快速检索
可以用 grep 等工具快速查找某个引脚或网络的连接关系
文档化
Markdown 格式的连接关系表既是技术文档,也是 AI 的上下文输入

问题发现

一切看起来都很顺利——我把 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 猜测的结果和实际引脚:

LED
U14引脚
AI 猜测的MCU引脚
实际MCU引脚
结果
LED1 (D1)
U14.11
PA8
PB3
错误
LED2 (D2)
U14.10
PA11
PA15
错误
LED3 (D3)
U14.9
PA12
PA12
碰巧正确
LED4 (D4)
U14.8
PB15
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 的每个引脚,只记录了:

  • 连接到了哪个网络(如 D1KEY13N763 ; 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
EDA 自动生成或第一个标签
可能是自动生成名
先从引脚引出并放标签 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 引脚,无需猜测或反推。


核心区别总结

绘制顺序
网络名结果
网表可读性
AI 解析难度
先从外设端命名(如 D1
功能名优先
低 — 不知道对应哪个 MCU 引脚
高 — 需要猜测或反推
先从 MCU 引脚端命名(如 PB3 MCU 引脚名优先 高 — 直接可读 低 — 直接可解析

对 LED 和 KEY 的影响

在我的原始原理图中,LED 和 KEY 网络是先从外设端命名(D1D4KEY1KEY4),所以网表显示的是功能名而非 MCU 引脚名。

问题关键:D1 ; J1.10 LED1.1 U14.11 这一行只告诉你 LED1 连到了 U14.11,不告诉你 U14.11 = PB3。

由于我在修改时才添加 MCU 引脚名标签,此时 D1 已经是”全局网络名”,无法再改变。如果我在绘制最初就从 U14.11 引出网络并命名为 PB3,网表就会直接显示 MCU 引脚名。


最终确认的 U14 引脚映射表

结合方式二网表 + 用户手动确认,得到完整映射:

U14引脚
网络名
MCU引脚
功能
1
CS
PB12
SPI Flash 片选
2
CLK
PB13
SPI Flash 时钟
3
MISO
PB14
SPI 数据输入
4
MOSI
PB15
SPI 数据输出
5
BEEP
PB1
蜂鸣器
6
DEBUG_TX
PA9
串口TX
7
DEBUG_RX
PA10
串口RX
8
D4
PA11
LED4
9
D3
PA12
LED3
10
D2
PA15
LED2
11
D1
PB3
LED1
12
PB4
PB4
扩展IO
13
PB5
PB5
扩展IO
14
PB6
PB6
I2C SCL
15
PB7
PB7
I2C SDA
16
PB8
PB8
扩展IO
17
KEY4
PB9
按键4
18
+5V
电源
19
GND
接地
20
VCC-MCU
MCU 3.3V
21
VBAT
VBAT
电池备份
22
PC13
PC13
LED0
23
PC14
PC14
扩展IO
24
PC15
PC15
扩展IO
25
KEY3
PA0
按键3
26
PA1
PA1
扩展IO
27
PA2
PA2
UART2 TX
28
PA3
PA3
UART2 RX
29
KEY2
PA4
按键2
30
KEY1
PA5
按键1
31
PA6
PA6
扩展IO
32
ADC1
PA7
ADC1
33
ADC2
PB0
ADC2
34
ADC3
PB1
ADC3
35
PB10
PB10
UART3 TX
36
PB11
PB11
UART3 RX
37
RESET
NRST
复位
38
VCC-MCU
MCU 3.3V
39
GND
接地
40
GND
接地

经验教训

对硬件工程师

  1. 绘制原理图时,优先从主控芯片/核心板引脚端命名网络:在立创EDA 中,网络名由第一个连接到该网络的标签决定。如果先从外设端命名为 D1,后续再添加 PB3 标签也不会改变网表中的显示。正确做法是从一开始就从 MCU 引脚端引出网络,并用引脚名(如 PB3)命名。

  2. 核心板模块的引脚编号 ≠ MCU 引脚号:这是一个常见的坑,尤其在使用第三方核心板时。网表只能告诉你”连到了模块的第几脚”,不能告诉你”对应 MCU 的哪个 GPIO”。

  3. 考虑软件开发的便利性:如果原理图是为软硬件协同开发或 AI 辅助开发设计的,网络命名应优先使用 MCU 引脚名,而非功能描述名。

对 AI 辅助开发

  1. AI 无法”知道”硬件设计意图:网表中没有的信息,AI 只能猜测。在涉及硬件引脚映射时,必须提供明确的引脚对应关系。

  2. 纯文本格式是 AI 与硬件之间的桥梁:将 PCB 工程转换为 AI 可读的文本格式,是实现 AI 辅助嵌入式开发的关键步骤。

  3. 验证环节不可省略:AI 生成的驱动代码必须经过实际硬件验证,不能仅依赖编译通过。本次问题就是编译通过但硬件不亮的典型案例。