Files
skills-win/kicad-flow/scripts/schgen/README.md
T
2026-10-15 01:59:40 +08:00

101 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# schgen —— kicad-flow 的原理图 / 封装生成库
`n10_draw_schematic`、`n23_assign_footprints`、`d11/d20` 排版检查用。由两块真实板子的生成脚本通用化而来:
ipots_tunerX10 载板(`E:\Kicad_design\ipots_tunerX10\carrier\gen`,9 页 / 327 器件)与
DVBS2_dmod tuner 子板(`E:\Kicad_design\DVBS2_dmod\carrier\gen`,4 页 / 78 器件,**最小完整示例,先看这个**)。
思路:**原理图由工程里的 python 脚本生成,不手画**。所有坐标由符号真实外框推出,
画什么就同步登记一个占位矩形,最后逐对查重叠/越界,有问题不写文件。改电路改脚本重跑。
## 模块
| 模块 | 干什么 | 跑它用的 python |
|---|---|---|
| `env` | 读 `~/skills_env.md`:`KICAD_ROOT`(必需)、`CHROME_EXE`(可选) | 任意 |
| `kicad_lib` | `.kicad_sch` 底层:符号提取(含 extends 展开)/ 外框 / 旋转 / `Sheet` 写文件;`register_lib()` 登记工程符号库 | 任意 |
| `layout` | `Canvas`:占位登记 + 重叠/越界检查(中文按 1.3 字宽估,G-0034) | 任意 |
| `page` | `Project` / `Page`:画图原语,见下 | 任意 |
| `symgen` | `box_symbol()` 按引脚表生成方框符号(每边可不同间距);`grab_from_sch()` 从参考 `.kicad_sch` 抽符号 | 任意 |
| `diagram` | drawio → PNG(SVG 外壳直接截;纯 XML 用 diagrams.net viewer 在 headless Chrome 渲染,需联网) | 任意 |
| `root` | 根图:层次页符号 + 内嵌框图 PNG(300DPI 反算 scale,G-0022);`.kicad_pro`;`sym/fp-lib-table` | 任意 |
| `check` | `python -m schgen.check <根图>`:ERC、网表器件数、**封装↔引脚一一对应**、子电路画法(G-0035/37) | 任意 |
| `fplib` | `FpLib`:按位号从参考 `.kicad_pcb` 提取封装 / 从 KiCad 官方库拷贝 | **KiCad 自带 python**(要 pcbnew) |
| `pcbimport` | n101:从网表建板(封装按页排停车场 + 挂网)并**逐焊盘验收**。代替不可信的 MCP `sync_schematic_to_board`(G-0039) | **KiCad 自带 python** |
| `pcbplace` | 布局:圆角板框、按占地中心摆放、正反面、实物禁布区(护套等)、占地重叠/出板检查(跨面只比通孔焊盘)、**自动摆位号** `place_refs()`、JLC 4 层叠层、出正反面 PNG | **KiCad 自带 python**(出图转 PNG 会找装了 fitz 的系统 python) |
在工程脚本里:
```python
import os, sys
sys.path.insert(0, os.path.expandvars(r"%USERPROFILE%\.claude\skills\kicad-flow\scripts"))
from schgen import Project, register_lib, R, C, L, GND, snap
```
## 画图原语(`Page`)
两脚无源件**必须画进它服务的电路里**(G-0035/G-0037),别摆空地两头挂标签:
| 原语 | 用途 |
|---|---|
| `comp(lib, ref, val, x, y, rot, fields=...)` | 放件;位号撞车直接报错(G-0028)。`fields`:above/left/right/top/none 或 `("xy", rx, ry, vx, vy)` |
| `inline(x0, y0, lib, ...)` / `vline(...)` | 在水平 / 竖直线上**串**一个件,返回线的另一端 |
| `shunt(bx, by, lib, ..., net, down=True)` | 从母线一点挂下(上)一个件到电源/地:退耦、上下拉 |
| `run_taps(px, py, ux, stops, net)` | 沿线打一串抽头挂 shunt,末端出标签 |
| `fan_series(...)` | 一组引脚各串一个件、排成一列(引脚距与件距不同时用) |
| `gnd_bus` / `gnd_row` | 多个地脚并一根母线只落一个地符号 |
| `stub(cx, cy, pp, pin, net, stagger)` | 引脚拉线接标签/电源符号;排针上相邻电源脚用 stagger 错开 |
| `dot` / `seg` / `path` / `nc_pin` / `frame` / `text` | 丁字接点(G-0036)/ 线段 / 折线 / 断路标记 / 虚线框(留位不贴)/ 注释 |
| `finish()` | 有重叠或越界:打印并**不写文件** |
二极管等横放符号竖着挂时传 `rot=90/270`(`D_Schottky` 1 脚=K:`rot=270` 时 K 在上)。
## 标准流程(DVBS2_dmod 就是这么跑的)
1. `gen/gen_sch.py`:`make_lib()`(box_symbol / grab_from_sch → `lib/<prj>.kicad_sym`)→ 每页一个函数 →
`render()` 框图 → `write_root()` → `write_project()` → `write_lib_tables()`
2. `python -m schgen.check <根图>`:ERC 0、器件数对得上、子电路 A/B 级 0
3. `kicad-cli sch export pdf` → 用 fitz 渲染 PNG **逐页看图**(检查器不管"挤",只管"压")
4. n23:`<KICAD_PYTHON> gen/mkfp.py`(FpLib 从参考 PCB 按位号取件 + 自画件),
`gen_sch.py` 里 `fp_resolver` 按**数值**查表、按位号覆盖;再跑一次 check 看封装一行
5. n101:`<KICAD_PYTHON> -m schgen.pcbimport <根图> <板.kicad_pcb> [--layers 4]`(在 scripts 目录下跑),
输出最后一行"问题 0"才算导入成功。它每次重建整块板(DNP/不进 BOM/MPN 等字段一起同步)
6. 布局:工程里写 `gen/place.py`(示例见 DVBS2_dmod),用 `Placer` 按"板内坐标"摆件,
`check()` 为 0 后再 `kicad-cli pcb drc --schematic-parity`。建板 → 布局两步都是脚本,
改原理图后可以一路重跑;**一旦开始手工布线就别再跑 pcbimport**(它会重建空板)
布局经验(DVBS2_dmod):先按信号流分区再摆件——并行总线让源端引脚与连接器引脚同序对齐,
串阻排一行;开关电源回路(LX→二极管→BOOST 电容→PGND)收在芯片一角;DNP 的留位件
(如 2.x 的大电感)可以放背面;金属壳 NIM 的正下方背面可以放它自己电源脚的 0402 去耦
## 坑(已在代码里处理,改代码前先看)
- `justify center` 会让整页静默解析失败,网表空、ERC 0(G-0018)→ 判断读没读进去看**网表器件数**
- 标签角度只有 0/90,180/270 会反向压元件;字段角度要补偿元件旋转(G-0019)
- 取 unit 时要带 `NAME_0_x` 公共图形(G-0019)
- KiCad 库的 `(extends ...)` 派生符号要展开,属性块有嵌套括号必须配平替换,否则 ERC 报 lib_symbol_mismatch
- 连接器是 passive 脚,`PWR_FLAG` 放在电源进线连接器旁;稳压器 OUT 多脚时只留一个 power_out,
其余 passive,否则 ERC 报 power_out 对 power_out
- `run_taps` 的每个挂件元组必须带另一端网络(第 6 项);`run_taps(net=None)` 之后若又手动把线往外延,
最后一个抽头点要自己补 `dot()`(check 的 C 级会报"丁字口缺接点")
- 检查器的字宽按 1.2mm/字(ASCII)估:0.9、1.1 都在实板上漏报过数值文字压隔壁件;
检查器只管"压"不管"挤",出图目视 + 独立 agent 复核仍然必要
- 改 `sym-lib-table`/`fp-lib-table` 后要**整个退出 KiCad 再开**才生效(G-0020)
- KiCad 通用连接器符号(`Connector_Generic:Conn_*`)自带 `ki_fp_filters`(如 `Connector*:*_1x??_*`),
封装选择器默认勾着"Apply footprint filters",工程库里的座子(从参考设计提取的 VH3.96-2P、IDC20_2MM)
会被藏掉,用户看到的是"这个件没有封装"。做法:`set_fp_filter(src, "库:名*")` 后
`rename(symbol_def(src), src, 新名)` 拷进工程符号库再用(示例见 DVBS2_dmod 的 make_lib)。
**不要**直接覆盖内嵌的通用符号——ERC 会报 lib_symbol_mismatch
- `kicad-cli pcb drc --schematic-parity` 对**脚本生成的原理图 + pcbimport 建的板**,会在所有无名网络
(`Net-(...)`)的焊盘上报 net_conflict "No corresponding pin found in schematic"(ipots 199 条、
DVBS2 85 条),有名网络一条不报;pcbimport 的逐焊盘验收(按 kicad-cli 导出的网表)全部一致。
根因未查清,按已知告警处理,在 KiCad 界面里按一次 F8 再确认
- 圆角板框要用 `SetArcGeometry(起, 中, 止)` 三点法;只给圆心+起止点,弧可能绕远路穿过板内
- pcbnew `SetField()` 新建的字段默认可见,会被印成丝印,必须 `GetField(k).SetVisible(False)`
- **丝印(位号)**:`place_refs(size=0.8, thick=0.15, prefer={...})` 按"离器件近、横移小"的代价
顺序找位置,要求不压任何器件占地(含自己)、焊盘、丝印图形、已摆位号、板边;数值统一挪到 Fab。
用 KiCad 真实文字外框算碰撞——0.8mm 字高的位号外框实测 3.38 x 1.46mm(竖写 1.46 宽),
所以**要竖写位号的缝至少留 1.8~1.9mm**,一排 0402 想统一竖写在正上方,间距要 ≥1.7mm。
摆不下的会列出来:那是布局问题(器件之间没给位号留地方),去改布局,别缩字号。
验收看 `kicad-cli pcb drc` 的 silk_over_copper / silk_overlap / silk_edge_clearance 三类都为 0
- 判断工程封装库有没有加载:选择器标题里的总数 = KiCad 自带(10.0 为 15435)+ 全局额外库 + 工程库