1. 这套玩法到底在解决什么问题
第一次听到“用 AI 远程控制嘉立创EDA专业版画原理图”这个想法时,我脑子里蹦出来的第一个念头是:这不是脱裤子放屁吗?画原理图本来就是鼠标点几下的事,让 AI 去操作,中间隔着一层通信,效率能高到哪去?
但真正动手把 STM32F103C8T6 最小系统这个案例跑通之后,我的看法变了。这套方案的价值不在于“比人手快”,而在于把重复性的、有固定套路的绘图工作自动化。STM32 最小系统这种东西,电源部分、晶振部分、复位部分、下载接口部分,几乎每一块都是标准电路,差别无非是引脚编号和网络标号。人画一遍要十几分钟,还容易漏掉去耦电容或者把 BOOT0 的下拉电阻画错。让 AI 按模板生成,再通过脚本灌进 EDA 里,一次配置好之后,后面就是流水线作业。
具体来说,这套方案适合三类人:一是经常要画同类型板子的硬件工程师,手里有一堆“换汤不换药”的项目;二是想学 EDA 脚本化操作但不知道从哪下手的初学者,拿 STM32 最小系统当练手项目刚刚好;三是做教学或者批量出图场景的朋友,需要快速生成标准原理图作为参考底图。
核心思路拆成三块:Claude Code 负责“想”,也就是根据你的自然语言描述生成结构化的电路网表或者嘉立创EDA能识别的脚本;嘉立创EDA专业版的扩展接口负责“做”,把 AI 生成的内容转换成实际的原理图元素;中间的通信层负责“传”,让 Claude Code 能远程调用 EDA 的接口。这三块拼起来,就实现了从一句话描述到一张可编辑原理图的完整链路。
注意:这里说的“远程控制”不是指你在外面用手机控制家里的电脑,而是指 Claude Code 作为一个独立的进程,通过本地接口或者文件交换的方式,驱动嘉立创EDA执行绘图操作。两者可以在同一台机器上,也可以在同一局域网内。
2. 为什么选这套技术栈而不是别的
2.1 Claude Code 在电路生成场景下的独特优势
市面上能写代码的 AI 不少,但 Claude Code 在这个场景里有几个别人替代不了的特点。第一是长上下文下的结构保持能力。STM32F103C8T6 最小系统涉及几十个元件、上百个网络连接,普通对话式 AI 聊到后面就忘了前面定义的网络标号。Claude Code 的工程化交互模式允许你把整个项目结构、引脚定义、连接规则一次性喂进去,它在后续生成中能稳定引用这些约束。
第二是对脚本语言的生成质量。嘉立创EDA专业版支持 JavaScript 扩展,Claude Code 写 JS 的功底在同类工具里属于第一梯队。我实测过让几个不同的 AI 写同样的“创建元件并连线”脚本,Claude Code 生成的代码在变量命名、错误处理、API 调用顺序上都更靠谱,基本不需要大改就能跑。
第三是文件系统操作能力。Claude Code 可以直接读写你本地的工程文件,这意味着它可以先生成一份中间格式的网表文件,再调用转换脚本导入 EDA。这种“生成-落盘-导入”的流程比纯对话式 AI 只能输出文本要实用得多。
2.2 嘉立创EDA专业版的脚本扩展能力
选嘉立创EDA专业版而不是其他 EDA 工具,主要看中它的扩展接口开放程度。专业版提供了完整的 JavaScript API,覆盖了原理图绘制的主要操作:创建元件、放置引脚、添加导线、设置网络标号、定义元件属性。这些 API 通过eda全局对象暴露出来,在扩展开发模式下可以直接调用。
另一个原因是元件库的丰富度。STM32F103C8T6 的符号在嘉立创的系统库里有现成的,不需要自己从零画。AI 生成脚本时只需要引用库里的元件 ID,然后设置好位号和参数就行。这比让 AI 去画一个 LQFP48 的符号要现实得多。
还有一点是本地化程度。嘉立创EDA的服务器在国内,元件搜索和库加载的速度很稳定,不会出现画到一半库加载不出来的尴尬情况。对于需要批量生成原理图的场景,这个稳定性很重要。
2.3 整体架构的设计取舍
我最终采用的架构是:Claude Code 生成 JSON 格式的电路描述文件 → Node.js 脚本读取 JSON 并调用嘉立创EDA扩展 API → EDA 执行绘图操作。没有选择让 Claude Code 直接生成 JavaScript 代码去执行,原因有两个。
一是调试成本。如果让 AI 直接写 JS 脚本,一旦 API 调用出错,报错信息是 EDA 内部抛出的,Claude Code 看不到完整的调用栈,很难定位问题。而 JSON 作为中间层,格式错误在解析阶段就能发现,排查起来简单得多。
二是复用性。JSON 描述文件是平台无关的,今天用嘉立创EDA,明天想换到别的工具,只需要换一个转换脚本就行。AI 生成的那部分逻辑不用动。
这个取舍带来的代价是多了一层转换,生成速度会慢几秒。但对于画原理图这种分钟级的任务来说,几秒的延迟完全可以接受。
3. 环境搭建与核心配置细节
3.1 Claude Code 的安装与项目初始化
Claude Code 的安装方式取决于你的操作系统。Windows 下推荐用 npm 全局安装,命令是npm install -g @anthropic-ai/claude-code。安装完成后在终端里执行claude命令,首次运行会引导你完成认证配置。如果你在 Ubuntu 或者 macOS 下,流程基本一致,注意 Node.js 版本不要低于 18。
安装完成后,在你的工作目录下执行claude init,它会生成一个项目配置文件。这个文件里需要关注几个关键项:model指定使用的模型版本,max_tokens建议设大一点,因为电路描述文件比较长,temperature设成 0.2 左右比较合适,太低会死板,太高会乱编引脚。
提示:如果你在 VS Code 里工作,可以装 Claude Code 的 VS Code 扩展,这样在编辑器里就能直接调用,不用来回切终端。扩展的配置和命令行版本是共享的,装一次就行。
项目初始化之后,建议在根目录建一个specs文件夹,专门放电路规格描述文件。我习惯把 STM32F103C8T6 的引脚定义、电源要求、外设连接规则写成一个 Markdown 文件放在里面,每次让 Claude Code 生成电路时都引用这个文件作为约束。
3.2 嘉立创EDA专业版的扩展开发环境
嘉立创EDA专业版的扩展开发入口在菜单栏的“设置”里,找到“扩展”选项,打开“扩展开发模式”。开启之后,顶部会多出一个“扩展”菜单,里面可以新建扩展项目、加载本地扩展、打开调试控制台。
新建一个扩展项目时,选择“原理图扩展”类型。生成的模板里会有一个main.js文件和一个extension.json配置文件。extension.json里需要声明扩展的名称、版本、入口文件,以及需要的权限。对于我们的场景,至少需要schematic:read和schematic:write这两个权限。
调试控制台是排查问题的关键工具。在扩展代码里用console.log输出的信息会显示在控制台里,API 调用出错时的异常信息也会在这里打印。建议在开发阶段把控制台一直开着,方便实时看日志。
3.3 通信层的搭建与文件交换机制
Claude Code 和嘉立创EDA之间的通信,我采用的是文件监听方案。具体来说,Claude Code 把生成的电路描述 JSON 写到output/circuit.json,嘉立创EDA的扩展里用 Node.js 的fs.watch监听这个文件的变化,一旦检测到文件更新,就读取内容并执行绘图。
这个方案的好处是解耦彻底。Claude Code 不需要知道 EDA 的 API 长什么样,EDA 也不需要知道 AI 是怎么生成内容的。两边通过一个约定好格式的文件来交互,任何一边出问题都不会影响另一边。
文件格式我定义了一个简单的 JSON Schema,顶层包含components和nets两个数组。components里每个元素描述一个元件,包括libraryId(库里的元件标识)、designator(位号)、value(参数值)、position(坐标)。nets里每个元素描述一个网络,包括name(网络名)和pins(连接的引脚列表,每个引脚用位号加引脚号表示)。
{ "components": [ { "libraryId": "stm32f103c8t6", "designator": "U1", "value": "STM32F103C8T6", "position": { "x": 300, "y": 200 } } ], "nets": [ { "name": "VDD", "pins": ["U1.24", "U1.36", "U1.48"] } ] }这个格式看起来简单,但实际用起来很顺手。Claude Code 生成这种结构化数据非常稳定,嘉立创EDA那边解析起来也几乎没有歧义。
4. 让 Claude Code 生成 STM32 最小系统电路描述
4.1 给 AI 喂什么规格信息
让 AI 画电路,最怕的就是它“自由发挥”。你让它画 STM32 最小系统,它可能给你加上一堆用不到的外设,或者把某些引脚的连接搞错。所以第一步是把约束条件写清楚。
我准备的规格文件里包含这几块内容。引脚定义表:把 STM32F103C8T6 的 48 个引脚按功能分组,标出哪些是电源、哪些是地、哪些是晶振、哪些是复位、哪些是下载接口、哪些是 BOOT 配置。电源方案:明确 VDD 用 3.3V,VDDA 通过磁珠或者零欧电阻从 VDD 隔离,VBAT 直接接 VDD(不用电池的情况下)。去耦电容配置:每个 VDD 引脚配一个 100nF,整体再加一个 10uF 的钽电容。晶振电路:8MHz 主晶振配两个 20pF 负载电容,32.768kHz 的 RTC 晶振可选。复位电路:10k 上拉电阻加 100nF 电容。下载接口:SWD 模式,SWDIO 和 SWCLK 加上拉电阻。
把这些信息写成 Markdown 文件后,在 Claude Code 里用@specs/stm32f103c8t6.md的方式引用,然后给出指令:“根据规格文件生成 STM32F103C8T6 最小系统的电路描述 JSON,输出到 output/circuit.json”。
4.2 生成过程中的参数计算与校验
Claude Code 生成完 JSON 之后,不要急着导入 EDA。先做一轮逻辑校验。我写了一个简单的 Node.js 校验脚本,检查几个关键点:所有 VDD 引脚是否都连接到了 VDD 网络、所有 VSS 引脚是否都连接到了 GND 网络、晶振引脚是否连接了正确的负载电容、复位引脚是否有上拉和电容、BOOT0 是否有下拉电阻。
这个校验脚本的逻辑不复杂,就是遍历nets数组,检查特定网络名下的引脚列表是否包含了预期的引脚。比如检查VDD网络时,确认U1.24、U1.36、U1.48都在列表里。如果缺少任何一个,脚本就报错并指出缺了哪个引脚。
参数计算方面,主要是去耦电容的数量和晶振负载电容的取值。STM32F103C8T6 有 3 个 VDD 引脚加 1 个 VDDA 引脚,所以至少需要 4 个 100nF 去耦电容。晶振负载电容的计算公式是CL = (C1 * C2) / (C1 + C2) + Cstray,其中 Cstray 是 PCB 走线的寄生电容,一般取 3 到 5pF。8MHz 晶振的 CL 典型值是 20pF,反推 C1 和 C2 大约在 20pF 左右。这些计算过程我会在规格文件里写清楚,让 Claude Code 直接引用结果,而不是让它自己去算。
4.3 生成结果的格式转换与导入
Claude Code 输出的 JSON 是通用格式,嘉立创EDA的扩展需要把它转换成 API 调用序列。这个转换脚本我放在 EDA 扩展的main.js里,核心逻辑是遍历components数组,对每个元件调用eda.sch.createComponent(),然后遍历nets数组,对每个网络调用eda.sch.createNet()并添加引脚连接。
转换过程中有几个细节要注意。坐标系统:嘉立创EDA的坐标原点和单位可能和 JSON 里定义的不一样,需要做一个映射。我一般把 JSON 里的坐标当作“格点坐标”,每个单位对应 EDA 里的 10 个内部单位。元件库 ID:JSON 里写的libraryId需要和嘉立创系统库里的实际 ID 对应,这个可以在 EDA 的元件搜索里查到。网络标号的命名规则:嘉立创EDA对网络标号有一些保留字限制,比如不能以数字开头,不能包含特殊字符。转换脚本里加一个清洗函数,把不合规的标号自动修正。
导入完成后,在 EDA 里打开生成的原理图,肉眼检查一遍。重点看电源网络是否连通、晶振电路是否完整、复位电路是否正确、下载接口是否接对。确认无误后,保存工程文件。
5. 实操过程中踩过的坑与排查记录
5.1 Claude Code 生成内容不稳定的几种表现
引脚号张冠李戴。有一次 Claude Code 把 PA0 的引脚号写成了 10,实际应该是 10 没错,但它把 PA1 也写成了 10。这种错误在校验脚本里能发现,因为同一个引脚号出现在了两个不同的网络里。解决办法是在规格文件里把引脚定义表写得更明确,用表格形式列出“引脚号-引脚名-功能”,让 AI 直接查表而不是凭记忆。
去耦电容漏画。AI 有时候会“偷懒”,觉得 3 个 VDD 引脚共用一个 100nF 就够了。这在实际工程中是不行的,每个 VDD 引脚都需要独立的去耦电容,而且布局时要尽量靠近引脚。我在规格文件里明确写了“每个 VDD 引脚必须配一个独立的 100nF 电容”,并且在校验脚本里加了数量检查。
网络标号命名不一致。比如电源网络一会儿叫VDD,一会儿叫VCC,一会儿叫3V3。这会导致导入 EDA 后网络连接断开。解决办法是在规格文件里定义一份“网络命名规范”,明确电源用VDD、地用GND、模拟电源用VDDA,让 AI 严格按这个来。
5.2 嘉立创EDA扩展API的调用陷阱
API 调用需要等待上一个操作完成。嘉立创EDA的扩展 API 大部分是异步的,如果你连续调用createComponent而不等待返回,后面的元件可能会创建失败。正确的做法是用async/await或者 Promise 链,确保每个操作完成后再进行下一个。
元件创建后需要手动刷新。有时候 API 返回成功了,但原理图界面上看不到新元件。这是因为 EDA 的视图没有自动刷新。解决办法是在批量创建完成后调用一次eda.sch.refresh(),强制重绘。
网络标号的作用域问题。嘉立创EDA里网络标号有“全局”和“局部”两种作用域。如果 AI 生成的网络标号被默认设置为局部,跨页面的连接就会断掉。在创建网络时需要显式指定scope: 'global'。
5.3 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 导入后元件重叠在一起 | JSON 里坐标都是默认值 | 检查 JSON 的 position 字段 | 在转换脚本里加自动布局逻辑 |
| 网络连接断开 | 网络标号命名不一致 | 对比 JSON 和 EDA 里的网络名 | 统一命名规范,加清洗函数 |
| 元件库找不到 | libraryId 写错 | 在 EDA 里搜索该元件 | 用正确的库 ID 替换 |
| 脚本执行报错 | API 权限不足 | 查看调试控制台 | 在 extension.json 里加权限声明 |
| 生成速度慢 | JSON 文件太大 | 看文件行数 | 分批生成,每批不超过 50 个元件 |
提示:调试扩展时,把
console.log的输出级别调成 verbose,这样能看到每个 API 调用的详细参数和返回值。虽然日志会很多,但排查问题时非常有用。
6. 从最小系统扩展到更复杂的板子
STM32F103C8T6 最小系统只是一个起点。这套“AI 生成描述文件 + EDA 脚本导入”的流程,稍微改改就能用在更复杂的项目上。
比如要画一个带 DHT11 温湿度传感器和 OLED 显示屏的板子,只需要在规格文件里加上 DHT11 的引脚定义(数据脚接 PA0,电源接 3.3V,地接 GND)和 OLED 的 I2C 接口定义(SCL 接 PB6,SDA 接 PB7),然后让 Claude Code 重新生成 JSON。校验脚本里加上“DHT11 数据脚必须有 4.7k 上拉电阻”的检查规则,就能保证生成的电路符合实际工程要求。
再比如要画一个 TB6612 电机驱动板,涉及 PWM 信号、方向控制信号、编码器反馈信号,网络连接更复杂。这时候可以在规格文件里定义一个“模块化”的结构,把电机驱动部分单独写成一个子规格,让 Claude Code 分模块生成,最后合并成一个完整的 JSON。这样 AI 的注意力不会被太多细节分散,生成质量更稳定。
对于 DDR4 这种高速电路,这套方案目前还不太适用,因为 DDR4 的布线规则、阻抗匹配、时序约束不是简单的网表能描述的。但如果是画 DDR4 的电源部分或者去耦电容阵列,用 AI 生成描述文件再导入,还是能省不少事。
7. 一些实操心得和后续可玩的方向
这套方案跑通之后,我最大的感受是:AI 不是用来替代你的,而是用来放大你的效率的。你依然需要懂 STM32 最小系统应该怎么画,需要知道去耦电容要放几个,需要清楚晶振负载电容怎么算。但你可以把这些知识写成规格文件,让 AI 去执行重复性的绘图操作。一次投入,后面每次画同类板子都能省下大量时间。
另一个心得是校验环节不能省。AI 生成的内容看起来再合理,也要用脚本过一遍。我现在的习惯是,校验脚本的规则库随着项目积累不断丰富,每踩一个坑就加一条检查规则。时间长了,这个校验脚本就成了一个“电路设计规范检查器”,比单纯依赖 AI 的自觉性靠谱得多。
后续可以玩的方向有几个。一是接入本地模型,把 Claude Code 换成调用本地部署的模型,这样在没网的环境下也能用,而且数据不出本地。二是做元件库的自动匹配,让脚本根据元件参数自动在嘉立创的库里搜索最合适的符号,而不是手动指定 libraryId。三是生成 PCB 布局建议,根据原理图的网络连接关系,让 AI 给出元件摆放和走线拓扑的建议,虽然不能全自动布线,但能提供一个不错的起点。
最后分享一个小技巧:在让 Claude Code 生成电路描述之前,先让它“复述”一遍你对电路的要求。比如你告诉它“STM32F103C8T6 最小系统,3.3V 供电,8MHz 晶振,SWD 下载”,让它用自己的话把关键点列出来。如果它复述的内容有遗漏或者理解偏差,你能在生成之前就发现,避免生成一大堆需要返工的内容。这个“先确认再执行”的习惯,能省下不少来回调试的时间。