The post has been translated automatically. Original language: Russian
Разработка масштабируемого многофазного преобразователя постоянного тока с малыми пульсациями с цифровой системой управления. Часть 7: Управление ШИМ через UART
В прошлой части мы написали модуль генерации ШИМ на SystemVerilog и убедились, что он работает. Однако скважность была жёстко задана в коде — 50%. Это нормально для первого теста, но для реального использования нам нужно менять скважность динамически.
В этой части мы добавим в систему UART и сделаем так, чтобы скважностью можно было управлять из терминала на компьютере.
Что мы сделаем:
- Внесём небольшие поправки в топ-модуль dcdc_1.sv.
- Познакомимся с Nios II и создадим программный проект.
- Напишем код на C, который читает команды из терминала и меняет скважность.
- Настроим терминал YAT.
- С помощью осциллографа проверим, как меняется ШИМ при разных значениях скважности.
2. Поправки в топ-модуль в Quartus
Система в Platform Designer уже содержит все необходимые модули: процессор Nios II, память, UART и PIO. Нам осталось только правильно их соединить в топ-модуле dcdc_1.sv.
Вот полный код топ-модуля:
module dcdc_1 (
input wire clk_50mhz,
input wire reset_n,
input wire fifoed_avalon_uart_0_external_connection_rxd,
output wire fifoed_avalon_uart_0_external_connection_txd,
output wire [3:0] pwm_out
);
// === PIO для управления ШИМ ===
wire [15:0] pwm_value_export; // значение скважности от Nios II
wire pwm_enable_export; // сигнал обновления (не используется, но оставлю)
// === QSYS система (Platform Designer) ===
dcdc_sys dcdcsys_inst (
.clk_clk (clk_50mhz),
.reset_reset_n (reset_n),
.fifoed_avalon_uart_0_external_connection_rxd (fifoed_avalon_uart_0_external_connection_rxd),
.fifoed_avalon_uart_0_external_connection_txd (fifoed_avalon_uart_0_external_connection_txd),
.pwm_value_external_connection_export (pwm_value_export),
.pwm_enable_external_connection_export (pwm_enable_export)
);
// === Регистр для хранения скважности ===
reg [15:0] duty_reg;
// Защёлкиваем значение скважности от Nios II
always @(posedge clk_50mhz or negedge reset_n) begin
if (!reset_n) begin
duty_reg <= 16'h0000;
end else begin
duty_reg <= pwm_value_export; // скважность из программы на C
end
end
// === Генерация 4-х ШИМ сигналов с фазовым сдвигом ===
// Канал 0: без сдвига
pwm_generator_100khz pwm0 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h0000), // 0 тактов
.pwm_out (pwm_out[0])
);
// Канал 1: сдвиг 125 тактов (90° при 500 тактах)
pwm_generator_100khz pwm1 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h007D), // 125 тактов
.pwm_out (pwm_out[1])
);
// Канал 2: сдвиг 250 тактов (180°)
pwm_generator_100khz pwm2 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h00FA), // 250 тактов
.pwm_out (pwm_out[2])
);
// Канал 3: сдвиг 375 тактов (270°)
pwm_generator_100khz pwm3 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h0177), // 375 тактов
.pwm_out (pwm_out[3])
);
endmoduleЧто изменилось: раньше duty_reg был жёстко привязан к константе 16'h00FA. Теперь он получает значение из pwm_value_export — это выход PIO, которым управляет процессор Nios II.
Базовый модуль pwm_generator_100khz остался без изменений — он считает такты и сравнивает с duty.
3. Что такое Nios II и как создать проект
Nios II — это 32-битный процессор, который «зашивается» внутрь ПЛИС. Он позволяет выполнять программы на языке C и управлять всей периферией, которую мы добавили в Platform Designer (UART, PIO, память). Проще говоря, Nios II превращает ПЛИС в полноценный микроконтроллер с возможностью аппаратного ускорения.
Как открыть Nios II Software Build Tools for Eclipse
1. Запускаем Quartus Prime с открытым проектом.
2. В верхнем меню выбираем Tools → Nios II Software Build Tools for Eclipse.

3. Eclipse запускается. Если это произошло впервые, он попросит выбрать рабочую область (workspace).

Если Eclipse не открывается: В Quartus Prime Lite 23.1 Nios II SBT требует WSL (Windows Subsystem for Linux). Убедитесь, что WSL установлен и имеет версию 1 (Nios II не поддерживает WSL2).
Создаём проект для Nios II
1. В Eclipse: File → New → Nios II Application and BSP from Template.
2. В поле SOPC Information File name указываем путь к файлу .sopcinfo (он лежит в папке проекта Quartus и был сгенерирован Platform Designer).

3. Выбираем название для проекта и снизу в списке выбираем Hello World Small.

Это создаст для нас проект для вывода Hello World на консоль с минимальной занятостью памяти.
В левой части мы увидим две папки. Одну с просто названием проекта и вторую с добавкой ‘bsp’ в конце. Расшифровывается как Board Support Packagе, он является неким переводчиком между вашим софтом и аппаратной частью. В него входят все файлы как драйвера, конфигурации и параметры всех компонентов для быстрого доступа.
4. Project name — например, dcdc.
5. Нажимаем Finish.
Теперь в Eclipse появилось два проекта: dcdc (наше приложение) и dcdc _bsp (библиотека с драйверами). В BSP автоматически сгенерирован файл system.h, где прописаны адреса всех наших PIO и UART.

Пишем код для Nios
На этом этапе нас интересует только файл hello_world_small.c, открываем его и удаляем весь код, он нам не понадобится.
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#define PWM_PERIOD_TICKS 500 // полный период 500 тактов
void set_pwm_duty(int percent) {
int ticks;
if (percent < 0) percent = 0;
if (percent > 100) percent = 100;
ticks = (percent * PWM_PERIOD_TICKS) / 100;
IOWR_ALTERA_AVALON_PIO_DATA(PWM_VALUE_BASE, ticks);
IOWR_ALTERA_AVALON_PIO_DATA(PWM_ENABLE_BASE, 1); // импульс обновления
usleep(10);
IOWR_ALTERA_AVALON_PIO_DATA(PWM_ENABLE_BASE, 0);
}
int main() {
char c;
int pwm_percent = 50;
printf("Commands: 0-9 (0%%..90%%)\r\n");
set_pwm_duty(pwm_percent);
while (1) {
c = alt_getchar();
if (c >= '0' && c <= '9') {
pwm_percent = (c - '0') * 10;
set_pwm_duty(pwm_percent);
printf("PWM = %d%%\r\n", pwm_percent);
}
}
return 0;
}
Что происходит в коде:
- PWM_VALUE_BASE — адрес PIO, по которому мы записываем скважность.
- PWM_ENABLE_BASE — адрес PIO для сигнала обновления.
- usleep(10) — короткая задержка для формирования импульса обновления.
- alt_getchar () — читает символ из UART.
Компиляция и прошивка
1. Кликаем правой кнопкой на проект dcdc → Build Project.
2. В консоли появляется процесс компиляции. Если ошибок нет — всё готово.
3. Открываем Quartus Programmer (Tools → Quartus Prime Programmer), прошиваем ПЛИС файлом .sof.
4. Возвращаемся в Eclipse: правой кнопкой на dcdc → Run As → Nios II Hardware.
5. Программа загружается в память ПЛИС и запускается.
5. Настройка терминала YAT
Для связи с устройством я использую программу YAT (Yet Another Terminal). Её можно скачать бесплатно.
Настройки YAT:

Подключаем адаптер к пинам ПЛИС, которые в Platform Designer назначены как fifoed_avalon_uart_external_connection.
После запуска программы в окне YAT появляется: «Commands: 0-9 (0%%..90%%)»
Вводим 5 → программа отвечает PWM = 50%.
Вводим 8 → PWM = 80%.
Вводим 1→ PWM = 10%.

6. Результат: осциллограммы при 10%, 50% и 80% заполнения
Подключаем осциллограф к выходу pwm_out[0]. Частота ШИМ — 100 кГц (период 10 мкс).
При 10% скважности (команда 1): Импульс длится 1 мкс, пауза 9 мкс.
При 50% скважности (команда 5): Импульс длится 5 мкс, пауза 5 мкс.
При 80% скважности (команда 8): Импульс длится 8 мкс, пауза 2 мкс.

Рис. 1 — Осциллограмма ШИМ при 10% заполнения (скважность 10%)

Рис. 2 — Осциллограмма ШИМ при 50% заполнения

Рис. 3 — Осциллограмма ШИМ при 80% заполнения
На всех осциллограммах хорошо видно, что частота остаётся 100 кГц, а ширина импульса меняется в соответствии с командой из терминала.
Ключевые выводы
1. UART — простой и удобный интерфейс для управления устройством с компьютера.
2. PIO-порты позволяют процессору Nios II влиять на аппаратную логику в реальном времени.
3. Nios II — это полноценный процессор внутри ПЛИС, который работает на частоте 50 МГц.
4. Программа на C компилируется в Eclipse, после чего загружается в память ПЛИС через USB-Blaster.
5. Терминал YAT — удобный инструмент для отправки команд и просмотра вывода.
6. Осциллограф подтверждает, что ШИМ меняется именно так, как мы задали.
Список литературы
1. Intel. (2017, July 6). Intel® MAX® 10 analog to digital converter user guide (Document ID: UG-M10ADC). Intel Corporation. https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug-m10adc.pdf
2. Intel Corporation. (2023, August 15). Embedded peripherals IP user guide (Document ID: UG-01085; Document No. 683130). https://www.intel.com/content/www/us/en/docs/programmable/683130
3. Intel. (2024, February 21). Intel® Quartus® Prime Standard Edition User Guide: Timing Analyzer (Version 18.1 Public, ID 683068). https://www.intel.com/content/www/us/en/docs/programmable/683068/18-1/timing-analysis-introduction.html
4. Intel Corporation. (2023, January 8). Intel® MAX® 10 FPGA (10M08S, 144-EQFP) evaluation kit user guide (Document No. 812857). https://www.intel.com/content/www/us/en/docs/programmable/812857
5. Коспанов, Т. Передача данных с АЦП ПЛИС Altera Max 10 на ПК. Часть 1 [Электронный ресурс] / Т. Коспанов. — Астана: Astana Hub, 2025. — Режим доступа: https://astanahub.com/ru/blog/peredacha-dannykh-s-atsp-plis-altera-max-10-na-pk-chast-21760615739, свободный.
6. Коспанов, Т. Передача данных с АЦП ПЛИС Altera Max 10 на ПК. Часть 2 [Электронный ресурс] / Т. Коспанов. — Астана: Astana Hub, 2025. — Режим доступа: https://astanahub.com/ru/blog/razrabotka-po-dlia-plis1756626565, свободный.
Разработка масштабируемого многофазного преобразователя постоянного тока с малыми пульсациями с цифровой системой управления. Часть 7: Управление ШИМ через UART
В прошлой части мы написали модуль генерации ШИМ на SystemVerilog и убедились, что он работает. Однако скважность была жёстко задана в коде — 50%. Это нормально для первого теста, но для реального использования нам нужно менять скважность динамически.
В этой части мы добавим в систему UART и сделаем так, чтобы скважностью можно было управлять из терминала на компьютере.
Что мы сделаем:
- Внесём небольшие поправки в топ-модуль dcdc_1.sv.
- Познакомимся с Nios II и создадим программный проект.
- Напишем код на C, который читает команды из терминала и меняет скважность.
- Настроим терминал YAT.
- С помощью осциллографа проверим, как меняется ШИМ при разных значениях скважности.
2. Поправки в топ-модуль в Quartus
Система в Platform Designer уже содержит все необходимые модули: процессор Nios II, память, UART и PIO. Нам осталось только правильно их соединить в топ-модуле dcdc_1.sv.
Вот полный код топ-модуля:
module dcdc_1 (
input wire clk_50mhz,
input wire reset_n,
input wire fifoed_avalon_uart_0_external_connection_rxd,
output wire fifoed_avalon_uart_0_external_connection_txd,
output wire [3:0] pwm_out
);
// === PIO для управления ШИМ ===
wire [15:0] pwm_value_export; // значение скважности от Nios II
wire pwm_enable_export; // сигнал обновления (не используется, но оставлю)
// === QSYS система (Platform Designer) ===
dcdc_sys dcdcsys_inst (
.clk_clk (clk_50mhz),
.reset_reset_n (reset_n),
.fifoed_avalon_uart_0_external_connection_rxd (fifoed_avalon_uart_0_external_connection_rxd),
.fifoed_avalon_uart_0_external_connection_txd (fifoed_avalon_uart_0_external_connection_txd),
.pwm_value_external_connection_export (pwm_value_export),
.pwm_enable_external_connection_export (pwm_enable_export)
);
// === Регистр для хранения скважности ===
reg [15:0] duty_reg;
// Защёлкиваем значение скважности от Nios II
always @(posedge clk_50mhz or negedge reset_n) begin
if (!reset_n) begin
duty_reg <= 16'h0000;
end else begin
duty_reg <= pwm_value_export; // скважность из программы на C
end
end
// === Генерация 4-х ШИМ сигналов с фазовым сдвигом ===
// Канал 0: без сдвига
pwm_generator_100khz pwm0 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h0000), // 0 тактов
.pwm_out (pwm_out[0])
);
// Канал 1: сдвиг 125 тактов (90° при 500 тактах)
pwm_generator_100khz pwm1 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h007D), // 125 тактов
.pwm_out (pwm_out[1])
);
// Канал 2: сдвиг 250 тактов (180°)
pwm_generator_100khz pwm2 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h00FA), // 250 тактов
.pwm_out (pwm_out[2])
);
// Канал 3: сдвиг 375 тактов (270°)
pwm_generator_100khz pwm3 (
.clk (clk_50mhz),
.reset_n (reset_n),
.duty (duty_reg),
.phase_shift (16'h0177), // 375 тактов
.pwm_out (pwm_out[3])
);
endmoduleЧто изменилось: раньше duty_reg был жёстко привязан к константе 16'h00FA. Теперь он получает значение из pwm_value_export — это выход PIO, которым управляет процессор Nios II.
Базовый модуль pwm_generator_100khz остался без изменений — он считает такты и сравнивает с duty.
3. Что такое Nios II и как создать проект
Nios II — это 32-битный процессор, который «зашивается» внутрь ПЛИС. Он позволяет выполнять программы на языке C и управлять всей периферией, которую мы добавили в Platform Designer (UART, PIO, память). Проще говоря, Nios II превращает ПЛИС в полноценный микроконтроллер с возможностью аппаратного ускорения.
Как открыть Nios II Software Build Tools for Eclipse
1. Запускаем Quartus Prime с открытым проектом.
2. В верхнем меню выбираем Tools → Nios II Software Build Tools for Eclipse.

3. Eclipse запускается. Если это произошло впервые, он попросит выбрать рабочую область (workspace).

Если Eclipse не открывается: В Quartus Prime Lite 23.1 Nios II SBT требует WSL (Windows Subsystem for Linux). Убедитесь, что WSL установлен и имеет версию 1 (Nios II не поддерживает WSL2).
Создаём проект для Nios II
1. В Eclipse: File → New → Nios II Application and BSP from Template.
2. В поле SOPC Information File name указываем путь к файлу .sopcinfo (он лежит в папке проекта Quartus и был сгенерирован Platform Designer).

3. Выбираем название для проекта и снизу в списке выбираем Hello World Small.

Это создаст для нас проект для вывода Hello World на консоль с минимальной занятостью памяти.
В левой части мы увидим две папки. Одну с просто названием проекта и вторую с добавкой ‘bsp’ в конце. Расшифровывается как Board Support Packagе, он является неким переводчиком между вашим софтом и аппаратной частью. В него входят все файлы как драйвера, конфигурации и параметры всех компонентов для быстрого доступа.
4. Project name — например, dcdc.
5. Нажимаем Finish.
Теперь в Eclipse появилось два проекта: dcdc (наше приложение) и dcdc _bsp (библиотека с драйверами). В BSP автоматически сгенерирован файл system.h, где прописаны адреса всех наших PIO и UART.

Пишем код для Nios
На этом этапе нас интересует только файл hello_world_small.c, открываем его и удаляем весь код, он нам не понадобится.
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#define PWM_PERIOD_TICKS 500 // полный период 500 тактов
void set_pwm_duty(int percent) {
int ticks;
if (percent < 0) percent = 0;
if (percent > 100) percent = 100;
ticks = (percent * PWM_PERIOD_TICKS) / 100;
IOWR_ALTERA_AVALON_PIO_DATA(PWM_VALUE_BASE, ticks);
IOWR_ALTERA_AVALON_PIO_DATA(PWM_ENABLE_BASE, 1); // импульс обновления
usleep(10);
IOWR_ALTERA_AVALON_PIO_DATA(PWM_ENABLE_BASE, 0);
}
int main() {
char c;
int pwm_percent = 50;
printf("Commands: 0-9 (0%%..90%%)\r\n");
set_pwm_duty(pwm_percent);
while (1) {
c = alt_getchar();
if (c >= '0' && c <= '9') {
pwm_percent = (c - '0') * 10;
set_pwm_duty(pwm_percent);
printf("PWM = %d%%\r\n", pwm_percent);
}
}
return 0;
}
Что происходит в коде:
- PWM_VALUE_BASE — адрес PIO, по которому мы записываем скважность.
- PWM_ENABLE_BASE — адрес PIO для сигнала обновления.
- usleep(10) — короткая задержка для формирования импульса обновления.
- alt_getchar () — читает символ из UART.
Компиляция и прошивка
1. Кликаем правой кнопкой на проект dcdc → Build Project.
2. В консоли появляется процесс компиляции. Если ошибок нет — всё готово.
3. Открываем Quartus Programmer (Tools → Quartus Prime Programmer), прошиваем ПЛИС файлом .sof.
4. Возвращаемся в Eclipse: правой кнопкой на dcdc → Run As → Nios II Hardware.
5. Программа загружается в память ПЛИС и запускается.
5. Настройка терминала YAT
Для связи с устройством я использую программу YAT (Yet Another Terminal). Её можно скачать бесплатно.
Настройки YAT:

Подключаем адаптер к пинам ПЛИС, которые в Platform Designer назначены как fifoed_avalon_uart_external_connection.
После запуска программы в окне YAT появляется: «Commands: 0-9 (0%%..90%%)»
Вводим 5 → программа отвечает PWM = 50%.
Вводим 8 → PWM = 80%.
Вводим 1→ PWM = 10%.

6. Результат: осциллограммы при 10%, 50% и 80% заполнения
Подключаем осциллограф к выходу pwm_out[0]. Частота ШИМ — 100 кГц (период 10 мкс).
При 10% скважности (команда 1): Импульс длится 1 мкс, пауза 9 мкс.
При 50% скважности (команда 5): Импульс длится 5 мкс, пауза 5 мкс.
При 80% скважности (команда 8): Импульс длится 8 мкс, пауза 2 мкс.

Рис. 1 — Осциллограмма ШИМ при 10% заполнения (скважность 10%)

Рис. 2 — Осциллограмма ШИМ при 50% заполнения

Рис. 3 — Осциллограмма ШИМ при 80% заполнения
На всех осциллограммах хорошо видно, что частота остаётся 100 кГц, а ширина импульса меняется в соответствии с командой из терминала.
Ключевые выводы
1. UART — простой и удобный интерфейс для управления устройством с компьютера.
2. PIO-порты позволяют процессору Nios II влиять на аппаратную логику в реальном времени.
3. Nios II — это полноценный процессор внутри ПЛИС, который работает на частоте 50 МГц.
4. Программа на C компилируется в Eclipse, после чего загружается в память ПЛИС через USB-Blaster.
5. Терминал YAT — удобный инструмент для отправки команд и просмотра вывода.
6. Осциллограф подтверждает, что ШИМ меняется именно так, как мы задали.
Список литературы
1. Intel. (2017, July 6). Intel® MAX® 10 analog to digital converter user guide (Document ID: UG-M10ADC). Intel Corporation. https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug-m10adc.pdf
2. Intel Corporation. (2023, August 15). Embedded peripherals IP user guide (Document ID: UG-01085; Document No. 683130). https://www.intel.com/content/www/us/en/docs/programmable/683130
3. Intel. (2024, February 21). Intel® Quartus® Prime Standard Edition User Guide: Timing Analyzer (Version 18.1 Public, ID 683068). https://www.intel.com/content/www/us/en/docs/programmable/683068/18-1/timing-analysis-introduction.html
4. Intel Corporation. (2023, January 8). Intel® MAX® 10 FPGA (10M08S, 144-EQFP) evaluation kit user guide (Document No. 812857). https://www.intel.com/content/www/us/en/docs/programmable/812857
5. Коспанов, Т. Передача данных с АЦП ПЛИС Altera Max 10 на ПК. Часть 1 [Электронный ресурс] / Т. Коспанов. — Астана: Astana Hub, 2025. — Режим доступа: https://astanahub.com/ru/blog/peredacha-dannykh-s-atsp-plis-altera-max-10-na-pk-chast-21760615739, свободный.
6. Коспанов, Т. Передача данных с АЦП ПЛИС Altera Max 10 на ПК. Часть 2 [Электронный ресурс] / Т. Коспанов. — Астана: Astana Hub, 2025. — Режим доступа: https://astanahub.com/ru/blog/razrabotka-po-dlia-plis1756626565, свободный.