208б. Нагрузка 230 В от микроконтроллера: реле, симистор, твердотельное реле
Раздел 208 провёл сеть внутрь прибора и поставил барьер изоляции, 208а собрал прибор от промышленных 24 В. Остался последний шаг: вывод микроконтроллера на 3,3 В должен включить нагреватель, лампу или двигатель на 230 В. Способов три — реле, симистор через оптосимистор и твердотельное реле, — и у каждого своя физика: катушка, которая не хочет отпускать, симистор, который гаснет только в нуле тока, детектор нуля, который врёт на миллисекунду. Здесь всё это посчитано, а в конце таймер сам ловит ноль сети и открывает симистор на нужном угле.
Опоры: гасящий диод — 51.2, реле и твердотельное реле в общих чертах —
52.6, оптрон и его коэффициент передачи — 54.2 и 54.3, зазоры и барьер —
208.3 и 208.4, захват и одноимпульсный режим таймера — 13.6 и 13.8,
фильтр входа — 13.10, действующее значение — 57.2, помехи — 203. Числа
раздела — модель на ПК _verify/load208b/load208b.py (прогон —
load208b_host.txt), код — load208b.c, собранный armclang для F103 и
G474.
Как это называется в документации
Оригинал Перевод triac симистор: двунаправленный тиристор opto-triac, random-phase / zero-crossing оптосимистор: без детектора нуля / с детектором нуля solid-state relay (SSR) твердотельное реле latching current / holding current ток включения (защёлкивания) / ток удержания snubber снаббер: RC-цепь поперёк ключа zero-crossing detector детектор перехода через ноль phase-angle control фазовое управление burst-fire, integral-cycle control пакетное управление: целыми периодами Trigger Mode режим запуска: счётчик стартует по фронту входа One pulse mode одноимпульсный режим PWM mode 2 ШИМ, режим 2: выход активен, пока CNT ≥ CCR fSAMPLING=fDTS/32, N=8 самый длинный фильтр входа: 8 отсчётов на fDTS/32
208б.1 Реле: катушка отпускает дольше, чем кажется
Схема катушки уже есть в 52.6: транзисторный ключ и гасящий диод параллельно обмотке (51.2). Диод спасает ключ, но у него есть цена — медленное отпускание. После выключения ключа ток катушки не исчезает, а спадает по закону L/R, и пока он велик, якорь держится.
Модель — катушка из 51.2: 12 В, 30 мА, около 100 мГн. Сопротивление
400 Ом, постоянная времени L/R = 0,25 мс, запасено 45 мкДж. Ток спадает
до нуля за t = (L/R) · ln(1 + I·R/Uогр), где Uогр — напряжение
ограничителя; численное интегрирование дало те же числа:
| Ограничитель | Спад тока | На ключе | Съел ограничитель |
|---|---|---|---|
| диод | 0,62 мс | 13,1 В | 6 мкДж из 45 |
| диод + стабилитрон 24 В | 0,098 мс | 37,1 В | 34 мкДж из 45 |
| диод + стабилитрон 47 В | 0,056 мс | 60,1 В | 39 мкДж из 45 |
Стабилитрон на 24 В последовательно с диодом ускоряет спад в 6,3 раза. Ту же роль играет ограничитель TVS (173). Плата — напряжение на ключе: 37,1 В вместо 13,1 В, и транзистор выбирают с запасом над этим числом. С одним диодом энергия уходит в сопротивление обмотки, со стабилитроном — в стабилитрон. Это спад тока, а не время отпускания якоря: механика добавляет своё, и её модель не считает — смотрят осциллографом по контакту.
Почему скорость важна. Контакты расходятся под током, между ними загорается дуга. На переменном токе она гаснет сама в ближайшем нуле тока, то есть не позже чем через 10 мс, но каждая дуга выжигает металл контакта. Медленное отпускание — дольше путь в зоне дуги.
Ресурс считается делением (52.6): 100 000 циклов. Термостат, щёлкающий раз в 60 с, съедает его за 69,4 суток. Пакетное управление с периодом 1 с (208б.5) — за 27,8 часа, то есть за 1,2 суток. Вывод: реле — для редких включений, для частых нужен симистор.
Включение в нуле реле не даётся. Время срабатывания реле — около 10 мс (52.6), и оно плавает. Если подать команду по детектору нуля с поправкой на среднее время, контакт замкнётся не в нуле, а с разбросом:
| Разброс срабатывания | Угол от нуля | Напряжение на контакте при замыкании |
|---|---|---|
| ±0,5 мс | ±9° | до 51 В |
| ±1 мс | ±18° | до 101 В |
| ±2 мс | ±36° | до 191 В |
Без синхронизации — до пиковых 325 В. Выигрыш реален, только если разброс конкретного реле мерили, а не взяли из головы; разброс в модели — параметр, не паспорт.
208б.2 RC-снаббер: расчёт
Поперёк контакта или симистора ставят последовательную цепь R и C — снаббер. Он делает две вещи: гасит искру на контакте и ограничивает скорость нарастания напряжения на симисторе после выключения. Слишком быстрое нарастание открывает симистор снова, без импульса затвора. Пример — 100 Ом и 100 нФ.
Закрытый ключ течёт. На 50 Гц у 100 нФ реактивное сопротивление 31,8 кОм, и через снаббер течёт 7,23 мА даже при выключенной нагрузке. Для нагревателя это ничто, а маленькая нагрузка — светодиодная лампа, катушка сетевого реле — от этого тока может светиться или не отпускать. В резисторе при этом всего 5,2 мВт. Конденсатор стоит последовательно с нагрузкой поперёк сети, поэтому он — класса X (208.4).
Резистор нельзя убрать. При включении на вершине синусоиды заряженный конденсатор разряжается прямо в ключ; 100 Ом ограничивают пик до 3,25 А.
Индуктивная нагрузка — худший случай. Пример: 230 В, 0,5 А, коэффициент мощности 0,6. Это |Z| = 460 Ом: 276 Ом активных и 1,171 Гн, ток отстаёт на 53,1°. Симистор гаснет в нуле тока, а напряжение сети в этот момент — 260 В, и оно скачком ложится на закрытый ключ. Модель (метод Рунге — Кутты, нагрузка плюс снаббер):
| Снаббер | Пик на ключе | Наибольшая скорость | Затухание |
|---|---|---|---|
| 100 Ом + 100 нФ | 534 В | 0,75 В/мкс | 0,05 |
| 470 Ом + 100 нФ | 498 В | 0,70 В/мкс | 0,11 |
| 1000 Ом + 100 нФ | 459 В | 0,65 В/мкс | 0,19 |
| 100 Ом + 22 нФ | 529 В | 1,61 В/мкс | 0,03 |
Два вывода. Меньшая ёмкость — быстрее нарастание: 22 нФ дают 1,61 В/мкс против 0,75. И снаббер вместе с индуктивностью нагрузки — колебательный контур: напряжение на ключе перелетает пиковые 325 В до 534 В, больший резистор сильнее гасит колебание и снижает пик до 459 В. Допустимую скорость нарастания и класс напряжения берут из даташита симистора; даташита на диске нет, поэтому здесь — только сравнение вариантов. В модели нет потерь в железе нагрузки, реальный пик ниже, но запас по напряжению закладывают на модельный.
208б.3 Симистор, оптосимистор, твердотельное реле
Симистор открывается импульсом тока затвора и дальше держится сам, пока ток нагрузки не упадёт ниже тока удержания, — то есть до ближайшего нуля тока. Поэтому на переменном токе он гаснет сам каждый полупериод, а на постоянном не выключится никогда (52.6). Второе условие — ток включения: пока идёт импульс затвора, ток нагрузки должен успеть его набрать, иначе после импульса симистор закроется. Числа обоих токов — из даташита конкретного прибора; на диске его нет, поэтому здесь их нет. Отсюда длина импульса в листинге — 200 мкс. Если открывать в самом нуле, к концу импульса сеть поднимется всего до 20,4 В: нагреватель на 2000 Вт (26,45 Ом) наберёт 0,77 А. Маломощная нагрузка может не набрать ток включения — тогда импульс удлиняют или открывают чуть позже нуля.
Оптосимистор переносит команду через барьер: светодиод на стороне микроконтроллера, маленький симистор на сетевой стороне. Его симистор через резистор подаёт ток в затвор силового. Резистор ограничивает бросок: с 360 Ом при открывании на вершине — 0,90 А пика, и этот бросок оптосимистор должен выдерживать по своему даташиту. Оптосимисторы бывают двух видов:
- без детектора нуля — открывается в любой момент, когда горит светодиод; только им делают фазовое управление (208б.5);
- с детектором нуля — открывается, лишь пока напряжение сети близко к нулю; фазу им не сделать, только целые полупериоды. Строчка 54.6 «оптосимистор с переходом через ноль» — про включение и выключение, а не про регулирование.
Нагрев. Падение на открытом симисторе описывают порогом V0 и
сопротивлением r: P = V0 · Iср + r · Iд², где Iср — средний ток
по модулю, Iд — действующий. Параметры примера — V0 = 1 В, r = 20 мОм;
это не даташит, а порядок величины для расчёта:
| Режим | Iд | Iср | Потери |
|---|---|---|---|
| нагреватель 2000 Вт, полностью | 8,70 А | 7,83 А | 9,34 Вт |
| тот же, угол 90° | 6,15 А | 3,91 А | 4,67 Вт |
Пик тока — 12,30 А. Упрощённая оценка «1 В × ток» даёт 8,70 Вт — близко, но меньше. Потери — 0,47 % мощности нагрузки: мало для нагрузки, много для корпуса. Радиатор считается от перегрева: при кристалле не выше 125 °C и воздухе 50 °C (тоже параметры примера) на 9,34 Вт допустимо всего 8,03 К/Вт. Минус переход — корпус 1,5 К/Вт и корпус — радиатор 0,5 К/Вт (пример) — радиатору остаётся 6,03 К/Вт. Это уже не пятачок меди на плате, а настоящий радиатор. И проверить по даташиту, соединён ли теплоотвод корпуса с выводом: если да, радиатор под сетью, и на него распространяются зазоры 208.3.
Твердотельное реле — оптосимистор и силовой симистор в одном корпусе, с детектором нуля или без. Какое брать, решает нагрузка. Модель:
| Нагрузка | Включение в нуле напряжения | Включение на вершине |
|---|---|---|
| ёмкость 1 мкФ через 10 Ом | пик тока 0,102 А | пик тока 32,5 А |
| индуктивность без насыщения | пик потока 2,00 от рабочего | пик потока 1,00 |
Для нагревателя и ёмкости — реле с переходом через ноль: нет скачка тока, меньше помех. Для трансформатора и двигателя наоборот: включение в нуле напряжения удваивает поток в сердечнике, сердечник насыщается и берёт бросок тока. Их включают на вершине — реле без детектора нуля с командой по детектору 208б.4. Для фазового управления годится только реле без детектора нуля.
208б.4 Детектор перехода через ноль
Классический детектор — оптрон со встречными светодиодами (54.2), подключённый к сети через два резистора по 100 кОм. Выход с подтяжкой 10 кОм к 3,3 В. Вдали от нуля ток светодиода велик, транзистор открыт, на выходе ноль; около нуля ток мал, транзистор закрывается, на выходе единица. Получается импульс вокруг каждого нуля сети.
Резисторы. Вместе они греются на 0,262 Вт, по 0,131 Вт на каждый, и каждый держит 163 В пика — та же логика двух корпусов, что у разряда X-конденсатора (208.5). Пик тока светодиода — 1,62 мА.
Где фронт. Выход переходит через половину питания, когда ток фототранзистора уже не может удержать подтяжку. Этот порог зависит от коэффициента передачи тока, а он гуляет от 50 до 600 % и стареет вдвое (54.2). Модель по трём значениям — 25 % (минимум 50 %, делённый пополам), 100 % и 600 %:
| Коэффициент | Порог по сети | Фронт раньше нуля | Ширина импульса |
|---|---|---|---|
| 25 % | 133,2 В | 1,343 мс = 24,2° | 2,69 мс |
| 100 % | 34,2 В | 0,335 мс = 6,0° | 0,67 мс |
| 600 % | 6,7 В | 0,066 мс = 1,2° | 0,13 мс |
Фронт — плохой ноль: между экземплярами он плавает на 1,3 мс. Зато импульс симметричен относительно нуля, и середина импульса — ноль сети при любом коэффициенте. Её и берут: ширину w мерят, ноль — через w/2 после фронта. Напряжение сети тоже двигает фронт: при коэффициенте 100 % и сети −10 % фронт уходит раньше на 0,037 мс (+0,67°), при +10 % — позже на 0,031 мс (−0,55°); середина остаётся на месте.
Цена микросекунды на 50 Гц — 0,018°. Фильтр входа таймера (13.10)
в самом длинном варианте — 8 отсчётов на fDTS/32 при CKD = ÷4 —
задерживает каждый фронт на 14,2 мкс у F103 (72 МГц) и на 6,0 мкс
у G474 (170 МГц). Оба фронта задерживаются одинаково, середина не
сдвигается. Чего модель не знает — разных времён включения и выключения
самого оптрона (54.3): с большой подтяжкой спад и фронт несимметричны,
и середина уползает. Это меряют осциллографом на готовой плате.
Вход — захват таймера, а не EXTI. Захват ставит метку времени аппаратно (13.6), и задержка прерывания на неё не влияет. EXTI тоже работает, но тогда в угол попадает всё, что задерживает прерывание.
Резисторный детектор без изоляции — 1 МОм прямо на вывод, и защитный диод вывода ограничивает напряжение. Пик тока в диод — 0,325 мА, порог 1,65 В проходит через 16,1 мкс после нуля — 0,29°. Точно и дёшево, но только если вся плата сама живёт на сети без изоляции, со всеми последствиями 208.7: никакого отладчика. И вывод должен допускать втекающий ток. У F103 PA6 — обычный вывод, даташит разрешает ±5 мА. У G474 PA6 — вывод TT_a, и для таких выводов даташит пишет, что положительный ток впрыска невозможен (−5/0 мА): там нужен внешний диод.
208б.5 Фазовое и пакетное управление
Фаза. Симистор открывают с задержкой t после нуля; угол α = t / 10 мс · 180°. Для активной нагрузки мощность — среднее квадрата напряжения на открытой части полупериода:
P(α) / Pmax = 1 − α/π + sin(2α) / (2π)
Модель сверила формулу с численным интегрированием во всех точках:
| Угол | Задержка от нуля | P / Pmax | Действующее напряжение |
|---|---|---|---|
| 0° | 0 мкс | 1,0000 | 230,0 В |
| 30° | 1667 мкс | 0,9712 | 226,7 В |
| 45° | 2500 мкс | 0,9092 | 219,3 В |
| 60° | 3333 мкс | 0,8045 | 206,3 В |
| 90° | 5000 мкс | 0,5000 | 162,6 В |
| 120° | 6667 мкс | 0,1955 | 101,7 В |
| 135° | 7500 мкс | 0,0908 | 69,3 В |
| 150° | 8333 мкс | 0,0288 | 39,1 В |
| 170° | 9444 мкс | 0,0011 | 7,7 В |
| 180° | 10000 мкс | 0 | 0 В |
Зависимость нелинейна: первые 30° почти не убавляют мощность, последние 30° почти ничего не дают. Поэтому в прошивку кладут обратную таблицу — задержку для каждой ступени мощности; модель решила уравнение делением отрезка пополам:
| Мощность | 10 % | 20 % | 30 % | 40 % | 50 % | 60 % | 70 % | 80 % | 90 % |
|---|---|---|---|---|---|---|---|---|---|
| угол | 133,4° | 119,5° | 108,6° | 99,1° | 90,0° | 80,9° | 71,4° | 60,5° | 46,6° |
| задержка, мкс | 7411 | 6637 | 6036 | 5504 | 5000 | 4496 | 3964 | 3363 | 2589 |
Цена фазы — гармоники. При 90° ток нагрузки — обрезанная синусоида: первая гармоника 0,593 от полной амплитуды, третья 0,318 (54 % первой), пятая 0,106 (18 %). Каждое открывание — ещё и скачок тока с крутым фронтом. Это помехи в сеть и в эфир (203), поэтому нагреватели фазой не регулируют; фаза нужна там, где пакеты не годятся, — яркость ламп накаливания, скорость коллекторного двигателя.
Две ошибки угла. Если взять за ноль фронт детектора, а не середину, при коэффициенте 25 % задуманные 90° станут 65,8°, и мощность выйдет 0,753 вместо 0,500. Если частота сети на 1 % ниже (49,5 Гц), задержка 5000 мкс, рассчитанная на 50 Гц, даёт 89,1° и мощность 0,5100 вместо 0,5000 — это терпимо, но для точности полупериод мерят по соседним нулям.
Пакеты. Симистор открывают в нуле целыми периодами, мощность задаёт доля включённых. Именно периодами, а не полупериодами: если включать полупериоды через один, все они окажутся одной полярности, и в нагрузке появится постоянная составляющая 103,5 В (Uпик/π), которую сеть и трансформаторы не любят. Целыми периодами — 0 В.
Шаг мощности задаёт окно: 50 периодов (1 с) — 2 %, 100 периодов (2 с) — 1 %. Как раскладывать включённые периоды внутри окна — вопрос пульсаций. Блоком («первые N из 50») — длинные паузы; накопителем (прибавлять уровень к сумме и включать период при переполнении через 100) — ровно:
| Уровень | Накопитель: включено из 100 | Длиннейшая пауза | Блок в окне 50: пауза |
|---|---|---|---|
| 10 % | 10 | 9 периодов, 180 мс | 45 периодов, 900 мс |
| 30 % | 30 | 3 периода, 60 мс | 35 периодов, 700 мс |
| 50 % | 50 | 1 период, 20 мс | 25 периодов, 500 мс |
| 90 % | 90 | 1 период, 20 мс | 5 периодов, 100 мс |
Нагревателю пульсации безразличны — у него тепловая инерция; лампа
на пакетах мигает. Накопитель в листинге — функция next_delay_us.
208б.6 Код: TIM3 ловит ноль и сам открывает симистор
Идея — не дать процессору участвовать во времени. Вход детектора — PA6, канал 1 TIM3; выход на светодиод оптосимистора — PB0, канал 3. На F103 это их основные функции, на G474 — альтернативная функция AF2 у обоих. Тик — 1 мкс: TIM3 получает 72 МГц на F103 (APB1 36 МГц, при делителе APB1 не 1 таймер тактируется вдвое чаще) и 170 МГц на G474 (APB1 без делителя).
- Режим запуска (
SMS= 110,TS= TI1FP1): фронт импульса детектора сам запускает счётчик; одноимпульсный режим (OPM) останавливает его на событии обновления. - Канал 2 от того же входа, по спаду (
CC2S= 10,CC2P): вCCR2попадает ширина импульса w — ноль сети был через w/2 после старта. - Канал 3 в режиме ШИМ 2: выход активен, пока
CNT≥CCR3, и гаснет на обновлении, когда счёт доходит доARR. Импульс на оптосимистор — отCCR3= w/2 + задержка доARR. - Прерывание по спаду готовит следующий полупериод: пишет
CCR3иARR. Оба с предзагрузкой (OC3PE,ARPE) и вступят при следующем запуске. Опоздание прерывания угол не сдвигает: импульс ставит таймер.
Задержку ограничивает сверху запас до следующего фронта: импульс должен
кончиться раньше. При самой широкой ширине 2700 мкс (коэффициент 25 %)
наибольшая задержка — 8350 мкс, то есть 150,3° и P/Pmax 0,0280; меньше
этого фаза не даёт, 10 % с их 7411 мкс помещаются. Это и проверяет
_Static_assert вместе с масками регистров — компилятор не соберёт код,
если числа разойдутся.
void triac_init(void)
{
#if defined(STM32F10X_MD)
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
GPIOA->CRL = (GPIOA->CRL & ~(0xFu << 24)) | (0x4u << 24); /* PA6: вход без подтяжки */
GPIOB->CRL = (GPIOB->CRL & ~0xFu) | 0xAu; /* PB0: альтернативная функция, 2 МГц */
#else
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_GPIOBEN;
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM3EN;
GPIOA->MODER = (GPIOA->MODER & ~(3u << 12)) | (2u << 12); /* PA6: AF2 — TIM3_CH1 */
GPIOA->AFR[0] = (GPIOA->AFR[0] & ~(0xFu << 24)) | (2u << 24);
GPIOB->MODER = (GPIOB->MODER & ~3u) | 2u; /* PB0: AF2 — TIM3_CH3 */
GPIOB->AFR[0] = (GPIOB->AFR[0] & ~0xFu) | 2u;
#endif
TIM3->PSC = TIM_CLK_HZ / TICK_HZ - 1u;
TIM3->CR1 = TIM_CR1_CKD_1 | TIM_CR1_ARPE | TIM_CR1_OPM; /* tDTS = 4 такта; стоп на обновлении */
TIM3->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC1F /* IC1 ← TI1, фильтр fDTS/32, N = 8 */
| TIM_CCMR1_CC2S_1; /* IC2 ← тот же TI1 */
TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3PE;
TIM3->CCER = TIM_CCER_CC2E | TIM_CCER_CC2P | TIM_CCER_CC3E; /* IC2 — по спаду */
TIM3->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1;
TIM3->ARR = W_MAX_US + GUARD_US;
TIM3->CCR3 = 0xFFFFu; /* до первого измерения ширины — не открывать */
TIM3->EGR = TIM_EGR_UG; /* теневые ARR и CCR3 ← предзагрузка */
TIM3->SR = 0u;
TIM3->DIER = TIM_DIER_CC2IE;
NVIC_EnableIRQ(TIM3_IRQn);
}
Пока ширина не измерена, CCR3 = 0xFFFF больше ARR, и выход не
включается ни разу — симистор закрыт с первого полупериода. Обработчик:
/* спад импульса детектора: CCR2 — его ширина w, ноль был через w/2 после фронта */
void TIM3_IRQHandler(void)
{
uint32_t w, d, d_max, start, stop;
if (!(TIM3->SR & TIM_SR_CC2IF))
return;
w = TIM3->CCR2; /* чтение снимает флаг */
d = next_delay_us();
if (d >= HALF_US || w > W_MAX_US) { /* пропустить: сравнение за пределом ARR */
TIM3->ARR = W_MAX_US + GUARD_US;
TIM3->CCR3 = 0xFFFFu;
return;
}
d_max = HALF_US - w / 2u - PULSE_US - GUARD_US;
if (d > d_max)
d = d_max; /* импульс кончается до следующего фронта */
start = w / 2u + d + 1u; /* CCR3 > 0: иначе импульса не будет */
stop = start + PULSE_US;
if (stop < w + GUARD_US)
stop = w + GUARD_US; /* счёт идёт, пока не пойман спад */
TIM3->CCR3 = start; /* обе записи вступят на следующем запуске */
TIM3->ARR = stop;
}
next_delay_us в фазовом режиме берёт задержку из таблицы 208б.5
(k_delay_us в файле — те же 11 чисел от 10000 до 0), в пакетном —
накопитель: первый полупериод пары решает за оба, поэтому включаются
только целые периоды. Ширина w берётся из текущего полупериода, а угол
применится в следующем — ширина меняется медленно, это честный обмен.
Код собран armclang для F103 и G474 с -Wall -Wextra без предупреждений:
имена регистров и битов у TIM3 на обоих одинаковы, различается только
включение портов.
208б.7 Грабли
Реле отпускает с опозданием, контакты чернеют. Один гасящий диод растягивает спад тока катушки до 0,62 мс, контакты расходятся медленно, дуга дольше. Стабилитрон 24 В последовательно с диодом ускоряет спад в 6,3 раза, но поднимает напряжение на ключе до 37,1 В (208б.1).
Реле в пакетном управлении умерло за выходные. Ресурс 100 000 циклов при периоде 1 с — 27,8 часа. Пакеты — только симистором (208б.1).
Выключенная лампа тлеет. Снаббер 100 Ом + 100 нФ пропускает 7,23 мА при закрытом ключе; маленькой нагрузке этого хватает, чтобы светиться. Уменьшать ёмкость, помня, что 22 нФ поднимают скорость нарастания до 1,61 В/мкс (208б.2).
С индуктивной нагрузкой симистор сам открывается после нуля. Ток отстаёт от напряжения, в нуле тока на ключ скачком ложится 260 В. Без снаббера нарастание ограничено только собственной ёмкостью симистора. Снаббер ограничивает скорость, но с нагрузкой звенит до 534 В — брать симистор с запасом по напряжению (208б.2).
Мощность у двух одинаковых плат разная. За ноль взят фронт детектора, а он плавает с коэффициентом оптрона: при 25 % — на 1,343 мс раньше нуля, 90° превращаются в 65,8°, мощность 0,753 вместо 0,500. Ноль — середина импульса детектора (208б.4).
Фаза не регулируется: нагрузка горит на полную или никак. Оптосимистор или твердотельное реле с детектором нуля открываются только около нуля: команда на 90° будет исполнена в следующем нуле. Для фазы — приборы без детектора нуля (208б.3).
Трансформатор через реле «с нулём» выбивает автомат. Включение в нуле напряжения удваивает поток в сердечнике (2,00 от рабочего против 1,00 на вершине), сердечник насыщается. Для трансформатора — включение на вершине (208б.3).
Пакеты по полупериодам гудят в трансформаторе. Полупериоды через один — одной полярности, постоянная составляющая 103,5 В. Включать целыми периодами (208б.5).
На G474 резисторный детектор портит вход. PA6 у G474 — вывод TT_a, положительный ток впрыска на нём невозможен по даташиту. Внешний диод к питанию или оптронный детектор; у F103 PA6 допускает ±5 мА (208б.4).
Во время стирания Flash симистор ведёт себя странно. Стирание страницы
занимает 20…40 мс у F103 и 22,02…24,47 мс у G474 по даташитам — 2…4
полупериода. Чтение того же банка Flash во время стирания останавливает
шину (так пишет RM0440), и обработчик прерывания из этого банка ждёт.
Таймер при этом продолжает выдавать импульсы по последним CCR3 и ARR: фаза держит прежний угол, а пакет замирает
в прошлом решении — включённым или выключенным. Стирать, когда нагрузка
выключена, или переносить обработчик в ОЗУ.
Радиатор симистора ударил током. У многих корпусов теплоотвод соединён с выводом, и радиатор оказывается под сетью. Смотреть даташит, ставить изолирующую прокладку или соблюдать зазоры 208.3 (208б.3).
208б.8 Итоги
- Катушка реле 12 В, 30 мА, 100 мГн: с диодом ток спадает за 0,62 мс, с диодом и стабилитроном 24 В — за 0,098 мс (в 6,3 раза быстрее), ценой 37,1 В на ключе. Ресурс 100 000 циклов: раз в 60 с — 69,4 суток, раз в секунду — 1,2 суток.
- Включение реле в нуле зависит от разброса срабатывания: ±1 мс — это ±18° и до 101 В на контакте вместо 325 В.
- Снаббер 100 Ом + 100 нФ: 7,23 мА утечки через закрытый ключ, 3,25 А разряда при включении на вершине; на индуктивной нагрузке 0,5 А с коэффициентом мощности 0,6 — 0,75 В/мкс и звон до 534 В, 1 кОм снижает пик до 459 В.
- Симистор держится до нуля тока; токи включения и удержания — из даташита. Оптосимистор без детектора нуля — для фазы, с детектором — только для пакетов. Потери на 2000 Вт с V0 = 1 В, r = 20 мОм — 9,34 Вт, радиатору остаётся 6,03 К/Вт.
- Твердотельное реле с переходом через ноль — для нагревателей и ёмкостей (0,102 А против 32,5 А), без него — для трансформаторов (поток 1,00 против 2,00) и фазы.
- Детектор на оптроне: фронт уходит от нуля на 0,066…1,343 мс в зависимости от коэффициента передачи, середина импульса — ровно ноль; 1 мкс = 0,018°, фильтр входа 14,2 / 6,0 мкс на обоих фронтах середину не двигает.
- Фаза:
P/Pmax = 1 − α/π + sin(2α)/(2π); 50 % — 90° и 5000 мкс, 10 % — 133,4° и 7411 мкс; при 90° третья гармоника — 54 % первой. - Пакеты — целыми периодами (полупериоды через один дают 103,5 В постоянной составляющей); окно 50 периодов — шаг 2 %, накопитель держит паузу при 50 % в 1 период вместо 25 у блока.
- TIM3 в режиме запуска с одноимпульсным режимом: фронт детектора стартует счёт, канал 2 мерит ширину, канал 3 в режиме ШИМ 2 выдаёт импульс 200 мкс; угол ставит таймер, прерывание лишь готовит следующий полупериод. Одинаково на F103 и G474.
Полные исходники
load208b.c — симистор по углу: TIM3 ловит детектор нуля и сам выдаёт импульс.
/* 208б: симистор по углу — TIM3 ловит импульс детектора нуля и сам выдаёт
импульс на оптосимистор в одноимпульсном режиме.
PA6 — TIM3_CH1, вход от детектора; PB0 — TIM3_CH3, выход на светодиод оптосимистора.
Собирается armclang: -DSTM32F10X_MD (stm32f10x.h) или -DSTM32G474xx (stm32g4xx.h). */
#include <stdint.h>
#if defined(STM32F10X_MD)
#define TIM_CLK_HZ 72000000u /* APB1 36 МГц, таймер получает ×2 */
#else
#define TIM_CLK_HZ 170000000u
#endif
#define TICK_HZ 1000000u /* тик 1 мкс */
#define HALF_US 10000u /* полупериод сети 50 Гц */
#define PULSE_US 200u /* импульс на светодиод оптосимистора */
#define GUARD_US 100u /* запас до следующего фронта детектора */
#define W_MAX_US 2700u /* самый широкий импульс детектора (CTR 25 %) */
#define D10_US 7411u /* задержка для 10 % мощности */
#define MODE_PHASE 0u
#define MODE_BURST 1u
static const uint16_t k_delay_us[11] = { /* мощность 0, 10 … 100 % → задержка от нуля */
HALF_US, D10_US, 6637, 6036, 5504, 5000, 4496, 3964, 3363, 2589, 0};
_Static_assert(TIM_CLK_HZ % TICK_HZ == 0u && TIM_CLK_HZ / TICK_HZ - 1u <= 0xFFFFu, "PSC: целое, 16 бит");
_Static_assert(sizeof k_delay_us / sizeof k_delay_us[0] == 11u, "ступени 0…100 % через 10");
_Static_assert(W_MAX_US + 2u * GUARD_US < HALF_US, "спад детектора ловится до следующего фронта");
_Static_assert(HALF_US - W_MAX_US / 2u - PULSE_US - GUARD_US >= D10_US, "10 % помещается при самом широком импульсе");
_Static_assert((TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) == 0x56u, "TS=101 TI1FP1, SMS=110 запуск");
_Static_assert((TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3PE) == 0x78u, "CH3: ШИМ 2, предзагрузка");
_Static_assert((TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC1F | TIM_CCMR1_CC2S_1) == 0x2F1u, "IC1 и IC2 от TI1, фильтр 1111");
static volatile uint8_t g_mode, g_level; /* режим и мощность 0…100 % */
void triac_init(void)
{
#if defined(STM32F10X_MD)
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
GPIOA->CRL = (GPIOA->CRL & ~(0xFu << 24)) | (0x4u << 24); /* PA6: вход без подтяжки */
GPIOB->CRL = (GPIOB->CRL & ~0xFu) | 0xAu; /* PB0: альтернативная функция, 2 МГц */
#else
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_GPIOBEN;
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM3EN;
GPIOA->MODER = (GPIOA->MODER & ~(3u << 12)) | (2u << 12); /* PA6: AF2 — TIM3_CH1 */
GPIOA->AFR[0] = (GPIOA->AFR[0] & ~(0xFu << 24)) | (2u << 24);
GPIOB->MODER = (GPIOB->MODER & ~3u) | 2u; /* PB0: AF2 — TIM3_CH3 */
GPIOB->AFR[0] = (GPIOB->AFR[0] & ~0xFu) | 2u;
#endif
TIM3->PSC = TIM_CLK_HZ / TICK_HZ - 1u;
TIM3->CR1 = TIM_CR1_CKD_1 | TIM_CR1_ARPE | TIM_CR1_OPM; /* tDTS = 4 такта; стоп на обновлении */
TIM3->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC1F /* IC1 ← TI1, фильтр fDTS/32, N = 8 */
| TIM_CCMR1_CC2S_1; /* IC2 ← тот же TI1 */
TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3PE;
TIM3->CCER = TIM_CCER_CC2E | TIM_CCER_CC2P | TIM_CCER_CC3E; /* IC2 — по спаду */
TIM3->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1;
TIM3->ARR = W_MAX_US + GUARD_US;
TIM3->CCR3 = 0xFFFFu; /* до первого измерения ширины — не открывать */
TIM3->EGR = TIM_EGR_UG; /* теневые ARR и CCR3 ← предзагрузка */
TIM3->SR = 0u;
TIM3->DIER = TIM_DIER_CC2IE;
NVIC_EnableIRQ(TIM3_IRQn);
}
void triac_set(uint8_t mode, uint8_t level)
{
g_mode = mode;
g_level = level > 100u ? 100u : level;
}
/* задержка от нуля на следующий полупериод; HALF_US — не открывать */
static uint32_t next_delay_us(void)
{
static uint8_t half, on;
static uint8_t acc;
if (g_mode == MODE_PHASE)
return k_delay_us[g_level / 10u];
half ^= 1u;
if (half) { /* первый полупериод пары решает за оба */
acc += g_level;
on = acc >= 100u;
if (on)
acc -= 100u;
}
return on ? 0u : HALF_US;
}
/* спад импульса детектора: CCR2 — его ширина w, ноль был через w/2 после фронта */
void TIM3_IRQHandler(void)
{
uint32_t w, d, d_max, start, stop;
if (!(TIM3->SR & TIM_SR_CC2IF))
return;
w = TIM3->CCR2; /* чтение снимает флаг */
d = next_delay_us();
if (d >= HALF_US || w > W_MAX_US) { /* пропустить: сравнение за пределом ARR */
TIM3->ARR = W_MAX_US + GUARD_US;
TIM3->CCR3 = 0xFFFFu;
return;
}
d_max = HALF_US - w / 2u - PULSE_US - GUARD_US;
if (d > d_max)
d = d_max; /* импульс кончается до следующего фронта */
start = w / 2u + d + 1u; /* CCR3 > 0: иначе импульса не будет */
stop = start + PULSE_US;
if (stop < w + GUARD_US)
stop = w + GUARD_US; /* счёт идёт, пока не пойман спад */
TIM3->CCR3 = start; /* обе записи вступят на следующем запуске */
TIM3->ARR = stop;
}