
Когда пишут программу HelloWorld на C, обычно выводят текст “Hello, World!”. Но когда программа пишется для микроконтроллера, часто ограничиваются миганием светодиода, особенно для микроконтроллеров семейства STM32.
В статье я разберу, как можно вывести “Hello World” в программе для микроконтроллеров этого семейства.
Для микроконтроллера RP2040 вывести “Hello world” проще, чем для микроконтроллеров STM32, пишешь printf("Hello, world!\n"); и в CMakefiles.txt указываешь использовать USB или UART для вывода. Для STM32 ситуация другая — нужно больше действий от программиста.
Вывод отладочной информации не доступен «из коробки» и может потребовать дополнительной настройки: выбора UART, подключения USB-UART преобразователя или использования отладочного интерфейса ST-LINK/J-Link
Я использовал отладочную плату WeAct Studio на базе микроконтроллера STM32H750VBT6. Плата не имеет встроенного аппаратного отладчика ST-Link и не предоставляет виртуальный COM-порт для отладки, у отладочных плат Discovery и NUCLEO, поэтому я использовал китайские клоны отладчиков ST-Link и J-Link.
Разрабатывая простую программу “Hello world” на микроконтроллере STM32, можно узнать много нового, систематизировать и улучшить свои знания.
Примеры, приведённые в статье, доступны в моём GitHub репозитории
Начнём с краткой теории.
STM32
После RP2040 разработка для STM32 кажется гораздо сложнее.
Если у RP2040 это один чип, то STM32 объединяет множество чипов от простых Cortex-M0 (серия F0/G0) до Cortex-M7 (серия H7) с частотами под 480 МГц, DSP и аппаратным ускорением графики. Под каждую задачу подбирают свой чип STM32.
Разработка для STM32 может вестись на трёх уровнях: CMSIS, LL и HAL.
CMSIS — прямой доступ к регистрам. Максимальная скорость и минимальный размер кода, но нужно наизусть знать тысячестраничный Reference Manual.
LL (Low-Layer) — лёгкая обёртка из inline-функций над регистрами. Быстро и прозрачно, но привязано к конкретному чипу.
HAL (Hardware Abstraction Layer) — тяжёлый высокоуровневый API. Позволяет легко переносить код между разными STM32, но расплачиваться приходится раздутым размером прошивки и медлительностью.
Перед началом работы с микроконтроллером в программном коде его необходимо сконфигурировать: настроить периферию и тактовые частоты для неё.
Главный шок после RP2040 — это дерево тактирования (Clock Tree). На RP2040 частоты настраиваются парой строчек. В STM32 нужно вручную связать цепочку из кварцев (HSI/HSE), множителей PLL и делителей Bus Prescalers. Поэтому обычно конфигурацию выполняют при помощи STM32CubeMX с последующей генерацией кода под разные IDE или системы сборки.
Так как подразумевается, что возможно придётся изменять конфигурацию и добавлять периферию в сгенерированном коде генерируются специальные теги в виде комментариев, куда программист может вписывать свой код.
Для меня это выглядит неуклюже, так как код содержит визуальный мусор, который отвлекает. Но видимо, от Legacy здесь не откажешься.
Этот визуальный мусор можно убрать, или добавив несколько вызовов ваших функций, которые будут уже реализовывать основную логику работы, между тегов, или отказаться от CubeMX и выполнить инициализацию периферии с нуля, что потребует большего изучения спецификаций конкретного микроконтроллера и понимания работы с микроконтроллером на низком уровне.
Высокий порог входа и «монструозная» экосистема STM32 — это плата за промышленный стандарт, гибкость и возможность подобрать чип точно под бюджет и задачи проекта.
Что необходимо для сборки, компиляции и отладки кода для STM32
Естественно, что нужен сам микроконтроллер, вернее, нужна отладочная плата с микроконтроллером.
Как я говорил ранее, я использовал плату WeAct Studio. Вы можете использовать её или какую-нибудь другую плату на базе STM32, например, так называемые Blue Pill и Black Pill.

Как и для любых других микроконтроллеров, кроме самого микроконтроллера, для разработки под STM32 необходимы:
Кросс-тулчейн.
Система сборки.
Интегрированная среда разработки.
SDK и библиотеки.
Программатор.
Аппаратный отладчик.
USB-UART преобразователь.
Сервер отладки.
Можно обойтись и частью из этого списка. Если вы хорошо владеете командной строкой и понимаете, как работают компилятор, компоновщик, система сборки — интегрированная среда разработки будет опциональна. Если для отладки достаточно вывода текстовых логов по UART, аппаратный отладчик будет лишним.
Чтобы лучше понять, что будет рассказано, далее приведу две схемы:


Они будут справедливы для многих микроконтроллеров (MCU) и STM32 тоже.
Кросс-тулчейн
Тулчейн (toolchain) — это набор программных инструментов, используемых для создания исполняемого файла из исходного кода для конкретной программно-аппаратной платформы.
В этот набор обязательно входят компилятор, ассемблер и компоновщик (линкер), а также могут входить стандартные библиотеки (например, libc), отладчик (debugger) и утилиты для анализа кода.
Кросс-тулчейн (Cross Toolchain) отличается от тулчейна тем, что с помощью него собирают бинарный код, предназначенный для другой платформы, отличной от той, на которой разрабатывают.
Система сборки
В отличие от тулчейна (который просто транслирует код), система сборки (например, Make, CMake, Ninja, MSBuild) автоматизирует весь процесс.
Вы описываете конечную цель (target), исходные файлы и зависимости, а система сама решает, в каком порядке и с какими параметрами вызывать компилятор и компоновщик.
Система сборки (Build System) управляет процессом через три ключевых понятия:
Цели (Targets): Что именно нужно получить. Это может быть исполняемый файл, статическая/динамическая библиотека или даже промежуточный этап (например, генерация документации).
Зависимости (Dependencies): Файлы или другие цели, которые необходимы для создания текущей цели. Например, чтобы собрать исполняемый файл app, сначала нужно скомпилировать файлы main.o и utils.o, а для них, в свою очередь, нужны исходники main.c, utils.c и заголовочные файлы .h.
Артефакты: Результаты сборки (объектные файлы, библиотеки и сам итоговый исполняемый файл).
Среды разработки
Для разработки и отладки STM32 существует несколько сред разработки (IDE).
STM32CubeIDE: Официальная бесплатная среда от компании STMicroelectronics, основанная на Eclipse и GCC. STM32CubeIDE: считается базовым и самым надёжным выбором для старта.

VS Code (Visual Studio Code) с плагинами: Универсальный текстовый редактор, который превращается в мощную IDE с помощью расширений (например, PlatformIO или официального расширения STM32 VS Code Extension). Часто используется в связке с CMake и отдельно запущенным CubeMX для генерации кода.

CLion: Платная профессиональная IDE от JetBrains с поддержкой Embedded-разработки. Доступна бесплатная лицензия для образовательных целей или 30-дневный пробный период.

Существуют ещё платные профессиональные среды IAR Embedded Workbench и Keil MDK, но для “Hello World" подойдут и первые три.
В процессе подготовки статьи я обнаружил, что каждая из сред имеет свои особенности. При использовании клонов J-Link v9 и ST-Link не всегда удобно или возможно вывести отладочное сообщение в той или иной среде.
Замечание о кроссплатформенности: Изначально экосистема STM32 была жёстко привязана к Windows, но сегодня разработка на Linux и macOS стала полноценным стандартом. Вся разработка в рамках этой статьи выполнялась под Linux.
SDK и библиотеки
Чтобы не работать с регистрами микроконтроллера напрямую «по адресам в памяти», используются готовые библиотеки от производителя или сообщества:
CMSIS (Cortex Microcontroller Software Interface Standard): Абстракция ядра от ARM.
HAL / LL от STMicroelectronics: Официальные библиотеки. HAL предоставляет высокоуровневый API, а LL (Low-Layer) — быстрые inline-обёртки над регистрами.
LibOpenCM3: Альтернатива официальному SDK с чистым и лаконичным API.
Программаторы и аппаратные отладчики
Часто аппаратный отладчик (Debug Probe) совмещён с программатором (Programmer).
ST-Link (STMicroelectronics)
Так как мы выводим “Hello World” на микроконтроллере STM32, рассмотрим программаторы ST-Link первыми. Если вы используете отладочную плату STM32 NUCLEO или STM32 DISCOVERY, то программатор ST-Link уже распаян на ней.
Также существуют отдельные устройства: как оригинальные от STMicroelectronics, так и их китайские клоны. Главное отличие большинства дешёвых клонов — отсутствие поддержки вывода SWO (Serial Wire Output), что ограничивает возможности быстрой отладки и трассировки.

J-Link
J-Link — аппаратный отладчик от компании SEGGER, совместно с ПО для компьютера поддерживает множество различных микроконтроллеров и отладочных плат.
На рынке существуют китайские клоны для этого отладчика. Насколько мне известно, компания борется с производством клонов, и клон можно окирпичить, если согласиться на обновление прошивки отладчика.

CMSIS-DAP / DAP-Link
DAP-Link — это референсная имплементация CMSIS-DAP с открытым программным кодом от ARM для аппаратных отладчиков.
Pico Debug Probe является примером ещё одной реализации CMSIS-DAP.
Так как у Pico Debug Probe используется RP2040, который не содержит модуля ITM, использование SWO невозможно.
Многие IDE для STM32 не содержат встроенной поддержки СMSIS-DAP, но если установить сервер отладки OpenOCD, то теоретически можно прошить и отладить код для STM32.
ST-Link и J-link это и физические устройства, и прошивка микроконтроллера. Имея прошивку, можно плату с микроконтроллером превратить в аппаратный отладчик и программатор.
Прошивки, поддерживающие стандарт CMSIS-DAP, также можно установить на микроконтроллеры и отладочные платы и получить из них программатор и аппаратный отладчик. Так, например, получается Pico Debug Probe из Raspberry Pi Pico.
USB-UART преобразователи (CP2102, FT232, CH340)

USB-UART преобразователь, наверное, самое простое и привычное устройство для получения диагностических сообщений от микроконтроллера. Если вы когда-нибудь разбирали роутер или телевизионную приставку, то видели нераспаянный 4 пиновый разъём на плате (TX, RX, GND, Vcc). Это и есть разъём для подключения преобразователя.
Пины TX и RX платы и преобразователя подключаются перекрёстно. TX платы с RX преобразователя, RX платы с TX преобразователя.
Для просмотра того, что выводит микроконтроллер на печать на компьютере, должен быть запущен эмулятор терминала, который подключён к виртуальному COM-порту (VCP), создаваемому драйвером USB-UART преобразователя.
Времена, когда нужно было искать и устанавливать драйвер в операционной системе вручную прошли. Но если у вас преобразователь на базе CH340 и операционная система Windows, вечер, потраченный на понимание, как же всё-таки загружаются драйвера в Windows, вам гарантирован.
Для просмотра сообщений, приходящих по UART, под Windows я обычно использую Putty, в Linux — picocom. Вам нужно знать параметры UART-протокола, который использует устройство (скорость передачи, используется ли проверка бита чётности (parity), количество стоп-бит). Если вы укажете их неправильно при старте эмулятора терминала, вы увидите мусор или вообще ничего.
Обычно используются три пина из четырёх: TX, RX и GND, а пин питание не используется, так как питание подаётся на устройство обычным образом.
Также нужно быть внимательным к используемым уровням логики. Может быть 1.8 В, 3.3 В, 5 В. Чтобы ничего не сжечь, они должны быть одинаковые. Узнать, какие уровни использует устройство можно, замерив напряжение на пине ТХ.
Обычно производители оставляют поддержку вывода диагностики по UART даже в потребительских устройствах.
UART можно успешно использовать для вывода “Hello, World”, но существуют другие способы, позволяющие это сделать.
Физические интерфейсы связи
Для взаимодействия микроконтроллера с аппаратным отладчиком или программатором используется несколько аппаратных интерфейсов:
JTAG,
SWD,
UART.
Последний интерфейс не обязательно используется для подключения к аппаратному отладчику. Микроконтроллер можно подключить к компьютеру через USB-UART преобразователь.
JTAG — классический многопроводный интерфейс (TDI, TDO, TMS, TCK).
SWD (Serial Wire Debug) — двухпроводная альтернатива от ARM (SWDIO, SWCLK).
UART (Universal Asynchronous Receiver-Transmitter) — текстовая связь (TX, RX).
Методы вывода текстовой отладочной информации
Semihosting
Sеmihosting — самый медленный метод вывода отладочных сообщений, так как при выводе строки или символа процессор микроконтроллера прерывает свою работу и ожидает обработки компьютером.
Текстовая отладочная информация выводится в консоль отладчика, также информацию можно посмотреть, подключившись к telnet-серверу, который создаёт сервер отладки.
У меня упорно не хотел работать semihosting при использовании сервера отладки J-Link совместно с аппаратным отладчиком J-Link. При использовании сервера отладки STLink и аппаратного отладчика STLink всё работало как положено. Мне удалось добиться работы semihosting с аппаратным отладчиком JLink, используя сервер отладки OpenOCD.
SWO (Serial Wire Output)
На микроконтроллерах с ядрами Сortex M3 и старше доступен метод вывода отладочных сообщений через отдельный пин SWO. В архитектуру встроен специальный модуль трассировки ITM (Instrumentation Trace Macrocell), который позволяет выводить отладочные сообщения через один выделенный пин SWO (Serial Wire Output). На более младших ядрах вроде Cortex-M0 и Cortex-M0+ этот функционал отсутствует. Для включения ITM нужно правильно сконфигурировать микроконтроллер. Также нужно правильно настроить частоту для SWV.
SWO поддерживается аппаратными отладчиками ST-Link и J-Link. Но китайские клоны ST-Link могут не содержать пина SWO. У меня именно такой.
На пин SWO информация выводится с использованием асинхронного протокола. SWO очень напоминает работу пина TX в UART. Когда SWO корректно сконфигурирован и находится в состоянии IDLE, на пине логическая единица.
На пин SWO может выводиться не только текстовые отладочные сообщения, но и другая отладочная информация.
SEGGER RTT (Real Time Transfer)
Если у вас аппаратный отладчик J-Link можно воспользоваться фирменной технологией от SEGGER, которая называется RTT (Real Time Transfer).
UART
UART — самый привычный способ вывода отладочной информации. Большинство устройств оставляют пины UART (TX, RX, GND, VCC) куда выводится отладочная информация при загрузке устройства.
Хотя многие аппаратные отладчики содержат пины TX и RX и создают виртуальный COM-порт для взаимодействия с устройством по UART, просмотреть отладочную информацию можно и без аппаратного отладчика. Достаточно подключить UART-USB адаптер.
При использовании UART в STM32, его необходимо настроить в CubeMX.
Практическая часть: Создаём проекты в STM32CubeMX и STM32CubeIDE
UART для вывода Hello, World
Запускаем STM32CubeMX.
-
Выбираем свою модель микроконтроллера или отладочной платы:

Выбор модели микроконтроллера Создаём проект в STM32CubeMX, нажав
Start Project.-
Выполняем конфигурирование UART-интерфейса. Обратите внимание, какие значения у
Basic Parameters, и какие пины используются для выбраного UART-интерфейса. Это понадобится позже для подключения UART-адаптера.
Конфигурирование UART-интерфейса -
Заходим на вкладку
Clock Configurationи соглашаемся на автоматическое конфигурирование.
-
На вкладке
Project Mananagerзаполняем поляProject NameиProject Location. Выбираем значениеCMakeв полеToolchain/IDE.
-
На вкладке
Code Generatorставим флажокGenerate peripheral initialization as pair of '.c/.h' files per peripheral.
Нажимаем кнопку
GENERATE CODE.Запускаем STM32CubeIDE и создаём новый Workspace.
-
Импортируем проект в STM32CuberIDE:

-
Выбираем свою модель микроконтроллера:

Собираем проект.
Создаём конфигурацию для отладки.
-
STM32CubeMX сгенерировал большинство кода за нас. Нам нужно подключить заголовочный файл
stdio.hв файлеmain.c/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */ -
Определяем функцию
_write:/* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ int _write(int file, char *ptr, int len) { HAL_UART_Transmit(&huart3, (uint8_t *)ptr, len, HAL_MAX_DELAY); return len; } /* USER CODE END 0 */ -
Вызываем функцию
printf():/* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ printf("UART Hello world \n"); HAL_Delay(1000); } /* USER CODE END 3 */ Перед запуском нужно подключить аппаратный отладчик и USB-UART преобразователь к микроконтроллеру и компьютеру. Я использовал J-Link, который может параллельно работать как USB-UART преобразователь.
-
Запускаем отладку. Результат можно посмотреть в эмуляторе терминала, подключённому к виртуальному COM-порту. Такой эмулятор терминала можно или создать в STM32CubeIDE или запустить командой:
sudo picocom -b 115200 /dev/ttyACM1где
ttyACM1— имя виртуального COM-порта в Linux.
Semihosting для вывода Hello, World
Вывод с использованием Semihosting немного сложнее, так необходимо выполнить несколько неочевидных действий.
Создаём и импортируем проект из STM32CubeMX, как мы делали ранее.
Создаём и настраиваем конфигурацию отладки, выбрав отладчик STLink.
-
Добавляем опцию для компоновщика в файл
CMakeLists.txttarget_link_options(${CMAKE_PROJECT_NAME} PRIVATE --specs=rdimon.specs ) -
Добавляем библиотеку
rdimonв файлеCMakeLists.txt# Add linked libraries target_link_libraries(${CMAKE_PROJECT_NAME} stm32cubemx # Add user defined libraries rdimon ) -
Чтобы проект смог собраться, нам нужно исключить из компиляции файл c заглушками
syscalls.c, который сгенерировал STM32CubeMX, так какrdimonдобавляет свои.set_source_files_properties(Core/Src/syscalls.c PROPERTIES HEADER_FILE_ONLY TRUE) -
В файле
main.cподключаем заголовочный файлstdio.h:/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */ -
В файле
main.cдобавляем объявление функцииinitialise_monitor_handles/* USER CODE BEGIN PFP */ extern void initialise_monitor_handles(void); /* USER CODE END PFP */ -
Не забываем её вызвать в начале функции
main():int main(void) { /* USER CODE BEGIN 1 */ initialise_monitor_handles(); /* USER CODE END 1 */ ... -
Используем обычную функцию
printf()для вывода с использованием semihosting.while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ printf("Hello World from Semihosting!\n"); HAL_Delay(1000); }
SWO для вывода Hello, World
Создаём и импортируем проект из STM32CubeMX, как мы делали ранее.
Создаём и настраиваем конфигурацию отладки, выбрав отладчик J-Link.
В конфигурации отладки активируем SWO.
-
В файле
main.cподключаем заголовочный файлstdio.h:/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */ -
Определяем функцию
SWO_PrintString():/* USER CODE BEGIN 0 */ void SWO_PrintString(const char *str) { while (*str) { ITM_SendChar(*str++); } } /* USER CODE END 0 */ -
Для вывода сообщений вызываем функцию
SWO_PrintString():/* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ SWO_PrintString("Hello world from SWO\n"); HAL_Delay(1000); } /* USER CODE END 3 */ -
Чтобы увидеть вывод, необходимо отобразить окно
SWV ITM Data Console:
Запускаем отладку.
-
В
SWV ITM Data Consoleактивируем мониторинг, нажав на кнопку с красным кружочком:
-
Нажимаем на кнопку с изображением инструментов и активируем
Stimulus port 0:
Наблюдаем вывод.
RTT для вывода Hello, World
Создаём и импортируем проект из STM32CubeMX, как мы делали ранее.
Создаём и настраиваем конфигурацию отладки, выбрав отладчик J-Link.
-
В терминале клонируем библиотеку RTT:
git clone https://github.com/SEGGERMicro/RTT.git В директорию
Core/Srcкопируем два файла из библиотекиRTT–SEGGER_RTT.cиSEGGER_RTT_printf.c.В директорию
Core/Incкопируем два файла из библиотекиRTT-SEGGER_RTT.hиSEGGER_RTT_ConfDefaults.h.-
Директории
Core/Incсоздаём пустой файлSEGGER_RTT_Conf.htouch SEGGER_RTT_Conf -
В файле
CMakeLists.txtдобавляем исходные файлы RTT:# Add sources to executable target_sources(${CMAKE_PROJECT_NAME} PRIVATE # Add user sources here Core/Src/SEGGER_RTT.c Core/Src/SEGGER_RTT_printf.c ) -
В файле
main.cподключаем заголовочный файлSEGGER_RTT.h:/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "SEGGER_RTT.h" /* USER CODE END Includes */ -
Выводим текст:
/* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ SEGGER_RTT_printf(0, "Hello World from SEGGER!\n"); HAL_Delay(1000); } /* USER CODE END 3 */ Запускаем отладку.
-
Запускаем из консоли
JLinkRTTViewer:
С чем я столкнулся при подготовке примеров
Маркетологи не зря хлеб едят, но когда гордо заявлено о поддержке той или иной фичи, всё-таки нужно самому смотреть, что и как реализовано.
Например:
Мне не удалось вывести “Hello World” средствами semihosting, используя сервер отладки J-Link. Пробовал все доступные версии для моей операционной системы, похоже на то, что в ПО J-Link здесь присутствует долгоживущий баг, по крайней мере, для ОС Linux.
Я не обнаружил простого способа отладки с использованием semihosting для аппаратного отладчика ST-Link в CLion.
Я долго не мог вывести в CLion отладочное сообщение средствами SWO для аппаратного отладчика J-Link, пока не обновил ПО J-Link на компьютере на самую свежую версию.
Заключение
На первый взгляд Hello World для микроконтроллера кажется совсем простой задачей. Но в случае STM32 за привычным printf() скрывается целая цепочка: микроконтроллер должен быть правильно настроен, сообщение — перенаправлено на выбранный интерфейс, а компьютер — получить и отобразить его.
В этой статье мы посмотрели на несколько способов сделать это: обычный UART, semihosting, SWO/ITM и SEGGER RTT. У каждого способа есть свои особенности, преимущества и ограничения. UART прост, понятен и не требует полноценного аппаратного отладчика. SWO позволяет получать отладочную информацию через интерфейс отладки, не занимая обычный UART. RTT предлагает удобный способ обмена данными с микроконтроллером при использовании J-Link. Semihosting прост с точки зрения программы, но сильно зависит от отладчика и при этом заметно влияет на выполнение программы.
На практике оказывается, что выбор способа вывода зависит не только от возможностей микроконтроллера, но и от используемого аппаратного отладчика, его прошивки, сервера отладки и среды разработки. Поэтому одинаковый проект может вести себя по-разному в STM32CubeIDE, VS Code или CLion и с разными ST-Link или J-Link.
Именно поэтому Hello World для STM32 — хороший учебный пример. Он позволяет не просто увидеть строку в терминале, а разобраться, что происходит между вызовом printf() и появлением символов на экране. За этим простым примером обнаруживается довольно большой пласт технологий: периферия STM32, UART, SWD, SWO, ITM, отладочные серверы и инструменты разработки.
После этого printf() уже не выглядит магией. Становится понятно, куда именно отправляется сообщение и какие компоненты обеспечивают его появление в терминале.
А дальше можно перейти от Hello World к настоящей отладке: смотреть значения переменных, трассировать выполнение программы и получать информацию о работе микроконтроллера уже не только через текстовый вывод.
© 2026 ООО «МТ ФИНАНС»
Комментарии (65)

TheHost
29.09.2026 14:38чет как-то сложно, я через програмулину для ардуино прошивал, просто подключив к USB

artyomsoft Автор
29.09.2026 14:38Используя все четыре способа?

TheHost
29.09.2026 14:38Ну в плане 4 способа? Заголовок - hello world, а текст как будто программирование микро контроллера из 2000х. Сейчас все намного проще делается.
У вас же не голый чип, а с интерфейсом на плате, по сути просто подключив его к компьютеру у вас и сериал порт будет и все остальное. А вы зачем-то вооружились программатором и прочим и называете это hello world.

artyomsoft Автор
29.09.2026 14:38Я рассказал про 4 возможных способа получить текстовые сообщения от микроконтроллера на хосте.
Если вы говорите про подкючение по USB отладочной платы WeAct Studio к компьютеру - то не будет сериал порта и всего такого у STM32. Это не Raspberry Pi Pico.
В случае STM32 должна быть плата Nucleo или Disovery. Они содержат в себе отладчик/програматор ST-Link и UART доступен через USB.
На моей плате, как и на известных Blue Pill и Black Pill такой возможности нет. Нужен программатор для заливки прошивки и USB-UART адаптер как минимум для того, чтобы видеть, что мы вывeли на UART.

vojlk
29.09.2026 14:38Если быть точнее, не USB-UART, а USB-TTL. Потому что на плате не распаян приёмопередатчик
И программатор по факту не нужен. Можно прошивать через встроенный загрузчик и stm32flasher. Плюс сразу удобно делать трасировку данных в терминалку по usart1
При таких габаритах платы это в несколько раз удобнее, потому что дополнительная лапша на столе очень мешает отладке
artyomsoft Автор
29.09.2026 14:38По USB-UART адаптером (преобразователем) я имею ввиду устройство на базе CP2102, CH340 и им подобным.
Может я неправильно понимаю архитектуру, но как данные из usart1 попадут в USB без дополнительного чипа?
Но отдадить с точками останова и пошагово не получится же вашим способом?

vojlk
29.09.2026 14:38Без программатора в режим отладки конечно не зайти. Но по сути бесполезная штука, последний раз отладку включал лет 10 назад, потому что как только появляется непрерывный поток данных и обработчики прерываний, то смысл в отладке отпадает. Только контроль пакетов осцилографом + трасировка буфера состояний в терминалку и ногодрыг на тестовом пине
как данные из usart1 попадут в USB без дополнительного чипа
Никак, так же через преобразователь.

NutsUnderline
29.09.2026 14:38USB-UART, а USB-TTL.
смешение физики и логики вижу тут я
Можно прошивать через встроенный загрузчик
в основном уже по usb dfu если речь про stm32. только старые по типу f103 не содержат возможности usb во встроенном загрузчике

vojlk
29.09.2026 14:38смешение физики и логики вижу тут я
Есть такое дело. Профдеформация, привык по старинке такие адаптеры usb to ttl, если на плате не разведен приёмопередатчик под rs422/485.
в основном уже по usb dfu
Согласен, но если это готовое изделие, нужно писать программный переход в dfu, потом этот обработчик в нестираемую область убрать. У меня изделия без usb и очень удобно в кабеле сделать переключатель и сразу одним махом прошивать и потом через этот же разъём данные в терминалку прокидывать

LinkToOS
29.09.2026 14:38не USB-UART, а USB-TTL
Эта штука помогает реализовать виртуальный COM-порт в компьютере. Так что по сути это плата расширения портов компьютера, которая по чистой случайности (из-за изобретения USB) втыкается не во внутренний слот, а в разъем USB.
А процессор подключается к ней без преобразователя уровня (приемопередатчика), потому что "а зачем?".

zambezi9
29.09.2026 14:38Меня тоже минуснули за то что написал, что все на самом деле проще. Это нормально. Есть авторы, которые считают разумным поделиться знаниями с массами как проще и быстрее теперь можно делать то, что раньше было недоступно из-за высокого по трудоемкости порога. Идеалисты, епт. Они верят во что-то там непонятное.
А есть авторы реалисты-прагматики, они пишут с конкретной целью, например показать как все дико сложно и трудоемко. Заказчику потом сунуть под нос статью в уважаемом издании, заказчик впечатлится, прикрепит статью куда-надо и уболтает инвестора отслюнявить больше денежек. А то что те, кто хочет вкатиться в АйТи, подумают, что слишком сложно, - и страна упустит талант в этой как никогда актуальной тематике, - им прагматикам неинтересно.

artyomsoft Автор
29.09.2026 14:38Получается, лучше вообще ничего не писать?

NutsUnderline
29.09.2026 14:38итоговые плюсы покажут ;) хорошо стурктурированный и читаемый материал - гораздо лучше чем клочки инфы по закоулочкам интернета. но проверенный на практике и очищенный от галюцинаций. Как ИИ так и живого автора материала.

CrashLogger
29.09.2026 14:38С Arduino вы никуда не вкатитесь. При трудоустройстве ее лучше вообще не упоминать)

LinkToOS
29.09.2026 14:38На вкладке Project Mananager заполняем поля Project Name и Project Location. Выбираем значение CMake в поле Toolchain/IDE
Почему CMake, если дальше используется STM32CubeIDE? В чем плюсы? Создаются какие-то дополнительные файлы для тонкой настройки проекта?


artyomsoft Автор
29.09.2026 14:38Потом проект проще будет открыть в СLion, если вдруг захотите в нем работать

artyomsoft Автор
29.09.2026 14:38СLion мне даже больше понравился, но с ним не получилось бы использовать все четыре способа вывода текста на имеющихся у меня сейчас устройствах для отладки и разработки. Ну или сложный конфиг для запуска сервера отладки городить. У СLion хуже поддержка серверов отладки.

dlinyj
29.09.2026 14:38А нафига это всё надо? Если есть Makefile и любимая IDE, хоть тот же прекрасный vim...

LinkToOS
29.09.2026 14:38Потому что просто. CubeMX + CubeIDE. Все сразу работает без лишних настроек. Для новичков лучший вариант.
А профи могут и без CubeMX обойтись. Им вообще кю-инициализатор периферии не нравится, кроме clock config.

dlinyj
29.09.2026 14:38Погодите, не поймите меня не правильно, вопрос без вызова. Скорее реально хочу понять.
Я новичок совершенно, буквально разок помигал светодиодом. Но мне понравилась идея инициализации HAL через CubeMX, а дальше я просто сгенерировал проект с Makefile и Visual Studio Code правил то что мне нужно, собирал и шил просто в косноли по классике.Может я что-то упускаю?

artyomsoft Автор
29.09.2026 14:38Но дебажить же проще в IDE? Чем в GDB. Xoтя что-то в дебаге в GDB есть

dlinyj
29.09.2026 14:38Ну вот, пример :). Но vscode может же в связке с gdb работать

artyomsoft Автор
29.09.2026 14:38А VS Code не IDE?
Но я думаю для дебага микроконтроллеоров нужно будет плагины ставить

aabzel
29.09.2026 14:38Но дебажить же проще в IDE? Чем в GDB. Xoтя что-то в дебаге в GDB есть
Зачем Вам эта пошаговая отладка из-под IDE?
Если ваш микроконтроллер поддерживается Segger Jlink (а все STM32 поддерживаются), то делайте пошаговую отладку в Segger Jlink Ozone.
Ozone стартует мгновенно и просто летает!Вот методички про то как это всё настроить и запустить
Программирование плат Nucleo отладчиком J-Link https://habr.com/ru/articles/1060054/ Отладка STM32 программатором J-LINK по SWD https://habr.com/ru/articles/995996/
dlinyj
29.09.2026 14:38Прмедленее, я записываю :)
Если вы посмотрите стоимость jlink оригинала, то будете неприятно удивлены

aabzel
29.09.2026 14:38Никто не покупает оригиналы. Покупайте клон jlink v12 на алиекспресс максимум за 4к руб и все у вас будет работать.

dlinyj
29.09.2026 14:38С ними там свои проблемы, к сожалению, если не домашний проект.

aabzel
29.09.2026 14:38Нет никаких проблем. Везде где я работал используют клоны jlink для коммерческих разработок. Более того используют ещё десятки и десятки клонов переходников PCAN (usb -can преобразователи) .

aabzel
29.09.2026 14:38Да такие случаи были.
А они не могут окирпичиться, если вдруг обновишь их прошивку?
В таких случаях надо откатываться на более старую прошивку и можно снова работать.

NutsUnderline
29.09.2026 14:38прошивка не прошивка, но вот с обновлениями софта на ПК оный софт становится что то подозревать и ругаться. вопрос с руганием решен в случае windows и macos но не очень понятно что делать в случае linux. например не обновлять

NutsUnderline
29.09.2026 14:38Везде где я работал используют клоны jlink
не забываем что есть места где нонче все все должно быть отечественное, из реестра. причем в такие места на aliexpress не вроде как и покупают, да и фирма segger официально не продала бы.

LinkToOS
29.09.2026 14:38Есть люди, которые свой путь в программировании начинают с микроконтроллеров. У них еще никакая среда программирования не развернута. Или те кто делал только приложения для ПК, например в Microsoft Visual C#. Вариантов много.

dlinyj
29.09.2026 14:38Понял, нет причин использовать.

LinkToOS
29.09.2026 14:38Переходить на CubeIDE повода нет, если процесс уже настроен в другой среде. Это тот же eclipse, только настроенный для stm.

aabzel
29.09.2026 14:38Более того stm32cubeide ещё и дольше прогружается при старте и больше тормозит, чем просто голый eclipse.
Переходить на CubeIDE повода нет, если процесс уже настроен в другой среде. Это тот же eclipse, только настроенный для stm.
Да . Именно так.

NutsUnderline
29.09.2026 14:38а можно и не использовать. сгенерировать набор нужных либ, заголовков и make/cmake к ним - а дальше в командой строке + текстовый редактор или любимая IDE

voldemar_d
29.09.2026 14:38ИМХО, как-то это всё сложновато, если это "руководство для новичка". Я вот подумываю заняться написанием чего-нибудь для STM32, но после Arduino как-то рука не поднимается такую кучу всего осваивать (для меня это хобби, а не работа).
Возможно, сейчас меня закидают чем-нибудь, но можно же и в Arduino IDE для STM32 писать. Например, здесь и тут пишут:
Программная поддержка STM32 в Arduino IDE называется STM32duino. Она реализована в виде пакета поддержки и загрузчика, прошиваемого в плату. В среду она добавляется как обычно: сначала указывается ссылка в настройках, потом устанавливается пакет из Менеджера плат.
Для новичка этого недостаточно будет?

artyomsoft Автор
29.09.2026 14:38Для новичка лучше, наверное, Raspberry Pi Pico и RP2040 или ESP32, а не STM32

voldemar_d
29.09.2026 14:38С этим я не спорю. Я имею ввиду "для новичка, желающего начать работать именно с STM32".

artyomsoft Автор
29.09.2026 14:38Ну если быстро получить результат и мотивацию для дальнейшего изучения, то, наверное, да.

RigelGL
29.09.2026 14:38STM после Ардуино ощущается как глоток свежего воздуха, всё под контролем, вся периферия настраивается, программа для настройки периферии (CubeMX) есть.
Что может предложить Ардуино? Недо pinMode и тормозной digitalWrite. А как ставится высокомное состояние в Ардуино? pinMode(INPUT), digitalWrite(HIGH) - что за бред? В то время как в stm режимов GPIO больше 3 и вместо хака с pinMode, digitalWrite в коде будет указан конкретный тип из enum.

Qwest_Prozto
29.09.2026 14:38Справедливости ради вы сравниваете фреймворк ардуины и HAL STM, хотя то и то может работать без этой шушеры на самописных фреймворках. Хотя их наличие у новичка не совсем реалистично.

RigelGL
29.09.2026 14:38Справедливости ради вы сравниваете фреймворк ардуины и HAL STM,
Новичок на STM скорее всего будет использовать HAL, получив полный контроль над периферией.
хотя то и то может работать без этой шушеры на самописных фреймворках. Хотя их наличие у новичка не совсем реалистично.
Согласен, писать в регистры не похоже на Arduino-way с шильдиками и готовыми библиотеками.
В то время как HAL генерируется в проекте, позволяя посмотреть реализацию, Ардуино предлагает максимально упрощённую среду разработки.

voldemar_d
29.09.2026 14:38Тормозной digitalWrite можно заменить на прямую запись в регистры, тогда побыстрее будет. Другое дело, что у многих Arduino тактовая частота МК низкая, и они просто медленные сами по себе.
А как ставится высокомное состояние в Ардуино? pinMode(INPUT), digitalWrite(HIGH) - что за бред?
вместо хака с pinMode, digitalWrite в коде будет указан конкретный тип из enum
Согласен, что лучше явное включение режима, но это, ИМХО, не такая уж страшная проблема, как малое количество памяти, низкая тактовая частота и др. ИМХО, на всё имеет смысл смотреть с точки зрения решаемых задач и баланса между возможностями и сложностью их использования.

RigelGL
29.09.2026 14:38Тормозной digitalWrite можно заменить на прямую запись в регистры, тогда побыстрее будет.
Теоретически в ~110 раз, если писать PORTA = 0b...;
Другое дело, что у многих Arduino тактовая частота МК низкая, и они просто медленные сами по себе.
но это, ИМХО, не такая уж страшная проблема, как малое количество памяти, низкая тактовая частота и др.
Попытка притянуть STM под Ардуино выглядит как добровольный отказ от большинства аппаратных фич STM и топтание на месте.
ИМХО, на всё имеет смысл смотреть с точки зрения решаемых задач и баланса между возможностями и сложностью их использования.
Ардуино решает задачу привлечения новичков в embedded (и решает отлично), но Ардуино нужно вовремя перерасти.

voldemar_d
29.09.2026 14:38Так ведь и более крутые уровни есть - разработка на FPGA, например, вплоть до плат PCIx. А вот "нужно" или нет - ИМХО, каждый решает сам.

aabzel
29.09.2026 14:38Что может предложить Ардуино? Недо pinMode и тормозной digitalWrite.
Для AVR есть codeVisionAVR, который умеет генерить код по настройкам в gui.
x89377
Когда же иссякнет эта река знаний ?
dimao79
Никогда. С недавних пор в эту реку начали вливаться множество новых притоков.
"Напиши статью, где будет сравнение Хелловорлда для STM и RPi, включи в нее обзор сред разработки, отладчиков, программаторов, включи побольше максимально простых и детальных примеров."
zambezi9
Если бы редактор разрешал схлопывать фрагменты, то почему нет. Я вот спросил элэлэмку для похожей платы: “in VS Code PlatformIO Arduino framework what would be typical “Hello World” code for WeAct STM32H750VBT6 board with small built-in OLED-display 0.96?”
Ответила всего двумя файлами platformio.ini и main.cpp. Карл, два небольших “кода” и эта неслабая плата уже что-то делает. Я взял ее (с дисплеем) всего за 1200р недавно на одном из маркетов. 480 MHz. Автор не очень удачно спросил и его элэлэмка нагрузила чуть ли не “bare-metal” подходом, когда то же можно проще сделать и в Ардуино фрэймворке.
RigelGL
STM используют чтобы уйти от тормозов Ардуино и получить бо́льший контроль над мк.
CrashLogger
Только это была бы статья про Arduino, а не про STM32. Приведенный выше код main.cpp не содержит ничего специфичного для STM32 и будет выглядеть так же для любой платы, которую поддерживает Arduino IDE.
aabzel
@artyomsoft
Добавьте, пожалуйста, в источники мои тексты на эту же тему.
Настройка ToolChain(а) для Win10+GCC+С+Makefile+ARM Cortex-Mx+GDB https://habr.com/ru/articles/673522/
Сборка прошивки STM32 компилятором IAR при помощи GNU Make скрипта (IAR+Make=CI/CD) https://habr.com/ru/articles/1010484/
STM32 + GCC + CMake + Win10
https://habr.com/ru/articles/1019118/
CLI через Segger J-Link RTT на ARM Cortex-M (или однопортовая лапароскопия) https://habr.com/ru/articles/1018168/
SoftSerial: Программный UART на STM32
https://habr.com/ru/articles/973392/
Почему Нам Нужен UART-Shell? (или Добавьте в Прошивку Гласность) https://habr.com/ru/articles/694408/
LinkToOS
Статей с руководствами для новичков может быть неограниченное количество, разных по стилю и сложности. Неизвестно кому что больше понравится, и будет более понятным.
dlinyj
И чем плоха эта река? Я вот никогда дел не имел с STM32, и начал вкатываться в неё. При этом портировал ядра, писал драйвера, работал с AVR и lpc2103. Но STM32 просто какая-то адовая наркомания и нормального гайда, так чтобы он был актуален и по шагам не нашёл. Очень сложно и запутанно. Я понимаю, что разный HAL, что там разве что щи не варит и невозможно всё объять.
Мне чтобы помигать светодиодом пришлось пару вечеров ставить STM32CubeMX, затем разбираться как генерировать проект. Непонятно зачем нужно для STM32 отдельное IDE, если даже блокнот прекрасно справляется. Потом разбирался как ставить компилятор, как генерировать Makefile, как шить под линукс.
Вроде всё просто и понятно (когда знаешь примерно что должно быть), но вкатиться в это сходу очень сложно.
Qwest_Prozto
Есть проблема у STM, что официальные способы собирать прошивку в целом не особо адекватны, и все пытаются делать так как им удобнее.
CubeMX страшная фигулина с кривой автогенерацией кода и прекрасным предложением писать код в секциях.
HAL еще большая катастрофа с ООП без ООП т.е. буквально код на C, который пытается выглядеть как C++
При этом все эти минусы важны только для уже сформировавшихся разрабов, для новичка вполне сносные инструменты
NutsUnderline
зато удобно сделать набросок мышкой и прикинуть как оно вообще работает, посмотреть куда какие байты надо совать, опять же карта клоков наглядная ... а уж потом - хоть табличку [105000]{адрес,значение}
Qwest_Prozto
Ну CubeMX у меня установлен и иногда пригождается как раз узнать делители на частоту и номера доступных таймеров
aabzel
Да. Именно так.
RTFM13
del
aabzel
Добавьте в ссылки аналогичные тексты других авторов,
которые уже освещали эту тему.
@andreyzaostrovnykh
STM32. Процесс компиляции и сборки прошивки https://habr.com/ru/companies/timeweb/articles/793152/
@andreyzaostrovnykh STM32. Подготавливаем среду разработки в Linux https://habr.com/ru/companies/timeweb/articles/787328/
@romanshuvalov ARM-микроконтроллеры STM32F. Быстрый старт c STM32-Discovery https://habr.com/ru/articles/128734/?ysclid=muoitpw2i874730498
@Butaforsky STM32 Часть 1. Как поморгать светодиодиком https://habr.com/ru/articles/694184/
@DimKa_exe Жизнь без CubeMX: Первая прошивка для STM32, имея под рукой только блокнот https://habr.com/ru/articles/1022976/