Embedded HandbookПриложения
Все разделы › XVI. Печатная плата
STM32F103 · уровень средний · 14 мин чтения
Открыть в интерактивном справочнике

132в. DipTrace: проверки, панель и файлы для завода

Плата разведена — осталось убедиться, что она правильная, при необходимости размножить её на заготовке и отдать заводу файлы, по которым её изготовят. Этот раздел — о трёх проверках DipTrace, панелизации и о каждом файле выпуска: что в нём лежит и какие галочки при выгрузке важны. В конце — взгляд внутрь самих файлов: короткая программа читает Gerber и сверловку настоящей платы и показывает, что числа в разных файлах обязаны сходиться.

Меню и параметры сверены с руководством к установленной DipTrace 5.3 и со строками интерфейса Pcb.exe. Файлы для завода — выгрузка платы раздела 131 (её делает проверка того раздела); их разбирает _verify/dip132c/fabread.py. Сверяет _verify/dip132c_check.py.

Как это называется в документации

Оригинал Перевод
net connectivity check проверка целостности цепей
compare to schematic сравнение платы со схемой
panelizing панелизация: несколько плат на одной заготовке
V-scoring V-надрез: канавки для разлома панели
edge rail технологическое поле по краю панели
solder mask swell расширение окна маски вокруг площадки
drill symbols условные знаки отверстий на чертеже
aperture, flash апертура (форма «пера») и её отпечаток
file function (Gerber X2) назначение файла, записанное в нём самом

132в.1 Три проверки

Руководство советует прогонять все три — они ловят разные ошибки.

Проверка Меню Что находит
DRC Verification / Check Design Rules, F9 зазоры, размеры объектов, параметры дифференциальных пар
целостность цепей Verification / Check Net Connectivity разорванные и слитые цепи — через слои, заливки и фигуры
сравнение со схемой Verification / Compare to Schematic расхождения структуры цепей и неизвестные компоненты

DRC работает в двух режимах: обычном (по команде) и в реальном времени — красные круги появляются прямо при перемещении и трассировке. Даже если реальное время было включено всю работу, перед выгрузкой Gerber обычный прогон делают хотя бы раз.

Правила — Verification / Design Rules, вкладки Clearances, Sizes, Real-time DRC и Options. На вкладке Options выбирают, что проверять: правила между классами, выравнивание длин, заливки. Галочка Same Net Clearance включает проверку зазоров и внутри одной цепи.

В списке ошибок — текущее и требуемое значение, Localize показывает место на плате, а раздел Rule Details — где поправить правило. Красный круг — ошибка зазора, пурпурный — ошибка размера. Исправили — Run DRC прямо из окна списка.

Целостность цепей особенно нужна на многослойной плате с заливками: DRC проверяет расстояния, но не заметит, что заливка перерезала цепь на два куска или слила две цепи в одну.

Сравнение со схемой берёт исходный файл схемы и сверяет с ним плату — ловит правку, сделанную на плате, но забытую в схеме.

Сводку по плате — число объектов, слоёв, размеры платы и отверстий — показывает File / Layout Information; кнопка Show on Board в окне размеров отверстий подсвечивает на плате отверстия выбранного диаметра.


132в.2 Панель

Мелкие платы изготавливают и собирают не по одной, а панелью. Tools / Panelizing: пример руководства — 12 копий, 3 столбца × 4 строки, разделение V-надрезом (V-Scoring), расстояние между платами 0, по краю — технологическое поле Add Edge Rail по 0,2 дюйма (5,08 мм) с каждой стороны для заводской сборки.

Панель 3 × 4 из платы 45 × 32 мм: V-надрезы по границам плат, поля по 5,08 мм, габарит 145,16 × 138,16 мм

Разные платы на одной панели: включить Edit / Keep RefDes while Pasting, скопировать плату и вставить рядом. Контур и вырезы для панели рисуют общие. Любопытная деталь из руководства: при включённом Keep RefDes while Pasting ограничение числа выводов редакции DipTrace не действует — на бесплатной версии можно собрать панель из нескольких плат по 300 выводов.


132в.3 Файлы для завода

Файл Меню Главное при выгрузке
Gerber RS-274X File / Export / Gerber каждый слой — своим файлом; Export All — архив Gerber или Gerber вместе со сверловкой
Gerber X2 File / Export / Gerber X2 то же окно; в файле записано назначение слоя, порядок слоёв и функции площадок; сверловку может положить в Gerber-файлы, но большинство заводов ждут Excellon
сверловка File / Export / N/C Drill формат Excellon; Auto назначает инструменты; для сквозных отверстий выбраны все слои, для глухих — только пара слоёв стиля
ODB++ File / Export / ODB++ режим CAM350 или Mentor Graphics (версия ODB++ 8.1), Make Zip Archive
DXF File / Export / DXF все слои в один файл кнопкой Select All; для механики и для фрезеровки
файл установки File / Export / Pick and Place для автомата сборки: обозначение, координаты, угол и сторона каждой детали; CSV или текст; нуль — как у Gerber: Offset или Use Design Origin

Слои Gerber и их галочки.

Offset во всех окнах выгрузки — расстояние от нуля до левого нижнего угла платы: начало координат проекта или своё значение. У Gerber, сверловки и файла установки оно должно быть одинаковым, иначе отверстия «уедут» с площадок, а автомат поставит детали мимо них. Спецификацию для закупки и сборки выгружают отдельно — 132д.6.

Один Offset на выгрузку: слева нули Gerber, сверловки и файла установки совпадают и отверстия стоят в центрах площадок, справа нуль сверловки сдвинут на дельту — все отверстия уехали с площадок

Drill Symbols — отдельный файл с условными знаками отверстий и таблицей диаметров, некоторые заводы его просят. После выгрузки галочку снимают: иначе остальные слои выгрузятся пустыми.

Готовые файлы руководство советует открыть сторонним просмотрщиком Gerber — лучше тем же, которым пользуется завод: программы читают формат немного по-разному.


132в.4 Фрезеровка и печать дома

Фрезеровка. В окне DXF есть слои Edge_Top и Edge_Bottom — это не слои платы, а траектории фрезы вокруг меди. Для платы с трассами снизу выбирают Edge_Bottom и Mirror. Edge Width — ширина реза; осевая линия фрезы идёт на половине этой ширины. Если зазоры между объектами меньше ширины реза, DipTrace предупредит до выгрузки. Заливки в траектории не учитываются (термобарьеры — учитываются). Станку нужен G-код — DXF переводят в него отдельной программой.

Печать для самодельной платы — File / Preview: масштаб, слой, Mirror, Print in Black Only, выгрузка в PDF или картинку. Лазерный принтер слегка растягивает изображение от нагрева бумаги; в окне печати есть калибровка.


132в.5 Что внутри файлов

Форматы стандартные, поэтому заглянуть внутрь можно на любой плате. Файлы здесь выпустил KiCad из платы раздела 131, а не DipTrace: отсюда переходы 0,3 мм (у стиля Default в DipTrace отверстие 0,51 мм, 132б.3) и файл задания .gbrjob, которого в руководстве DipTrace нет. Команды Gerber и Excellon и правило «числа сходятся» от программы не зависят; у выгрузки DipTrace будут свои имена файлов и свой набор атрибутов X2.

Взяли плату раздела 131 (две стороны, LQFP-48, развязка, кварц), выгрузили восемь слоёв Gerber X2 и сверловку и прочитали их программой _verify/dip132c/fabread.py. Главное в ней — разбор команд Gerber:

aper_func, pending, cur, region = {}, None, None, False
for cmd in re.findall(r"%[^%]*%|[^%*]+\*", txt):
    cmd = cmd.strip()
    if cmd in ("G36*", "G37*"):                 # внутри G36…G37 отрезки — края залитой области
        region = cmd == "G36*"
        continue
    m = re.match(r"%TA\.AperFunction,([^,*]*)", cmd)
    if m:
        pending = m.group(1)
        continue
    m = re.match(r"%ADD(\d+)", cmd)
    if m:
        aper_func[int(m.group(1))] = pending or "?"
        info["apertures"] += 1
        continue
    if cmd.startswith("%TD"):
        pending = None
        continue
    m = re.match(r"(?:G54)?D(\d+)\*$", cmd)
    if m and int(m.group(1)) >= 10:
        cur = int(m.group(1))
        continue
    m = re.match(r"(?:X(-?\d+))?(?:Y(-?\d+))?(?:I-?\d+J-?\d+)?D0([123])\*$", cmd)
    if m:
        if m.group(1):
            info["xs"].append(int(m.group(1)) / 10 ** ndec)
        if m.group(2):
            info["ys"].append(int(m.group(2)) / 10 ** ndec)
        if m.group(3) == "3":
            info["flash"][aper_func.get(cur, "?")] += 1
        elif m.group(3) == "1":
            info["edges" if region else "draws"] += 1

Словарь Gerber небольшой. %FSLAX46Y46*% — координаты целыми числами, 4 знака до запятой и 6 после: X15262000 — это 15,262 мм. %MOMM*% — миллиметры. %ADD10C,0.100000*% — апертура 10: круг диаметром 0,1 мм. D03 — отпечаток апертуры в точке («вспышка» — так ставятся площадки), D01 — ведение апертуры по отрезку (так рисуются трассы и контуры), G36…G37 — залитая область. Атрибут X2 %TF.FileFunction,Copper,L1,Top*% прямо в файле говорит, что это верхняя медь, а %TA.AperFunction,SMDPad,CuDef*% перед апертурой — что ею ставят площадки SMD.

Площадки платы раздела 131 и их число в каждом файле выпуска

Что получилось:

Файл Назначение (X2) Вспышки Отрезки Области
верхняя медь Copper,L1,Top 74 SMD + 6 выводных + 4 перехода = 84 10 0
нижняя медь Copper,L2,Bot 6 выводных + 4 перехода = 10 0 1 (края — 356 отрезков)
верхняя маска Soldermask,Top 80 0 0
нижняя маска Soldermask,Bot 6 0 0
верхняя паста Paste,Top 74 0 0
контур Profile,NP — 4 0
Сверловка Диаметр Отверстий Назначение
T1 0,30 мм 4 Plated, ViaDrill
T2 1,00 мм 6 Plated, ComponentDrill

Числа в разных файлах обязаны сходиться, и это удобная ручная проверка выгрузки:

Нижняя медь — заливка земли: одна область G36…G37, край которой описан 356 отрезками — вместе с вырезами вокруг чужих площадок и лучами термобарьеров. Трасс снизу нет ни одной: все 10 отрезков-трасс — на верхней меди.

Строки Gerber по полям и три способа положить медь: вспышка D03, отрезок D01 и область G36…G37 с числами платы раздела 131


132в.6 Грабли

Реального времени DRC хватило — обычный прогон не делали. Реальное время могло быть выключено для части действий. Перед выгрузкой — F9.

DRC чист, а плата не работает. Заливка разрезала цепь: это ловит проверка целостности цепей, а не DRC.

Плату поправили, схему — нет. Compare to Schematic покажет расхождение.

Панелизация не включается. Нет контура платы.

Переходы остались без маски и собрали припой. В слое маски стояла галочка Vias. Для маски её снимают, для меди — ставят.

Все слои после Drill Symbols — пустые. Галочку Drill Symbols не сняли после выгрузки знаков.

Отверстия смещены относительно площадок. Разный Offset у Gerber и сверловки.

Автомат поставил детали мимо площадок. Разный Offset у Gerber и файла установки.

Завод вернул файлы: «нет сверловки». Выгрузили Gerber без N/C Drill. Export All умеет положить оба в один архив.

Фреза «съела» заливку. Заливки в траекториях фрезеровки не учитываются — для фрезерованной платы заливку лучше не делать.

Числа не сходятся. Паста не равна числу SMD-площадок, маска — числу площадок: где-то своё окно маски, SMD на нижней стороне или переходы без маски. Разбираться до отправки на завод.


132в.7 Итоги

Полные исходники

fabread.py — чтение файлов Gerber и сверловки Excellon с подсчётом по слоям.

# -*- coding: utf-8 -*-
"""Читает файлы для завода: Gerber (RS-274X с атрибутами X2) и сверловку Excellon.

    python fabread.py каталог_с_файлами
Печатает по каждому слою: назначение (TF.FileFunction), формат координат, число апертур,
вспышек (D03) по назначению площадки, отрезков (D01) и областей (G36); по сверловке —
инструменты и число отверстий; по контуру — габарит платы."""
import collections
import os
import re
import sys


def gerber(path):
    txt = open(path, encoding="ascii").read()
    fs = re.search(r"%FSLAX(\d)(\d)Y(\d)(\d)\*%", txt)
    ndec = int(fs.group(2))
    info = {"function": re.search(r"%TF\.FileFunction,([^*]*)\*%", txt).group(1),
            "units": "мм" if "%MOMM*%" in txt else "дюймы",
            "format": "%s.%s" % fs.group(1, 2),
            "apertures": 0, "flash": collections.Counter(), "draws": 0, "edges": 0,
            "regions": txt.count("G36*"), "xs": [], "ys": []}
    aper_func, pending, cur, region = {}, None, None, False
    for cmd in re.findall(r"%[^%]*%|[^%*]+\*", txt):
        cmd = cmd.strip()
        if cmd in ("G36*", "G37*"):                 # внутри G36…G37 отрезки — края залитой области
            region = cmd == "G36*"
            continue
        m = re.match(r"%TA\.AperFunction,([^,*]*)", cmd)
        if m:
            pending = m.group(1)
            continue
        m = re.match(r"%ADD(\d+)", cmd)
        if m:
            aper_func[int(m.group(1))] = pending or "?"
            info["apertures"] += 1
            continue
        if cmd.startswith("%TD"):
            pending = None
            continue
        m = re.match(r"(?:G54)?D(\d+)\*$", cmd)
        if m and int(m.group(1)) >= 10:
            cur = int(m.group(1))
            continue
        m = re.match(r"(?:X(-?\d+))?(?:Y(-?\d+))?(?:I-?\d+J-?\d+)?D0([123])\*$", cmd)
        if m:
            if m.group(1):
                info["xs"].append(int(m.group(1)) / 10 ** ndec)
            if m.group(2):
                info["ys"].append(int(m.group(2)) / 10 ** ndec)
            if m.group(3) == "3":
                info["flash"][aper_func.get(cur, "?")] += 1
            elif m.group(3) == "1":
                info["edges" if region else "draws"] += 1
    return info


def excellon(path):
    tools, holes, cur = {}, collections.Counter(), None
    func = {}
    last = None
    for line in open(path, encoding="ascii"):
        line = line.strip()
        m = re.match(r"; #@! TA\.AperFunction,(.*)", line)
        if m:
            last = m.group(1)
        m = re.match(r"T(\d+)C([\d.]+)$", line)
        if m:
            tools[int(m.group(1))] = float(m.group(2))
            func[int(m.group(1))] = last
            continue
        m = re.match(r"T(\d+)$", line)
        if m:
            cur = int(m.group(1))
            continue
        if re.match(r"X-?[\d.]+Y-?[\d.]+$", line):
            holes[cur] += 1
    return tools, holes, func


if __name__ == "__main__":
    d = sys.argv[1]
    for fn in sorted(os.listdir(d)):
        p = os.path.join(d, fn)
        if fn.endswith(".drl"):
            tools, holes, func = excellon(p)
            for t in sorted(tools):
                print("%-22s T%d ⌀%.2f мм — %d отв. (%s)" % (fn, t, tools[t], holes[t], func[t]))
        elif not fn.endswith(".gbrjob"):
            g = gerber(p)
            size = ""
            if g["function"].startswith("Profile"):
                size = " габарит %.2f × %.2f мм" % (max(g["xs"]) - min(g["xs"]), max(g["ys"]) - min(g["ys"]))
            print("%-22s %-22s %s %s апертур %2d вспышек %s отрезков %d областей %d (краёв %d)%s" % (
                fn, g["function"], g["format"], g["units"], g["apertures"], dict(g["flash"]), g["draws"],
                g["regions"], g["edges"], size))

Дальше: раздел 132г «DipTrace: скоростные цепи, дифференциальные пары, переходы к заливкам».

Открыть в интерактивном справочнике