0ж. Первый вечер: что купить, как поставить среду и помигать светодиодом — пошагово для того, кто ни разу не прошивал
Раздел 0е научил читать числа вроде 0x40021018. Этот раздел — про руки.
Здесь нет теории, только один вечер и одна цель: светодиод на плате мигает
по программе, которую вы сами собрали и сами записали в плату.
Записать программу в плату называют «прошить», а саму программу — «прошивкой». Паяльник не нужен, опыт тоже. Нужны плата, маленький переходник для прошивки и четыре провода. После этого вечера маршрут новичка (0а) читается уже с платой на столе, а не в уме.
Всё, что сказано про проект, проверено: проект создан той же программой STM32CubeMX 6.18.1, которой будете пользоваться вы, собран теми же ключами, что ставит STM32CubeIDE, и запущен в эмуляторе — программе, которая притворяется микроконтроллером. Живой платы в опытах не было.
Опоры: 0.2 — что купить на старт; 2а — подделки; 4б — что внутри STM32CubeIDE; 8.4 — та же мигалка, но без библиотеки, на регистрах.
Как это называется в документации
Оригинал Перевод firmware прошивка: готовая программа для микроконтроллера debug probe, ST-Link программатор-отладчик: переходник между компьютером и платой SWD (Serial Wire Debug), SWDIO, SWCLK отладка по двум проводам: провод данных и провод такта GPIO Output вывод общего назначения, настроенный как выход IDE, toolchain среда разработки; набор программ для сборки workspace рабочее пространство: папка с настройками среды Build, Run собрать; записать в плату и запустить breadboard, jumper макетная плата («макетка»); перемычка
0ж.1 Что купить
На этот вечер нужны только первые три строки. Остальное пригодится на следующих шагах маршрута, и его удобно купить сразу, в один заказ.
| Что | Сколько | Зачем | На что смотреть |
|---|---|---|---|
| плата BluePill на STM32F103C8 | 1–2 | на ней всё; вторая — запасная | штырьки уже припаяны: иначе без паяльника не обойтись |
| программатор ST-Link V2 («свисток») | 1 | записывает прошивку в плату | годится любая версия: V2, V2.1, V3 (2.7) |
| провода «мама–мама» | 10 | четыре — от ST-Link к плате | на концах гнёзда: у ST-Link и у платы торчат штырьки |
| макетная плата | 1 | собирать схемы без пайки: детали втыкаются в дырочки | — |
| светодиоды | 5–10 | первые свои схемы | — |
| резисторы 220 Ом | 10 | ставятся в одну цепочку со светодиодом и ограничивают ток | — |
| кнопки | 2–3 | первая кнопка в программе (8.5) | — |
Почему 220 Ом. Красный светодиод, подключённый к выводу 3,3 В через резистор, берёт ток, который зависит от резистора. Расчёт — в 49.3: на выводе теряется около 0,4 В, на светодиоде 2,0 В, на резистор остаётся 0,9 В. С резистором 220 Ом ток выходит 4,09 мА: светодиод светит хорошо, а вывод не перегружен. С 110 Ом — 8,18 мА, с 1 кОм — 0,90 мА: горит тускло, но горит. Сколько выдерживает вывод — в 49.7.
BluePill или BlackPill. BlackPill — плата того же размера на другом
камне, STM32F411 или STM32F401 (2ж). Светодиод у неё тоже на выводе
PC13 и тоже горит при нуле (2ж.1), а прошить её можно и без ST-Link,
по кабелю USB (2ж.4). Но весь этот раздел написан для BluePill: если
купили BlackPill, в 0ж.4 выбирайте её камень, остальное то же.
Как не нарваться на подделку. Дешёвая BluePill может нести не STM32,
а похожий камень другого производителя или перемаркированный. Для мигалки
это почти никогда не важно. Если же программа для прошивки ругается на
«не тот» камень или плата ведёт себя странно — откройте раздел
2а «Клоны и подделки STM32: как отличить». В нём три случая —
оригинал, честный клон под своей маркой и подделка — и как их различить
программой, отладчиком и глазами. Например, отладчик у настоящего F103
читает код 0x1BA01477, а у клона CS32F103 — 0x2BA01477 (2а.6).
0ж.2 Среда: две программы и драйвер
Среда разработки — это набор программ, в котором пишут, собирают и прошивают. Собрать — значит перевести текст программы на языке C в команды, которые понимает процессор. Делает это компилятор: он внутри среды, отдельно его ставить не надо.
Ставим две программы ST, обе бесплатные:
- STM32CubeMX — настраивает выводы мышкой и создаёт проект;
- STM32CubeIDE — среда: редактор, компилятор и прошивка в одном окне.
Раньше вторая включала в себя первую. С версии 2.0 это две отдельные программы (4б), поэтому и ставим две.
По шагам:
- На сайте st.com найти страницы STM32CubeMX и STM32CubeIDE и скачать установщики для своей системы. Обе работают на Windows, Linux и macOS.
- Поставить обе программы, соглашаясь со всем, что предложено по умолчанию.
- Драйвер ST-Link (только Windows). Драйвер — маленькая программа,
которая учит Windows разговаривать с устройством. Для ST-Link это
пакет STSW-LINK009. Если установщик CubeIDE предложит поставить
драйверы ST-Link — соглашайтесь. Если нет — пакет скачивается с сайта
ST отдельно под этим именем; он же входит в программу
STM32CubeProgrammer (папка
Drivers\stsw-link009_v3). В его инструкции сказано главное: ставить от имени администратора до того, как ST-Link вставлен в компьютер. - Первый запуск CubeIDE спросит, где держать рабочее пространство (workspace). Это папка с настройками самой среды (4б.1); соглашайтесь с предложенной.
- Первый проект в CubeMX потребует пакет библиотек для серии F1 — STM32Cube FW_F1. Программа предложит скачать его сама; нужен интернет. В этом разделе проект создан с пакетом V1.8.7.
0ж.3 Провода: ST-Link к плате
Программатор говорит с камнем по двум проводам — это и есть SWD. Ещё два провода нужны для питания и для земли. Итого четыре.
| Провод | На ST-Link | На плате | Зачем |
|---|---|---|---|
| 1 | 3,3 В | 3,3 В | питание платы от ST-Link |
| 2 | SWDIO | SWDIO, вывод PA13 |
данные отладки |
| 3 | SWCLK | SWCLK, вывод PA14 |
такт отладки: «тик-так», по которому читают данные |
| 4 | GND | GND | общая земля |
Четыре правила, и всё заработает:
- Соединяйте по надписям, а не по месту. У разных ST-Link штырьки стоят в разном порядке; на корпусе напечатано, какой из них что. Подписи сокращают: SWDIO пишут как DIO или IO, SWCLK — как CLK.
- Земля обязательна. Напряжение — это всегда разница между двумя точками. Без общей земли сигналам платы и ST-Link не с чем сравниться.
- Один источник питания. Плата питается по проводу 3,3 В от ST-Link; кабель USB к самой плате сегодня не нужен.
- Перемычки BOOT0 и BOOT1 — обе на 0. Это два маленьких колпачка
рядом с кнопкой сброса. При
BOOT0= 0 камень после включения запускает вашу программу из Flash — памяти, которая не стирается при выключении. ПриBOOT0= 1 он запускает заводской загрузчик, а не её (4.9). Пригодится в 0ж.7.
Соединяйте, пока ST-Link вынут из компьютера, и только потом вставляйте его в порт USB.
0ж.4 Первый проект: настроить вывод в CubeMX
Микроконтроллер — маленький компьютер в одном корпусе. Его ножки
называются выводами. Вывод можно сделать входом (читать кнопку) или
выходом (зажигать светодиод). Светодиод BluePill подключён к выводу
PC13: порт C, вывод номер 13. Значит, PC13 надо сделать выходом.
В STM32CubeMX:
- File → New Project. Во вкладке выбора камня (MCU/MPU Selector)
набрать
STM32F103C8, выбрать в спискеSTM32F103C8Txи подтвердить. На экране появится картинка корпуса с выводами по краям. - Вывод. Щёлкнуть правой кнопкой по выводу
PC13на картинке и выбратьGPIO_Output. - Отладка. Слева, в списке блоков, открыть
SYSи в поле Debug выбратьSerial Wire. Это самый важный шаг вечера, и ниже сказано почему. - Project Manager. Имя проекта —
blink, в поле Toolchain/IDE —STM32CubeIDE. - GENERATE CODE. После генерации CubeMX предложит открыть проект;
кнопка Open Project откроет его в CubeIDE. Если ничего не открылось,
значит, файлы проекта не связаны с CubeIDE (4б.11): тогда в CubeIDE
File → Import → Existing Projects into Workspace и папка
STM32CubeIDEвнутри проекта.
Частоту не трогаем. По умолчанию камень работает от внутреннего генератора на 8 МГц: восемь миллионов тактов в секунду. Для мигалки хватает с запасом.
Почему шаг 3 так важен. Без него в поле Debug остаётся No Debug.
CubeMX понимает это буквально и пишет в проект строку, которая
выключает выводы отладки:
__HAL_AFIO_REMAP_SWJ_DISABLE();. Программа запустится, и с этой секунды
ST-Link перестанет видеть камень: следующая прошивка не пройдёт.
С Serial Wire на том же месте стоит
__HAL_AFIO_REMAP_SWJ_NOJTAG(); — отладка по SWD остаётся включённой.
Проверено так: проект создан дважды, с Serial Wire и без, и других
отличий в коде, кроме этой строки и включения порта A, нет. Как вернуть
плату, если шаг уже пропущен, — в 0ж.7.
Что CubeMX положил в папку проекта: Core/Src/main.c — главный файл,
с ним мы и будем работать; рядом ещё пять файлов настройки; в Drivers —
библиотека HAL, 11 файлов на C. HAL — библиотека ST, в которой у каждого
действия с железом есть понятное имя функции.
0ж.5 Две строки кода, сборка и прошивка
Откройте Core/Src/main.c. Программа начинается с функции main —
с неё камень начинает работу после включения. CubeMX уже написал её
начало:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
Здесь пропущены пустые строки и комментарии. Три вызова по порядку:
HAL_Init()— готовит библиотеку и запускает часы по миллисекундам;SystemClock_Config()— выбирает частоту: те самые 8 МГц;MX_GPIO_Init()— делаетPC13выходом, как вы задали мышкой. Первым делом он пишет на вывод 0, а светодиод BluePill горит именно от нуля: он включён между питанием и выводом (8.4). Так что светодиод загорается ещё до вашего кода.
Ниже — бесконечный цикл. Добавьте в него две строки — между
комментариями USER CODE BEGIN 3 и USER CODE END 3:
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);
}
/* USER CODE END 3 */
Что значит каждая строка:
while (1)— «повторять, пока условие верно». Единица верна всегда, значит — вечно. У микроконтроллера нет «выхода из программы»: он крутит цикл, пока есть питание./* USER CODE BEGIN 3 */и/* USER CODE END 3 */— заборчик. Всё, что между ними, CubeMX сохранит, если проект придётся сгенерировать заново. Всё, что вне заборчиков, он перепишет (4.7).HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);— «переключи вывод 13 порта C»: был 0 — станет 1, была 1 — станет 0.GPIOC— это адрес порта C в памяти камня,0x40011000.GPIO_PIN_13— число0x2000, в котором стоит ровно один бит, тринадцатый: так библиотека говорит, какой вывод из шестнадцати имеется в виду. Как читать такие числа — в 0е.HAL_Delay(500);— подождать 500 миллисекунд, то есть полсекунды. Внутри она считает тики — короткие прерывания от встроенного таймера SysTick. Таймер отсчитывает 8000 тактов, это ровно 1 мс при 8 МГц, и сообщает «прошла миллисекунда». Библиотека добавляет к паузе ещё один тик для надёжности, поэтому на деле пауза — 501 мс.- Точка с запятой заканчивает каждую команду, фигурные скобки собирают команды в группу. Это всё, что нужно знать о C на сегодня; остальное — в разделе 3.
Собрать. В CubeIDE: Project → Build Project. Внизу, в окне Console, появятся строки компилятора, а в конце — сколько памяти заняла прошивка:
Memory region Used Size Region Size %age Used
RAM: 1584 B 20 KB 7.73%
FLASH: 4884 B 64 KB 7.45%
FLASH — постоянная память, в ней живёт программа: 4884 байта из 64 КБ. RAM — оперативная память для переменных: 1584 байта из 20 КБ. Почти всё это — запас под стек и кучу, рабочие черновики программы: 1540 байт, которые среда держит свободными заранее; настоящих переменных — 44 байта. Если у вас цифры чуть другие — ничего страшного: они зависят от версии компилятора.
Прошить и запустить. Run → Run As → STM32 C/C++ Application, в окне
настройки — OK. Среда соберёт проект, запишет его через ST-Link
и запустит. Первое же переключение в цикле погасит светодиод,
зажжённый в MX_GPIO_Init, через полсекунды он загорится, ещё через
полсекунды погаснет — и так, пока есть питание.
Как это выглядит изнутри, видно в эмуляторе: вызовы
HAL_GPIO_TogglePin приходятся на 0, 501, 1002, 1503 и 2004-й тик.
Шаг — 501 мс; полный цикл «горит — погашен» — 1002 мс, то есть
вспышка раз в секунду.
0ж.6 Первое своё изменение: мигать быстрее
Программа — это ваш текст, и его можно менять. Первое изменение — одно число. Замените 500 на 100:
HAL_Delay(100);
Снова Run → Run As → STM32 C/C++ Application (среда сама пересоберёт проект). Теперь светодиод мигает быстрее: в эмуляторе переключения идут на 0, 101, 202, 303 и 404-м тике. Шаг — 101 мс, полный цикл — 202 мс, это 4,95 вспышки в секунду, почти пять. Прошивка стала короче на 4 байта: 4880 вместо 4884.
Попробуйте сами другие числа: с 1000 полный цикл — 2002 мс, вспышка
раз в две секунды; с 50 — часто. Каждый раз проверяйте, что новое число
стоит между USER CODE BEGIN 3 и USER CODE END 3.
Это и есть разработка встраиваемых систем в миниатюре: изменили текст, собрали, прошили, посмотрели на железо. Всё остальное в справочнике — тот же цикл, только с задачами посложнее. Та же мигалка без библиотеки HAL, прямо записью в регистры, — в 8.4: после разделов 1, 3 и 3а она будет читаться так же легко, как эти две строки.
0ж.7 Грабли
Если не прошивается, идите по пунктам по порядку: от компьютера к плате. Начинайте с первого, даже если кажется, что дело не в нём.
1. Компьютер не видит ST-Link. Нет драйвера или кабель без линий
данных (есть кабели «только для зарядки»). Программа STM32CubeProgrammer
в этом случае пишет No ST-Link detected!. Поставьте драйвер (0ж.2),
выньте и снова вставьте ST-Link, попробуйте другой порт.
2. ST-Link виден, камень — нет. Это и есть «target not found»:
среда сообщает, что не нашла камень. В STM32CubeProgrammer та же беда
пишется No STM32 target found!. Первым делом — питание: провод 3,3 В
на месте и сидит в гнезде плотно?
3. Перепутаны SWDIO и SWCLK. Самая частая пара ошибок (200.5). Сверьте провода 2 и 3 с надписями на корпусе ST-Link и на плате.
4. Нет общей земли. Провод 4 забыт или вставлен не туда. Без земли ни один сигнал не читается (95.9).
5. Первая прошивка прошла, вторая — нет. Пропущен шаг 3 в 0ж.4:
в проекте осталось No Debug, и программа выключила выводы отладки.
Плата не сломана. Переставьте перемычку BOOT0 в 1 и нажмите кнопку
сброса: камень запустит заводской загрузчик, а не вашу программу,
и выводы отладки снова свободны (4.9). Поставьте в CubeMX Serial Wire,
сгенерируйте проект, прошейте, верните BOOT0 в 0 и нажмите сброс.
6. Прошилось, но программа не работает после сброса. Перемычка
BOOT0 осталась в 1: камень каждый раз запускает загрузчик вместо
вашей программы. Верните её в 0.
7. Светодиод горит ровно и не мигает. Прошивка дошла: светодиод
зажёг MX_GPIO_Init. А двух строк в ней нет: либо файл не сохранён
и проект не пересобран, либо строки стояли вне заборчика и новая
генерация их стёрла. Проверьте main.c и соберите заново.
8. Плата отвечает, но «не тем» камнем или ведёт себя странно. Возможно, на плате клон или подделка. Это раздел 2а; на первом шаге он подскажет, как это узнать.
Если ничего не помогло — в разделе 4 есть таблица симптомов ST-Link (4.5), а в разделе 36 — общий порядок поиска неисправности.
0ж.8 Итоги
- На первый вечер нужны три покупки: плата BluePill, ST-Link и провода «мама–мама»; с резистором 220 Ом светодиод от вывода 3,3 В берёт 4,09 мА.
- Среда — две программы ST: STM32CubeMX настраивает выводы, STM32CubeIDE собирает и прошивает. На Windows ещё драйвер ST-Link, до того как вставить сам ST-Link.
- Проводов четыре: 3,3 В, SWDIO (
PA13), SWCLK (PA14), GND. ПеремычкиBOOT0иBOOT1— на 0. - В CubeMX две настройки:
PC13—GPIO_Output, SYS Debug —Serial Wire. Без второй прошивка выключит отладку строкой__HAL_AFIO_REMAP_SWJ_DISABLE();. - Своего кода — две строки:
HAL_GPIO_TogglePinиHAL_Delay(500). Прошивка — 4884 байта Flash из 64 КБ и 1584 байта ОЗУ из 20 КБ. HAL_Delay(500)ждёт 501 тик по 1 мс: светодиод мигает раз в секунду.HAL_Delay(100)— 101 тик и 4,95 вспышки в секунду.- Не прошивается — восемь пунктов 0ж.7 по порядку, от компьютера к плате.
Проверь себя
- Зачем в CubeMX в разделе SYS поле Debug ставят в
Serial Wire? - А) Без этой настройки прошивка сама выключит отладку, и ST-Link перестанет видеть камень - Б) Чтобы светодиод мигал быстрее - В) Чтобы включить консоль UART - Г) Это настройка частоты камня - Свои строки вписали в
main.cвне комментариевUSER CODE BEGINиUSER CODE END. Чем это грозит? - А) Программа не соберётся - Б) Светодиод будет мигать медленнее - В) Ничем: эти комментарии — просто украшение - Г) При новой генерации проекта CubeMX перепишет всё, что вне этих заборчиков, и строки пропадут - Перемычка
BOOT0стоит на 1. Что запустит камень после включения? - А) Вашу программу из Flash - Б) Заводской загрузчик, а не вашу программу - В) Ничего: камень не включится - Г) Вашу программу, но без отладки
Проверь себя: ответы
- 1 — А. Почему: Без Serial Wire CubeMX вставит строку __HAL_AFIO_REMAP_SWJ_DISABLE();, и следующая прошивка не пройдёт (0ж.4).
- 2 — Г. Почему: Код между USER CODE BEGIN и USER CODE END CubeMX сохраняет при перегенерации, а всё вне их переписывает (0ж.5).
- 3 — Б. Почему: При BOOT0 = 0 камень запускает программу из Flash, при BOOT0 = 1 — заводской загрузчик, поэтому на первый вечер обе перемычки ставят на 0 (0ж.3).
Что дальше. Плата мигает — пора узнать, что происходит внутри. Маршрут новичка — раздел 0а «Маршрут новичка: двадцать разделов по порядку»; его этап 1 (0а.2) — пять разделов, и каждый теперь можно примерить к своей мигалке:
- 1 «Микроконтроллер как таковой» — что такое ядро, память и порт C, куда вы только что писали;
- 3 «Язык C для встраиваемых систем» — что такое
volatileи указатель на регистр; - 3а «Битовые операции» — как устроено число
0x2000и почему в нём один бит; - 4 «Инструментарий» — что ещё бывает, кроме CubeIDE, и три способа прошить плату;
- 5 «Три уровня абстракции: CMSIS, HAL и LL» — чем
HAL_GPIO_TogglePinотличается от записи в регистр.
На девятом шаге маршрута — раздел 8 «Порты ввода-вывода (GPIO)»: там
вы снова встретите PC13, теперь уже изнутри.
Дальше: раздел 1 «Микроконтроллер как таковой» — что лежит внутри кристалла: ядро, память, периферия — и почему без этого всё дальнейшее придётся принимать на веру.