Итак, компилятор установлен, пришло время создания первого проекта. Сразу думаю надо обсудить библиотеки, которые мы будем использовать в нашей работе с STM32.
Во-первых, CMSIS. Это замечательная библиотека, единый стандарт для всех Cortex. CMSIS позволяет легко переносить код с одного контроллера с ядром ARM Cortex на любой другой. Короче, в CMSIS стандартизирован доступ к разной периферии разных микроконтроллеров STM. Библиотека состоит из нескольких файлов, которые нам надо будет добавить в проект, но об этом немного позднее.
Время традиционной вставки: поскольку компания STMicroelectronics прекратила поддержку библиотеки SPL, которая использовалась в этом курсе, я создал новый, посвященный работе уже с новыми инструментами, так что буду рад видеть вас там - STM32CubeMx. Кроме того, вот глобальная рубрика по STM32, а также статья на смежную тему из нового курса: STM32. Быстрый старт с STM32CubeMx.
Во-вторых, библиотека Standard Peripheral Library. В SPL очень удобно реализована настройка всевозможных периферийных модулей, а также есть множество функций для работы с ними же. Эту библиотеку достаточно подробно будем изучать при обсуждении какой-либо конкретной периферии в будущих статьях. А сейчас кратенько рассмотрим ее структуру в общих чертах. Для любого модуля микроконтроллера есть 2 файла: заголовочный файл и, собственно, файл с исходным кодом. Так что, создавая проект для работы, например, с АЦП, мы будем включать в проект два файла из Standard Peripheral Library.
Возможно, кто-то сомневается, стоит ли использовать эту библиотеку. Речь, конечно о SPL (по поводу CMSIS думаю ни у кого нет особых сомнений). Так вот, я для себя однозначно решил, что стоит. Потому что ни к чему изобретать велосипед, библиотека написана и очень удобна, гораздо удобнее, чем напрямую ковыряться в многочисленных регистрах. НО! При всем этом, надо все-таки иметь представление какой регистр за что отвечает, и как с ними работать. Для этого не лишним будет просматривать раздел даташита на конкретную периферию при работе с ней.
Итак, скачиваем CMSIS и Standard Peripheral Library (SPL) и шагаем дальше:
- скачать CMSIS - STM32_CMSIS
- скачать Standard Peripheral Library - STM32_SPL
Теперь, наконец-то, переходим к нашему первому проекту. Создадим отдельную папку для проектов, и в ней будем создавать по папке для каждого отдельно взятого проекта. Если этого не делать, то в итоге получится просто каша из файлов. А если проект большой, то есть включает большое количество файлов, то лучше сгруппировать файлы в группы и разложить по разным подпапкам. Итак, запускаем Keil!
Идем в Project -> New uVision Project. Появляется окошко для выбора папки, в которой будет создан проект. Также надо дать нашему проекту имя. Пусть будет, например, test, это будет просто тестовый проект. Скриншот приводить не буду, тут все и так понятно. Теперь нам надо выбрать микроконтроллер. Я остановил свой выбор на STM32F103CB:
Жмем OK, появляется диалоговое окно, жмем "Да", и вот первый шаг позади.
В левой части видим окошко Project. Там будут отображаться все файлы, добавленные в наш проект. Я обычно переименовываю группы, которые по умолчанию называются Target 1 и Source Group 1 в STM32 и StartUp соответственно. Сразу же добавим еще пару групп – для библиотек, а также для наших файлов, в которых будет собственно сам код. У меня после модификации все выглядит вот так:
Конечно, такой вариант не является единственно верным, просто так удобнее, а пока проект содержит немного файлов, пары папок вполне хватит. Идем дальше. Создадим пустой файл .c: File - New .
Появляется пустой файл, жмем File - Save As и называем наш первый файл test.c. Готово! Теперь нужно добавить все необходимые файлы в проект. Дважды тыкаем на папку CMSIS в дереве проекта и добавляем следующие файлы:
- core_cm3.c
- system_stm32f10x.c
И вот они, первые грабли, с которыми я столкнулся. Проект отказался собираться без файла stm32f10x_conf.h. А в моей скачанной CMSIS он напрочь отсутствовал. Поэтому качаем его отдельно и тоже добавляем в проект (если качали библиотеки по ссылкам выше, то там уже есть этот файл). Далее открываем этот файл, находим строчку #include "stm32f10x_type.h" и комментируем ее. Этот файл мы использовать не будем. Такие действия лично мне пришлось осуществить, чтобы успокоить компилятор, возможно, у меня просто оказалась битая библиотека. Мне было проще поправить имеющуюся под себя, чем искать какие то другие варианты 🙂
Теперь аналогично добавим файлы библиотеки SPL. Пока они нам не понадобятся, но пусть будут. Добавим, например stm32f10x_rcc.c и подхватим includ’ом stm32f10x_rcc.h (файлы, содержащие все связанное с тактированием различной периферии). И наконец добавим наш созданный файл test.c в папку Source Files в дереве проекта.
Далее идем в Project - Options for target… Тут несколько вкладок для различных настроек. Идем во вкладку Output и ставим галку Create HEX File. Теперь наша цель – вкладка C/C++. В поле define пишем следующее: USE_STDPERIPH_DRIVER. Без этого проект не соберется. Осталось в Include Paths добавить пути ко всем(!) файлам, включенным в проект. Получим примерно следующее:
И вот тут еще одни грабли. Все папки, которые добавляем в Include Paths не должны содержать пробелов. Так что мои Header Files, Source Files и Project Files плавно превращаются в Header_Files, Source_Files и Project_Files.
Еще один шаг к созданию проекта сделан, в принципе, осталось совсем чуть-чуть. В файл test.c закинем следующий тестовый код, который абсолютно ничего не делает:
#include "stm32f10x.h" #include "stm32f10x_rcc.h" int main() { while(1); }
Осталось лишь нажать F7 (build) и проект соберется. Все отлично, но мы наблюдаем непредвиденные warning’и. Хорошо написанная программа не должна их содержать, так что будем править. К счастью, это потребует от нас минимум усилий. Итак:
incompatible redefinition of macro "HSE_Value"
Чтобы это не вылетало, открываем stm32f10x_conf.h, ищем:
#define HSE_Value ((u32)8000000) /* Value of the External oscillator in Hz*/
И беспощадно комментируем эту строку. Вот и все... Если у кого-то вылезло:
warning: #1-D: last line of file ends without a newline
то надо сделать так, чтобы файл test.c не заканчивался строкой кода. Проще говоря, ставим курсор после последней скобки в этом файле и жмем Enter. Warning сразу же пропадает.
Ну вот, первые шаги сделаны. Мы создали пустой проект, который абсолютно ничего не делает полезного (бесполезного впрочем тоже 🙂 ). Но для начала уже неплохо, в следующих статьях будем заполнять проект кодом. Кстати, если у кого-нибудь возникли какие-либо трудности при создании проекта, пишите в комментарии, не стесняйтесь! И не пропустите статью нашего курса по STM32CubeMx, описывающую аналогичный процесс создания базового проекта.