В данной статье представлена схема тиристорного регулятора мощности с фазовым управлением на микроконтроллере и подробно описывается алгоритм работы.
В тех случаях, когда необходимо управлять значительными токами (высокотемпературные муфельные печи, электродвигатели с большим крутящим моментом, источники тока для прогрузочных устройств и т.д.) используются силовые тиристоры (ключ, вентиль), поскольку они, в отличии от симисторов, способны коммутировать токи величиной сотни ампер (вплоть до 1000).
В промышленных установках, которые управляют нагрузками относительно малой мощности (нагреватели до 3 кВт в тепловых шкафах, вентиляторы охлаждения, электродвигатели в станках), в качестве силовых ключей применяются симисторы (симметричные тиристоры). Их недостаток заключается в том, что они не способны коммутировать большие токи, а также обладают низкой устойчивостью к помехам при работе с индуктивной нагрузкой (например, электродвигатели).
Ранее в качестве управляющих цепей автоматизированных устройств фазовой регулировки мощности (ФРМ) использовались решения на дискретных элементах (микросхемы цифровой логики). В современных устройствах чаще всего применяются микроконтроллерные системы управления.
На рисунке 1 представлен вариант принципиальной схемы устройства ФРМ под управлением микроконтроллера (МК).
Описание схемы устройства
Для эксперимента в качестве центрального компонента системы управления был применён 8-битный микроконтроллер PIC18LF1220 (обозначен как DD1). В тексте будут приводиться отрывки из программы, необходимых для понимания алгоритма функционирования устройства. Подробнее он будет описан в разделе «Пояснения к работе регулятора», что позволит адаптировать код для любого другого микроконтроллера.
Тактирование микросхемы осуществляется посредством внешнего кварцевого резонатора ZQ1 на 8 МГц. Чтобы МК стартовал, достаточно минимальной обвязки: конденсатор C6 для фильтрации питания как можно ближе к выводам, подтяжка вывода MCLR через резистор R9 к питанию.
Питание +5В управляющей части устройства обеспечивается линейным блоком питания, который построен на базе понижающего трансформатора T1, диодного моста VD1 и стабилизатора LM7805 (обозначен как DA1) с фильтрующими конденсаторами C2…C5.
Выбранный контроллер обладает встроенным 10-разрядным аналого-цифровым преобразователем (АЦП). Для регулировки уровня выходной мощности используется потенциометр R6, выполняющий роль резистивного делителя. В зависимости от величины напряжения на его выходе, которое измеряет встроенный АЦП, меняется фаза открывания тиристоров.
Чтобы регистрировать момент перехода через ноль, переменное напряжение со вторичной обмотки трансформатора T1 (для обеспечения гальванической развязки) поступает на диодный мост VD2 через токоограничивающие резисторы R7 и R8 (для обеспечения нормированного тока через светодиод в оптопаре). После двухполупериодного выпрямителя сигнал подаётся на транзисторный оптрон CNY17F (обозначен как U3). Его транзисторный выход подтянут к питанию через резистор, и сигнал поступает на вход микроконтроллера с пометкой «ZERO».
Для определения полярности полуволны синусоиды применяется цепь, похожая на регистратор ноля, но без использования диодного моста. Через каждые 10 мс оптопара U4 открывается, и сигнал поступает на пин МК с пометкой «POLAR». Диоды VD3 и VD4 включены в цепь последовательно со светодиодом оптопары U4, чтобы защитить светодиод от обратного напряжения при прохождении отрицательной полуволны синусоиды. Резисторы R10 и R11 ограничивают ток.
В макете применены тиристоры модели BT151-880R (обозначены как VS1 и VS2), которые управляются посредством симисторных оптронов MOC3021 (U1 и U2). Эти микросхемы без встроенного детектора ноля (в отличие от серии MOC306x), поскольку эту задачу выполняет МК через специальную цепь, описанную выше.
Устройства ФРМ обладают недостатком: в момент включения силовых вентилей возникают помехи в сети питания, что может сильно влиять на стабильность функционирования МК, а также других устройств, подключенных к той же сетевой линии. Амплитуда помехи становится больше, когда синусоида достигает своего максимума. Для подавления выбросов в схеме применена RC-цепочка (снаббер на элементах R1 и C1), которая подключена параллельно клеммам сети ~220V.
Для регистрации формы сигнала на нагрузке применим осциллограф P1.
Пояснения к работе регулятора
После подачи питания на устройство микроконтроллер инициализируется:
— пин №8 «ZERO» (RB0/INT0) настраивается как вход регистрации прерывания по внешнему сигналу;
— пин №1 (RA0) переходит в режим аналогового входа АЦП (опорное напряжением соответствует уровню питания контроллера);
— пины №6 «KEY_1» (RA2) и №7 «KEY_2» (RA3) настроены на выход для подачи сигналов на управляющие электроды тиристоров через оптопары;
— пин №9 «POLAR» (RB1) также настроен на вход и регистрирует полярность полупериода.
Как только завершится процесс загрузки контроллера, устройство перейдёт в режим работы регулятора.
В бесконечном цикле while() основной функции main() программы аналого-цифровой преобразователь постоянно опрашивает пин RA0. Вращая ручку потенциометра R5, мы меняем уровень сигнала на входе измерителя. Нулевой уровень (0 В) соответствует максимальной выходной мощности, а предельный (5 В) — минимуму:
0 Вольт — 100 %
5 Вольт — 0 %
Шумы по питанию значительно снижают точность измерений. Улучшить её можно методом усреднения некоторого числа значений:
unsigned int32 adc_value = 0;
for (int step = 0; step < 50; step++) {
adc_value = adc_value + read_adc();
}
adc_value = adc_value / 50;
Посредством цикла for производится поэтапный сбор суммы значений, считываемых с АЦП, после чего она делится на количество выборок. Получаем среднее арифметическое.
Далее отсчёты преобразуются в напряжения:
float volts = adc_value * 5.0;
volts /= 1023.0;
Теперь необходимо произвести преобразование измеренного напряжения в величину временной задержки в рамках одного полупериода, в течение которого тиристор будет заперт. На рисунке 2 представлены осциллограммы сигналов в сети и на нагрузке. В течение временного промежутка Δt1 силовой ключ заперт, и в конкретном случае этот промежуток равен половине полупериода — 5 мс. А временной отрезок Δt2, с длительностью тоже 5 мс, соответствует открытому ключу.
Один полупериод длится 10 мс (полный период синусоидального сигнала с частотой 50 Гц равен 20 миллисекунд), и измеряемое посредством АЦП напряжение пропорционально этому временному промежутку:
0 мс — 0 В — 100 %
10 мс — 5 В — 0 %
Ещё раз: в нашем случае максимальное напряжение, прикладываемое к АЦП, равно 5 В, и это значение соответствует 10 мс. И, чтобы преобразовать напряжение в величину времени, оно должно быть умножено на 2.
Так как вычисляемое время — это в рамках одной полуволны длительность паузы, в течение которой тиристор заперт, то величина может меняться от 0 до 10 мс. И её лучше представлять в микросекундах. Во многих комплиляторах для микроконтроллеров от различных разработчиков функция временной задержки delay_ms() чаще всего оперирует целочисленными значениями, поэтому не рекомендуется использовать дробные значения миллисекунд.
Мы разделим величину рассчитанной временной задержки на 10 частей, чтобы воспользоваться функцией микросекундной паузы delay_us(), поскольку эта функция исполняется со значениями от 1 до 1000.
unsigned int32 calc_time = volts * 2; // преобразуем вольты в миллисекунды
calc_time *= 1000; // преобразуем миллисекунды в микросекунды
// разделим полученное значение времени на 10 частей, поскольку
// функция delay_us() работает со значениями от 1 до 1000
unsigned int32 pause_time = calc_time / 10;
Для объяснения вышеописанных расчётных манипуляций рассмотрим пример, опираясь на рисунок 2. Как было там указано, в течение первых 5 мс (Δt1) мы должны держать тиристор запертым, а последующие оставшиеся 5 мс (Δt2) полупериода силовой ключ должен быть открытым. Временная задержка 5 мс соответствует уровню 2,5 В на АЦП. Преобразовываем измеренное напряжение в величину времени:
2,5 * 2 = 5 мс.
Получили те самые 5 мс. Преобразовываем их в микросекунды:
5 * 1000 = 5000 мкс.
Может возникнуть вопрос: зачем переводить в микросекунды, если можно и миллисекунды применить в функции delay_ms(5). В том случае, когда. К примеру, расчётное время будет 5,2 мс, то уже нельзя будет подставить это значение в качестве аргумента в функцию delay_ms(5,2), поскольку она будет выполняться некорректно. Именно по этой причине мы перевели время в микросекунды.
Но далее другая проблема: функция delay_us() не может корректно работать со значениями более 1000. Именно по этой причине мы должны поделить на 10 равных частей весь временной промежуток 5000 мкс. А на 10 частей делим потому, что если будет задержка длительностью 10000 мкс, то каждой функции delay_us() в качестве аргумента будет присвоено максимальное значение 1000 мкс.
В это же время, пока программа исполняется в цикле while(), микроконтроллер параллельно следит за состоянием входа RB0 («ZERO»), отслеживая возникновение высокого логического уровня. Как было сказано выше, переменное напряжение со вторичной обмотки трансформатора прикладывается к двухполупериодному выпрямителю (диодный мост VD2), в следствии чего каждые 10 мс закрывается оптопара U3. На рисунке 3 представлена осциллограмма на выходе диодного моста.
В те моменты, когда напряжение сети проходит через 0, на пине микроконтроллера «ZERO» возникают короткие импульсы, провоцирующие прерывание основной программы контроллера. То есть каждые 10 мс возникает прерывание основной программы.
Прерывание вызывает специальную функцию, в рамках которой выполняется три действия:
— определение полярности полуволны в момент данного прерывания;
— выполнение временной задержки в течение рассчитанного времени, соответствующего уровню измеренного напряжения с выхода потенциометра регулировки мощности;
— подача команды на открытие тиристора.
Чтобы определить полярность текущей полуволны, применена схема на базе оптрона U4. Когда полупериод в сети положительный, оптопара открывается, и на входе микроконтроллера «POLAR» возникает логический ноль. Когда отрицательный — логическая единица.
Определение полярности производится через условный оператор if:
if (input_state(POLAR) == 0) { // если на входе POLAR низкий логический уровень
polar_half_cycle = 1; // полярность положительная
}
else { // иначе — на входе POLAR высокий логический уровень
polar_half_cycle = 0; // полярность отрицательная
}
Определив полярность полуволны, выполняем рассчитанную ранее временную задержку pause_time 10 раз, после чего подадим кратковременный импульс на вход оптопары, которая откроет тиристор:
if (polar_volt == 0) { // если полярность полуволны положительная
delay_us(pause_time); // выполняем временную задержку,
delay_us(pause_time); // в течение которой тиристор заперт
delay_us(pause_time); // при прохождении положительного полупериода
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
output_high(KEY_1); // команда на включение оптрона U1
delay_us(100); // небольшая задержка для срабатывания микросхемы
output_low(KEY_1); // команда на закрытие оптопары, так как тиристор уже открыт
}
else { // если полярность полуволны отрицательная
delay_us(pause_time); // выполняем временную задержку,
delay_us(pause_time); // в течение которой тиристор заперт
delay_us(pause_time); // при прохождении отрицательного полупериода
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
output_high(KEY_2); // команда на включение оптрона U2
delay_us(100); // небольшая задержка для срабатывания микросхемы
output_low(KEY_2); // команда на закрытие оптопары, так как тиристор уже открыт
}
Для открытия силового ключа достаточно подать кратковременный импульс на управляющий электрод, поэтому применена пауза в 100 мкс для срабатывания оптрона. Ключ будет закрыт, когда синусоида перейдёт через ноль. На этом выполнение функции прерывания завершается, и исполнение программы возвращается к основному циклу while().
Полный листинг программы:
#include <18LF1220.h>
#fuses HS,NOWDT,NOLVP
#device ADC=10
#include <math.h>
#use delay(clock=8000000)
#define KEY_1 PIN_A2 // пин для управления тиристором №1
#define KEY_2 PIN_A3 // пин для управления тиристором №2
#define POLAR PIN_B1 // пин для регистрации полярности полуволны синусоиды напряжения
int polar_volt = 0; // полярность полуволны (по умолчанию отрицательная)
unsigned int32 pause_time = 0;
unsigned int32 calc_time = 0;
unsigned int32 adc_value;
float volts = 0;
int step = 0;
#INT_EXT
void ext_isr(void) // функция прерывания
{
if (input_state(POLAR) == 0) { // если на входе POLAR низкий логический уровень
polar_volt = 1; // полярность положительная
}
else { // иначе — на входе POLAR высокий логический уровень
polar_volt = 0; // полярность отрицательная
}
if (polar_volt == 0) { // если полярность полуволны положительная
delay_us(pause_time); // выполняем временную задержку,
delay_us(pause_time); // в течение которой тиристор заперт
delay_us(pause_time); // при прохождении положительного полупериода
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
output_high(KEY_1); // команда на включение оптрона U1
delay_us(100); // небольшая задержка для срабатывания микросхемы
output_low(KEY_1); // команда на закрытие оптопары, так как тиристор уже открыт
}
else { // если полярность полуволны отрицательная
delay_us(pause_time); // выполняем временную задержку,
delay_us(pause_time); // в течение которой тиристор заперт
delay_us(pause_time); // при прохождении отрицательного полупериода
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
delay_us(pause_time);
output_high(KEY_2); // команда на включение оптрона U2
delay_us(100); // небольшая задержка для срабатывания микросхемы
output_low(KEY_2); // команда на закрытие оптопары, так как тиристор уже открыт
}
clear_interrupt(INT_EXT); // очистка флага прерывания
}
void main(void) // основная функция
{
// настройка встроенного АЦП на пине RA0 (канал AN0)
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
// настройка прерываний
ext_int_edge(H_to_L); // прерывание по положительному импульсу
clear_interrupt(INT_EXT); // очистка флага прерывания
enable_interrupts(INT_EXT); // прерывание по входу INT0
enable_interrupts(GLOBAL); // сделать прерывания глобальными
// бесконечный цикл основной функции
while(TRUE) {
for(step = 0; step < 50; step++)
{
adc_value = adc_value + read_adc();
}
adc_value = adc_value / 50;
volts = adc_value * 5.0;
volts /= 1023.0;
calc_time = volts * 2.0;
calc_time *= 1000;
pause_time = calc_time / 10;
}
}
Практический эксперимент
Проверим на практике работоспособность спроектированной системы. Ниже представлена фотография собранного макета:
Будем регулировать выходную мощность, вращая ручку потенциометра, и наблюдать за формой сигнала на нагрузке посредством осциллографа. Для наглядной демонстрации регуляции воспользуемся лампочкой накаливания в качестве нагрузки.
— 0 %
— 25 %
— 50 %
— 75 %
— 100 %