Ранее мы познакомились с несколькими отладочными платами на базе микроконтроллеров STM32 — это Blue Pill , платами серии Nucleo , и даже такой экзотикой, как Кракен . Все это здорово, но что, если нам захочется использовать микроконтроллер не в прототипе, а в полноценном готовом устройстве? Не вкорячивать же в него плату Nucleo! Поэтому сегодня мы разберемся, как работать с STM32 напрямую, то есть, прямо на макетной плате, на примере микроконтроллера STM32F103C8T6. Казалось бы, тема эта несложная, однако есть пара подводных граблей, про которые стоит знать.
Fun fact! Аналогичную инструкцию для микроконтроллеров AVR вы найдете в посте Как собрать Arduino прямо на макетной плате .
Примечание: Пользуясь случаем, я хотел бы поблагодарить пользователей форума easyelectronics.ru за то, что помогли мне разобраться с парой проблем , возникших при изучении сего вопроса. Особой благодарности заслуживают пользователи dosikus_2 и BusMaster , так как они раньше других предложили верные решения.
Итак, первая сложность заключается в том, что микроконтроллеры STM32 не бывают в DIP-корпусах, а значит понадобится переходник. STM32F103C8T6 имеет корпус LQFP-48, для которого готового переходника у меня не было. Такой переходник можно вытравить самому, можно поискать на eBay. Я прикинул, что в будущем мне понадобится больше одного переходника. А еще я могу захотеть подарить парочку из них, так как многие мои коллеги занимаются электроникой в качестве хобби. Плюс мне не хотелось долго ждать доставки. Поэтому я спроектировал собственный переходник в KiCad и заказал десяток плат на Резоните . Также для вашего удобства я залил плату на OSH Park . Следует однако учесть, что в пересчете на одну плату цены у OSH Park существенно выше, чем у Резонита, и доставка обычно занимает несколько недель против трех дней.
Допустим, переходник у нас уже есть. Далее открываем даташит [PDF] и смотрим распиновку микроконтроллера (стр 16):
Наиболее интересные нам сейчас пины я выделил цветом. Подключаем их таким образом:
- Пины VSS* (8, 23, 35 и 47) идут к земле;
- Пины VDD* (9, 24, 36 и 48) — к 3.3 В;
- NRST (7) оставляем висеть неподключенным, но готовим перемычку для подключения его к земле в случае необходимости. Если места на макетке хватает, вместо перемычки можно использовать кнопку с конденсатором для защиты от дребезга. При этом подтягивающий резистор к плюсу не требуется, так как такой резистор уже есть в самом микроконтроллере;
- BOOT0 (44) определяет, откуда микроконтроллер будет загружать прошивку. Нам нужно, чтобы он делал это из flash-памяти, поэтому подключаем к земле. При этом напряжение на пине BOOT1 (20) не имеет значения, и этот пин может использоваться для обычного GPIO;
- SWIO и SWCLK (34 и 37) — к соответствующим пинам программатора;
- Наконец, пин PC13 (2) у нас будет мигать светодиодом;
Важно! Между каждой парой соседних пинов VSS и VDD втыкаем по конденсатору на 100 нФ, и желательно — как можно ближе к пинам микроконтроллера. Без этого микроконтроллер в лучшем случае не будет прошиваться (я проверял). Некоторые же источники утверждают, что без конденсаторов его можно даже сжечь в момент подачи питания.
В итоге должно получиться примерно следующее:
Теперь можно приступать и к генерации проекта в STM32CubeMX. Только обязательно проверьте, чтобы SWD был включен:
Если забыть включить SWD и прошить микроконтроллер, прошить его во второй раз будет затруднительно. У меня по умолчанию SWD был выключен. В интернете пишут, что это считается багом в STM32CubeMX, который что-то никак не починят. При этом проявляется баг только для микроконтроллеров определенных серий.
Спрашивается, а что делать, если мы случайно прошили микроконтроллер прошивкой, которая отключает SWD? В этой ситуации выполняем следующие шаги. (1) Пин NRST подключаем к земле, или, если вместо перемычки вы использовали кнопку, нажимаем и держим кнопку. (2) Говорим st-info --probe
. Должны увидеть что-то вроде:
serial: 543f73066775545512251267
openocd: «x54x3fx73x06x67x75x54x55x12x25x12x67»
flash: 0 (pagesize: 1024)
sram: 20480
chipid: 0x0410
descr: F1 Medium-density device
Заметьте, что программатор видит 0 байт flash-памяти. На этом шаге это нормально. (3) Выдергиваем перемычку между NRST и землей, или отпускаем кнопку. Несмотря на то, что ранее в микроконтроллер была залита какая-то прошивка, сейчас она не будет запущена. Если же повторить команду st-info --probe
, окажется, что программатор видит всю flash-память:
После этого можно спокойно говорить make erase
или make flash
, а значит и включить SWD, как это было описано выше.
Фактически, мы получили собственную минимальную отладочную плату, собранную на макетке. За исключением описанных выше моментов, работа с ней ничем не отличается от работы с той же Blue Pill. Правим код, компилируем, прошиваем, при необходимости повторяем — все работает, как часы. Цель достигнута!
Эта заметка, разумеется, не претендует на то, чтобы полностью заменить собой даташит. В частности, за кадром осталось подключение внешних кварцевых резонаторов (LSE и HSE) и другие вопросы. Но в них, думаю, вы без труда разберетесь и самостоятельно.
Исходники к этому посту я выложил на GitHub . В репозитории вы найдете как простенькую прошивку для микроконтроллера, так и KiCad-проект адаптера для LQFP-48 вместе с готовыми Gerber-файлами.
Как обычно, если у вас есть вопросы, дополнения, возражения, и так далее — не стесняйтесь оставлять комментарии!
Дополнение: Как и зачем я делал очередную отладочную плату