203. ЭМС изделия: помехи, стойкость и проверка в мастерской
Прибор работает на столе — и это ничего не говорит о том, как он поведёт себя рядом с контактором, под рацией монтажника или после зимней куртки и дверной ручки. Электромагнитная совместимость — последний экзамен изделия, и сдают его дважды: изделие не должно мешать соседям и не должно падать от их помех. Выводы уже защищены (раздел 62), вход питания собран (раздел 173); здесь — картина целиком: кто в приборе шумит, что в него прилетает, как строится оборона от корпуса до прошивки и что из этого можно проверить в мастерской до платной лаборатории.
Числа раздела — расчёты _verify/emc203/wave_calc.py, спектр фронтов —
ряд Фурье spectrum.py, разряд и наводка — модели ngspice в контейнере
stm-lab:1, сторож конфигурации — собран и прогнан на ПК и собран
для Cortex-M3 в stm-arm:1; скорости выводов — из заголовков паков.
Как это называется в документации
Оригинал Перевод electromagnetic compatibility (EMC) электромагнитная совместимость: не мешать и выдерживать electromagnetic interference (EMI) электромагнитная помеха radiated / conducted emission излучение в эфир / помеха, уходящая по проводам immunity, susceptibility стойкость к помехам, восприимчивость contact / air discharge контактный разряд / разряд через воздух electrical fast transient (EFT), burst пачки наносекундных импульсов surge выброс: длинный импульс большой энергии voltage dip, short interruption провал и кратковременное пропадание питания pre-compliance testing предварительная проверка до формальных испытаний pigtail «косичка»: хвостик, которым экран кабеля подпаян к земле
203.1 Две стороны ЭМС: сам шумишь — и тебя глушат
У задачи два зеркальных лица. Эмиссия: тактовые фронты, импульсный преобразователь и кабели изделия излучают и гонят помеху в сеть — за это изделие бракуют на испытаниях, даже если само оно работает безупречно. Стойкость: разряд статики с руки, пачки от искрящих контактов, выброс в проводке и провал сети — от этого изделие виснет, врёт и перезапускается у заказчика.
Помеха ходит двумя путями: по проводам (кондуктивно) и через поле (излучение и наводка). Ниже десятков мегагерц главный путь — провода, выше — эфир; граница размыта, потому что кабель, по которому помеха пришла кондуктивно, тут же работает передающей антенной.
Карта угроз конкретного прибора составляется за вечер: выписать все кабели (питание, интерфейсы, датчики), всё, чего касается человек (корпус, кнопки, разъёмы), всё, что искрит и коммутирует рядом (реле, контакторы, двигатели), и все свои источники шума (тактовые, шины, импульсник). Дальше по разделу видно, что почти каждая пара «источник → жертва» закрывается одним из типовых средств.
203.2 Кто в приборе излучает: фронты, тактовые, кабели
Излучает не «частота 72 МГц», а фронты. Меандр — это нечётные
гармоники: 72, 216, 360 МГц и дальше; их амплитуда спадает медленно,
пока частота не дойдёт до излома огибающей 1/(π·t_фронта) — при фронте
1 нс это 318 МГц, при 5 нс — 64 МГц. Выше излома спектр валится быстро,
поэтому чем медленнее фронт, тем короче хвост гармоник. Ряд Фурье
трапеции 3,3 В на 72 МГц (spectrum.py, ДПФ сходится с аналитической
формулой лучше 2 %):
| Гармоника | Частота | Фронт 1 нс | Фронт 5 нс | Спад |
|---|---|---|---|---|
| 1 | 72 МГц | 2,083 В | 1,681 В | 1,9 дБ |
| 3 | 216 МГц | 0,648 В | 0,051 В | 22,0 дБ |
| 5 | 360 МГц | 0,336 В | 0,044 В | 17,7 дБ |
| 9 | 648 МГц | 0,102 В | 0,016 В | 16,3 дБ |
Первая гармоника — сам сигнал — почти не изменилась, а хвост упал
на порядок. Отсюда правило: скорость выводов — минимально
достаточная. У F1 она задаётся в конфигурации вывода — 2, 10 или
50 МГц (перечисление GPIO_Speed_… в заголовке пака), у F4 и младше —
регистром OSPEEDR. «50 МГц» на выводе, который щёлкает светодиодом,
— бесплатный передатчик.
Сам по себе сантиметровый проводник на плате излучает слабо — плохи
кабели: провод длиной в четверть волны — уже настроенная антенна.
Длина волны λ = c/f:
| Частота | λ | λ/4 |
|---|---|---|
| 72 МГц | 4,16 м | 1,04 м |
| 216 МГц | 1,39 м | 34,7 см |
| 360 МГц | 0,83 м | 20,8 см |
Метровый кабель питания — четвертьволновая антенна прямо на тактовой частоте, а тридцатисантиметровый хвостик к датчику — почти антенна для пятой гармоники. Раскачивает антенну синфазный ток — тот, что течёт по всем жилам кабеля в одну сторону и возвращается через ёмкость на окружение: оценка по формуле короткого диполя даёт от 5 мкА синфазного тока на 30-см кабеле на 216 МГц поле около 68 мкВ/м в трёх метрах — порядок допустимого для бытовой обстановки. Микроамперы! Поэтому синфазный дроссель или ферритовая бусина на кабеле (раздел 168) делают для эмиссии больше, чем любая правка схемы.
Третий источник — импульсный преобразователь (раздел 58): сотни килогерц коммутации и гармоники до десятков мегагерц. Его лечат на плате: минимальная площадь горячей петли и сплошная земля под ней (разделы 130, 181), а скоростные цепи и возвраты токов — раздел 132г.
⚠️ Частоту не спрятать, фронт — можно. Тактовую вниз не сдвинешь — она нужна работе. А фронты почти всегда быстрее, чем требует схема: и у GPIO, и у SPI, и у затвора ключа импульсника (там фронт задаёт резистор затвора). Замедление фронтов — первое и самое дешёвое средство.
203.3 Стойкость: разряд, пачки, выброс, провал
Испытания на стойкость выглядят по-разному, но каждое имитирует конкретное событие из жизни изделия.
Разряд статики. Человек в сухом помещении — заряженный конденсатор:
модель испытательного генератора — 150 пФ, заряженные до единиц-десятков
киловольт, разряжаемые через 330 Ом (рука с металлическим предметом).
Модель ngspice esd.cir при 8 кВ: пик тока 24,2 А, спад до 1/e
за 49,5 нс, в резисторе выделилось 4,8 мДж — интеграл сошёлся
с формулой E = CU²/2 = 0,5 · 150 пФ · (8 кВ)² = 4,8 мДж
(Ф·В² = Кл·В = Дж — размерность сходится). Пиковая мощность —
U²/R ≈ 194 кВт: миллиджоули, но за наносекунды. Это в 24 раза больше
энергии, чем в модели человеческого тела из паспорта микросхемы, —
почему встроенной защиты не хватает, разобрано в 62.8. Разряд бьёт во
всё, чего касается человек: корпус, кнопки, разъёмы, — причём контактный
разряд злее разряда через воздух: у него нормированный наносекундный
фронт со спектром до гигагерц.
Пачки. Каждый контактор и реле в щите при размыкании индуктивной
нагрузки искрит серией наносекундных импульсов. Катушка небольшого реле
(100 мГн, 30 мА) хранит всего 45 мкДж, но без гасящей цепи разрыв
раскачивает контур катушки до U = I·√(L/C) ≈ 2,1 кВ — и искра
повторяется, пока контакты расходятся. Энергия каждого импульса
ничтожна, страшен фронт: модель coupling.cir прикладывает фронт
300 В за 5 нс к «чужому» проводу, лежащему в одном жгуте с нашим
(10 пФ ёмкости между ними):
| Куда пришло через 10 пФ | Пик на линии |
|---|---|
| высокоомный вход, подтяжка 10 кОм | 293 В |
| линия с нагрузкой 100 Ом | 60 В |
| 100 Ом плюс конденсатор 1 нФ | 2,9 В |
| тот же фронт, но за 1 мкс, на 100 Ом | 0,3 В |
Три вывода из одной таблицы: наносекундный фронт пролезает через
пикофарады (i = C·dU/dt = 10 пФ · 60 В/нс = 0,6 А); высокоомные входы
беззащитны, низкоомные — в пять раз лучше, а конденсатор у входа гасит
наводку в сто раз; медленному выбросу те же 10 пФ безразличны.
Выброс. Микросекундно-миллисекундный импульс от коммутации мощных нагрузок и грозовых наводок: напряжение ниже, чем у статики, но энергия — уже не милли-, а джоули. Его встречает не вывод МК, а вход платы: ограничитель, предохранитель и их правильный порядок — раздел 173.
Провал и пропадание питания. Сеть «моргает» на полпериода-период: прибор должен либо прожить это на запасённой энергии, либо корректно перезапуститься — но не зависнуть и не испортить данные во флеш. Что из этого выбрано — решение, которое надо принять и записать до испытаний, а не после.
203.4 Первая линия обороны: вход питания, интерфейсы, корпус
Общий принцип: помеху встречают на границе, пока у неё один путь внутрь, а не десять.
Вход питания — цепочка из раздела 173: предохранитель, защита от переполюсовки, ограничитель, за ним фильтр и стабилизатор. Провал сети держит накопительный конденсатор: 1000 мкФ, разряжаемые нагрузкой 1 Вт от 12 до 8 В, дают 40 мс — период сети с запасом. Дольше — уже не конденсатор, а осознанное «перезапустимся»: детектор просадки PVD (раздел 10.7) успевает предупредить прошивку, чтобы та дописала журнал и не начинала запись во флеш.
Интерфейсы. Всё, что уходит с платы, получает последовательный резистор и ограничитель у разъёма (разделы 62.3, 62.9), длинные и межблочные линии — RS-485 со своими защитами (раздел 89.4), самое злое окружение — гальваническую развязку (раздел 54). От синфазной помехи и для эмиссии — синфазный дроссель или бусина на кабель (раздел 168). Конденсатор в единицы нанофарад у входа — та самая строка «2,9 В вместо 293 В» из таблицы выше.
Корпус и земля. Металлический корпус — экран и приёмник разряда: статика уходит в него, минуя схему, — если земля платы соединена с корпусом у разъёмов и путь разряда не проходит через плату. Правила, которые дают большую часть результата:
- все кабели входят с одной стороны корпуса — иначе помеха, вошедшая слева, выйдет справа насквозь через плату;
- экран кабеля садится на корпус по окружности или хвостиком короче
сантиметра. «Косичка» 10 см — это около 100 нГн; на фронте разряда
24 А/нс она поднимет землю экрана на
U = L·di/dt≈ 2,4 кВ — экран превращается в инжектор помехи; - щель в экране — антенна: прозрачна для волн, чья λ/2 сравнима с её длиной (15-см щель «настроена» на 1 ГГц — как раз спектр разряда); крышки и стыки соединяют чаще, ряды переходных сшивают полигоны (раздел 132г.7);
- земля — сплошная, обратные токи — под своими сигналами (разделы 130, 181).
🔧 Заложить оборону заранее. Посадочные места под ограничители, бусины и RC у каждого разъёма разводят на плате с первой версии — не запаяны, стоят ноль. Если лаборатория найдёт проблему, доработка — паяльник и час, а не новая плата и месяц.
203.5 Прошивка, которая переживает помеху
Электроника гасит энергию, но часть помех доходит до кристалла — и тогда изделие спасает прошивка. Её оборона — три эшелона.
Сторож (раздел 12) — последний рубеж: независимый IWDG перезапустит намертво зависшую программу. Но сброс — это признание поражения на десятки миллисекунд: для счётчика это потерянные импульсы, для регулятора — рывок. Поэтому выше сторожа стоит второй эшелон.
Сверка конфигурации периферии. Помеха умеет перещёлкнуть бит в регистре конфигурации: программа цела, цикл крутится, сторож сыт — а UART молчит, потому что у него сбросился делитель. Регистры конфигурации не защищены ничем, кроме прошивки, — значит, после полной инициализации снимается эталон, а в главном цикле он сверяется:
enum { NCFG = 8 };
volatile uint32_t *cfg_addr[NCFG]; /* что охраняем: заполняется при инициализации */
static uint32_t cfg_good[NCFG]; /* эталон после инициализации */
static uint32_t cfg_ref; /* его контрольная сумма */
void cfg_snapshot(void) /* вызвать после полной инициализации */
{
for (int i = 0; i < NCFG; i++)
cfg_good[i] = *cfg_addr[i];
cfg_ref = cfg_crc();
}
int cfg_guard(void) /* из главного цикла, раз в десятки мс */
{
if (cfg_crc() == cfg_ref)
return 0; /* всё на месте — дёшево: одна сумма */
int fixed = 0;
for (int i = 0; i < NCFG; i++)
if (*cfg_addr[i] != cfg_good[i]) {
*cfg_addr[i] = cfg_good[i]; /* вернуть как было */
fixed++;
}
return fixed; /* и записать событие в журнал */
}
В cfg_addr[] кладут адреса регистров конфигурации — GPIOA->CRL,
USART1->CR1, — только конфигурацию, не данные и не флаги. Прогон
_verify/emc203/emc_guard.c на ПК: подмена одного бита обнаружена
и восстановлена за один вызов, подмена в двух регистрах — «восстановлено
регистров: 2», контрольная сумма после ремонта совпала. Для Cortex-M3
весь механизм собрался в 172 байта кода и 68 байт ОЗУ.
Восстановление того, что снаружи. Разряд посреди транзакции I²C оставляет ведомого с зажатой SDA — шину оживляют тактами вручную (рецепт 17.6). Приёмник UART после помехи пересинхронизируют по ошибке кадра. Кварц, задушенный помехой, подхватывает система защиты тактирования: она переводит МК на внутренний генератор (раздел 6). Входы читают трижды и берут совпавшее большинство, а состояние критичных выходов периодически перезаписывают — как и конфигурацию.
⚠️ Каждый сброс — в журнал. Флаги причины сброса (раздел 12.4)
и счётчик срабатываний cfg_guard в энергонезависимой памяти
или телеметрии (раздел 190) — единственный способ узнать, что прибор
у заказчика ловит помеху раз в час. Прибор, который «просто иногда
моргает», — это прибор, который молча перезапускается.
203.6 Проверка в мастерской: зажигалка, реле, приёмник
До лаборатории грубые дыры находятся подручными средствами — если честно понимать, что они показывают, а что нет.
Пьезозажигалка — генератор разряда. Пьезоэлемент без горелки даёт искру 3–4 мм; воздух пробивается примерно при 3 кВ/мм, то есть это импульс порядка 9 кВ — уровень серьёзного испытания. Щёлкать по корпусу, возле кнопок, в разъёмы, вдоль щелей; прибор при этом работает, а рядом человек смотрит на поведение.
🔧 Как щёлкать. Сначала — косвенный разряд: искра в металлическую пластину, стоящую в паре сантиметров от изделия; потом — в корпус и металл разъёмов; в последнюю очередь — рядом с пластиковыми кнопками и швами. В открытую плату без корпуса не разряжать вовсе: живой кристалл такой опыт переживает не всегда, а изделие испытывают в сборе — как его увидит человек с наэлектризованной рукой.
Реле — генератор пачек. Реле, коммутирующее собственную катушку через свой же размыкающий контакт, — классический зуммер: контакты искрят непрерывно, и без гасящей цепи каждый разрыв — звон в киловольты (расчёт из 203.3: около 2,1 кВ). Пару витков провода от этого «стенда» вокруг жгута изделия — и видно, переживают ли интерфейсы наносекундные фронты. Провал сети имитируется проще всего: выдернуть и воткнуть вилку, отпустить кнопку блока питания на полсекунды — и смотреть, перезапустился ли прибор корректно.
Приёмник — индикатор эмиссии. АМ-приёмник средних волн, дешёвая рация или SDR-свисток рядом с платой слышат «пение» импульсника и тактовых. Абсолютный уровень так не измерить, но сравнение «до/после» работает отлично: замедлили фронты, надели бусину, закрыли крышку — шипение в приёмнике упало или нет.
| Стенд | Что имитирует | Чего НЕ покажет |
|---|---|---|
| пьезозажигалка | разряд статики ~9 кВ | нормированные ток и фронт; «сколько кВ держим» |
| реле-зуммер у жгута | пачки от контакторов | уровень связи с реальной проводкой |
| дёрганье вилки | провал и пропадание сети | форму и фазу нормированного провала |
| приёмник у платы | излучение в ближнем поле | абсолютный уровень, дальнее поле, весь диапазон частот |
⚠️ Домашний стенд ловит провалы в обороне, а не подтверждает запас. Ни один из этих опытов не нормирован: энергия зажигалки не равна энергии испытательного пистолета, связь реле со жгутом — произвольная. «У нас дома всё прошло» означает «грубых дыр нет», и только.
203.7 Когда в лабораторию и что взять с собой
В лабораторию идут, когда изделие продаётся или встраивается в чужие системы: перечень формальных испытаний зависит от рынка и класса изделия, а домашняя проверка из 203.6 экономит платные часы — на нормированном стенде дорого искать то, что нашлось бы зажигалкой.
Собранный к поездке набор отличает подготовленную команду:
- две-три единицы изделия со штатными кабелями штатной длины и всеми крышками: другой кабель — другая антенна, и результат не повторится;
- прошивка для испытаний: индикатор «жив / перезапустился / восстановился сам», журнал сбросов и срабатываний сверки конфигурации — иначе кратковременный сбой на стенде никто не заметит;
- письменные критерии: что считается нормой при каждом виде воздействия. Исходов три — не заметил; сбился и восстановился сам; нужен человек. Какой исход допустим для какого воздействия — решение разработчика, принятое до испытаний;
- паяльник и коробка доработок: бусины, ограничители, конденсаторы, перемычки — под посадочные места, заложенные в 203.4; полдня на стенде с паяльником заменяют месяц переписки;
- время на повтор: после любой правки платы испытания повторяют — это закладывают в план и бюджет, а не открывают с удивлением.
203.8 Грабли
На столе всё проходит, у заказчика падает. Кабель — часть антенны: другой длины и укладки хвост меняет и эмиссию, и стойкость; λ/4 для пятой гармоники 72 МГц — всего 21 см. Испытывать со штатными кабелями, уложенными по-боевому.
Сторож перезапускает, а прибор всё равно «мёртв». Помеха перещёлкнула регистр конфигурации: цикл крутится, сторож сыт, периферия молчит. Нужна сверка и восстановление конфигурации (203.5), а не только IWDG.
Экран есть — толку нет. Экран кабеля подпаян «косичкой» 10 см: это ~100 нГн, и фронт разряда поднимает землю экрана на ~2,4 кВ. Экран — на корпус у самого входа, коротко или по окружности.
Разряд в пластиковую кнопку валит прибор. Пробой идёт не сквозь пластик, а по щели вокруг кнопки к дорожкам за ней: при ~3 кВ/мм восьми киловольт хватает почти на 3 мм воздуха. Дорожки и контакты отводят от щелей, щели закрывают.
Замедлили фронты — интерфейс перестал успевать. Скорость вывода — минимально достаточная, а не минимальная: фронт входит в бюджет времени сигнала, у быстрых шин — жёстко (раздел 132г).
«Развязали» землю разрезом — помех стало больше. Обратный ток пошёл в обход разреза большой петлёй, петля стала антенной (раздел 181). Сплошная земля почти всегда лучше художественных разрезов.
Импульсник шумит только под нагрузкой. На холостом ходу преобразователь пропускает импульсы и токи малы; слушать приёмником и снимать эмиссию — под рабочей нагрузкой.
203.9 Итоги
- ЭМС — две стороны: эмиссия (не мешать) и стойкость (не падать); пути — провода и поле, ниже десятков МГц главный путь — провода.
- Излучают фронты: растяжка фронта 72-МГц меандра с 1 до 5 нс роняет
третью гармонику на 22 дБ, пятую на 17,7 дБ, сигнал — на 1,9 дБ;
излом огибающей
1/(π·t_фронта)— 318 МГц при 1 нс, 64 МГц при 5 нс. - Кабели — антенны: λ/4 — это 1,04 м на 72 МГц, 34,7 см на 216 МГц, 20,8 см на 360 МГц; синфазных микроампер достаточно для брака — дроссель и бусина на кабель.
- Разряд 8 кВ из 150 пФ через 330 Ом: 24,2 А, 49,5 нс, 4,8 мДж, пиковая мощность ~194 кВт; фронт 300 В/5 нс через 10 пФ — 293 В на высокоомном входе, 60 В на 100 Ом, 2,9 В с конденсатором 1 нФ.
- Оборона на границе: цепочка входа питания (173), резистор и ограничитель у разъёмов (62), экран без «косичек» (10 см = 2,4 кВ на фронте разряда), кабели с одной стороны; 1000 мкФ держат провал 40 мс при 1 Вт.
- Прошивка: сторож + сверка конфигурации (172 байта кода, 68 байт ОЗУ на Cortex-M3) + оживление шин (17.6) + журнал сбросов.
- Мастерская находит дыры (зажигалка ~9 кВ, реле-зуммер ~2,1 кВ, приёмник «до/после»), но не подтверждает запас — запас подтверждает лаборатория, к которой едут с кабелями, критериями и паяльником.
Полные исходники
emc_guard.c — сверка конфигурации периферии после помехи.
/* Раздел 203.5: сверка конфигурации периферии после помехи.
*
* На плате в cfg_addr[] кладут адреса регистров конфигурации:
* &GPIOA->CRL, &USART1->CR1, &TIM2->CR1, ... — только конфигурацию,
* не данные и не флаги. Здесь, на компьютере, вместо периферии —
* массив fake_regs, а «помеха» перещёлкивает в нём один бит.
*
* Сборка на ПК: gcc -O2 -Wall -Wextra -o emc_guard emc_guard.c && ./emc_guard
* Для кристалла: arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -O2 -DNO_HOST_TEST -c emc_guard.c
*/
#include <stdint.h>
#ifndef NO_HOST_TEST
#include <stdio.h>
#endif
enum { NCFG = 8 };
volatile uint32_t *cfg_addr[NCFG]; /* что охраняем: заполняется при инициализации */
static uint32_t cfg_good[NCFG]; /* эталон после инициализации */
static uint32_t cfg_ref; /* его контрольная сумма */
static uint32_t cfg_crc(void)
{
uint32_t crc = 0xFFFFFFFFu;
for (int i = 0; i < NCFG; i++) {
crc ^= *cfg_addr[i];
for (int b = 0; b < 32; b++)
crc = (crc >> 1) ^ (0xEDB88320u & (0u - (crc & 1u)));
}
return crc;
}
void cfg_snapshot(void) /* вызвать после полной инициализации */
{
for (int i = 0; i < NCFG; i++)
cfg_good[i] = *cfg_addr[i];
cfg_ref = cfg_crc();
}
int cfg_guard(void) /* из главного цикла, раз в десятки мс */
{
if (cfg_crc() == cfg_ref)
return 0; /* всё на месте — дёшево: одна сумма */
int fixed = 0;
for (int i = 0; i < NCFG; i++)
if (*cfg_addr[i] != cfg_good[i]) {
*cfg_addr[i] = cfg_good[i]; /* вернуть как было */
fixed++;
}
return fixed; /* и записать событие в журнал */
}
#ifndef NO_HOST_TEST
static volatile uint32_t fake_regs[NCFG]; /* «периферия» для опыта на ПК */
int main(void)
{
for (int i = 0; i < NCFG; i++) { /* «инициализация периферии» */
fake_regs[i] = 0xB4430000u + 0x111u * (uint32_t)i;
cfg_addr[i] = &fake_regs[i];
}
cfg_snapshot();
printf("эталон: %d регистров, CRC 0x%08X\n", NCFG, cfg_ref);
printf("тихий проход: guard=%d (расхождений нет)\n", cfg_guard());
fake_regs[3] ^= 1u << 13; /* «помеха» перещёлкнула бит */
printf("помеха: бит 13 регистра 3 перещёлкнут, CRC 0x%08X\n", cfg_crc());
printf("guard: восстановлено регистров: %d\n", cfg_guard());
printf("после восстановления: CRC %s\n",
cfg_crc() == cfg_ref ? "совпал" : "НЕ совпал");
fake_regs[1] ^= 1u << 0; /* и два регистра сразу */
fake_regs[6] ^= 1u << 31;
int fixed = cfg_guard();
printf("помеха в двух регистрах: guard=%d, CRC %s\n",
fixed, cfg_crc() == cfg_ref ? "совпал" : "НЕ совпал");
return 0;
}
#endif
Дальше: раздел 204 «Надёжность: запасы, старение и испытания у себя» — прибор пережил помеху; теперь — чтобы жил годами.