STM32F407(STM32F4-DISCOVERY) - Нестандартный подход - Базовый проект.

С этой статьи я начинаю приводить практические примеры. И первый из них будет - создание базового проекта. Для чего я это делаю? Ответ прост: чтобы упростить сборку нужной мне программы. Структура этого проекта рассчитана на полную автономность по отношению к другим заголовочным файлам и библиотекам, поэтому он достаточно переносим.

Также следует заметить, что в том решении которое я выбрал, есть два больших плюса:

  1. Проект расширяем, т.е. вы можете легко добавить в него как простой код, так и целые библиотеки.
  2. Изменением минимального количества файлов можно изменять модель МК (чуть позднее я проработаю этот момент получше, чтобы можно было менять семейства МК).
Рассмотрим поподробнее этот проект, а также некоторые технические моменты.

Makefile

Для управления сборкой, очисткой и загрузкой проекта используется система make . Перейдя по ссылке можно узнать как она работает, я же сконцентрирую внимание на некоторых особенностях моей версии системы сборки:

    # Project root path

    ROOTDIR = $(realpath . ) - данная опция указывает что считать корнем проекта, очень удобно дабы не плодить в каждом звене иерархии проекта тучу относительных путей. Применяется для включения заголовочных файлов и указания путей библиотек.
  1. # Include common config

    include lib/make/Makefile.common - включает общий конфигурационный файл проекта (ниже я опишу его устройство чуть подробнее). Позволяет быстро добавлять глобальные флаги и пути.
  2. # Making libs

    lib :

    $(MAKE ) -C lib ROOTDIR = $(ROOTDIR ) - при сборке библиотек я передаю путь корня проекта во все нижележащие Makefile.
  3. # Rules for write firmware to mcu

    write : firmware.bin

    qstlink2 -cewV ./firmware.bin - для записи я использую приложение QSTLink о котором рассказывал в .
Остальные конструкции кода этого Makefile вполне стандартны. Поэтому я не буду их описывать, однако в комментариях готов ответить на любые вопросы связанные с этим, равно как и с другими интересующими вас особенностями.

stm32f4xxxg_flash.lg

Скрипт построения бинарного образа программы с экспортом абсолютных адресов регионов для инициализации. Скопирован из стандартного скрипта сборки, с добавлением некоторых опций, а также изменений активных областей.

Общие заголовочные файлы проекта. Собственно помимо заголовочного файла для каждого файла исходного кода в src, есть директории в которых находятся специфичные для проекта определения. Вот краткое описание содержимого этой директорииx:

  1. all :

    $(MAKE ) -C std_periph - для сборки библиотеки
  2. clean :

    $(MAKE ) clean -C std_periph - для её очистки
Т.е по сути в этом файле на каждую новую библиотеку заводится всего 2 строчки кода, что упрощает добавление новых библиотек в проект.

Также, в этой директории присутствует std_periph/ - библиотека стандартной периферии, о которой я расскажу в следующей статье.

  • reset_handler.c - обработчик вектора сброса, помимо вызова функции work() - /* call working code */ work (); , выполняет роль инициализатора переменных проекта, как описанных так и определённых: uint32_t * src; uint32_t * dest; src = &__text_end; dest = &__data_start; if (src != dest) while (dest < &__data_end) *(dest++) = *(src++); dest = &__bss_start; while (dest < &__bss_end) *(dest++) = 0;
  • reset_handler (void ) __attribute__ ((weak , alias ("default_handler" )));
  • work.c - рабочий код проекта, он же основной цикл. В настоящее время тут только бесконечный цикл: /* main work function */ void work(void) { /* infinity loop */ while (1); }
На этом, я заканчиваю описание основных опций базового проекта, в последующих статьях я подробно опишу каждую его часть.

Вместо предисловия

Здравствуйте! Сегодня я начал публикацию цикла статей по программированию STM32F4. Курс будет выглядеть как обучающие видеоуроки с кратким описанием и исходными кодами уроков .

Предисловие

Примерно с весны 2015 года, после долгих внутренних противоречий души, я решил начать программировать STM32F4. Почему сразу STM32F4? Данная линейка является если не флагманом МК семейства STM32, то однозначно ярким, серьезным и не дорогим решением. Паябельный корпус даже в домашних условиях и наличие огромного количества возможностей, как со стороны переферии так и АЛУ. STM32F4 - это Cortex-M4, который является прямым наследником Cortex-M3(STM32- L1, F1, F2) и отличается от него главным образом ядром с наличием DSP (цифрового сигнального процессора) и FPU (модуля операций с плавающей запятой).

Чем это курс интересен?

В рунете много различных курсов по программированию STM32. Заказчиком моды на эту тему может служить сообщество EasyElectronics.ru . Очень много полезной инфы можно оттуда подчерпнуть. Форум данного ресурса тоже весьма полезен. Сам очень много интересного узнал именно с данного ресурса. Данный курс будет интересен тем, кто как и я начинает изучать программирование STM32F4 не с нуля, а с базы 8-ми битных МК. Буду описывать своими мысли и наработки по изучению STM32F4 и его программирования.

Чем будем пользоваться?

В этой статье описан "STM32CubeMX — продвинутый генератор проектов для STM32". Именно им и будем пользоваться. HAL от ST - это библиотека. Очень схожа с SPL. Поэтому примеры написанные на SPL легко портируются на HAL. Хотя есть и приличные различия в самих функциях. STM32Cube позволяет генерировать готовый проект с функциями инициализации выбранной переферии для некоторых комерческих и не только IDE. Это IAR, Keil, TrueStudio, System Workbench for STM32 (SW4STM32). Проекты для IAR, Keil генерируюся под ключ, а вот с SW4STM32 не все так ровно. Но не стоит отчаиваться. Для себя я выбрал System Workbench for STM32 (SW4STM32). И все уроки будут построены на этой IDE.

Практика. Начало. Установка STM32CubeMX.

Идем на офф. сайт ST, на страницу STM32CubeMX STM32Cube initialization code generator (UM1718) и скачиваем софт STM32CubeMX. Установка не вызывает проблем. После установки необходимо установить необхоимые библиотеки под разные типы ядер. Это делается во вкладке Help - > Install New Libraries ставим галочку на необходимом пункте Firmware Packege For Family STM32F4 и нажимаем кнопку Install Now. После процесса скачивания и распаковывания, STM32CubeMX готов к работе.

Практика. Продолжение. Установка System Workbench for STM32 (SW4STM32).

Тут тоже ничего сверестественного. Идем на сайт , регистрируемся, скачиваем дистрибутив. Устанавливаем. Все достаточно банально. У меня данный дистрибутв: Latest Windows 7 32 bit installer (Version v1.3, updated on Friday, July 24, 2015 at 12:52:28 CEST), чем он отличается от версии 64 bit мне не известно. Но они должны быть не критическими. У меня данная версия встала как на XP SP3, так и на 8.1

Практика. Окончание. Импорт проекта куба в SW4STM32.

На ютьюбе есть познавательный ролик по импорту проекта. Правильной дорогой пойдем и мы. Видеоурок к посту смотри ниже:

Уроки по программированию STM32F4. Урок № 0. Вводный. Описание. Установка IDE. ВИДЕО.

З.Ы. коментарии, вопросы и предложения складываем

Кто-то любит пирожки, а кто-то - нет.

И так, есть отладочка stm32f429итд. Демки погоняли, посмотрели, что картиночки бегают, кнопочки на экране нажимаются, мимими. Это клёво, но начнём с пустого проекта.

Проект, в целом, создаётся точно так же, как и для .

Но если в кейле нет поддержки этого контроллера вовсе (не обновлён), то всё становится несколько хитрее =)
Во-первых, скачаем архив с библиотеками и примерами программ под плату - там есть что повыдирать.

И в первую очередь, выдерем stm32f4xx.h из CMSIS. В кейле, если он не поставлен с нуля, последний, этот файл дюже древний. Для начала, конечно, хватит и его, но с экраном уже ничего сделать не выйдет, периферия такая только появилась.
Берём файл в папке STM32F429I-Discovery_FW_V1.0.0\Libraries\CMSIS\Device\ST\STM32F4xx\Include и передислоцируем его в аналогичную папку кейла Keil\ARM\INC\ST\STM32F4xx . У меня новый файл на 100 кб оказался больше.

Стартапы для новых серий 4хх можно найти в папке STM32F429I-Discovery_FW_V1.0.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm . Их там много разных:
startup_stm32f4xx.s
startup_stm32f40_41xxx.s
startup_stm32f40xx.s
startup_stm32f401xx.s
startup_stm32f427_437xx.s
startup_stm32f427x.s
startup_stm32f429_439xx.s

Естественно, что нам нужен последний. Там же, на папку выше можно взять обновлённый system_stm32f4xx.c . Но не верьте ему, он настроен на частоту кварца 25 МГц. Лучше сделайте своё через генератор (если найдёте, я не нашёл) или стянуть из папки STM32F429I-Discovery_FW_V1.0.0\Projects\Demonstration\Core\Devices\STM32F4xx .

Неплохо было бы добавить файл описания регистров для System Viewer.
Сначала скачиваем svd файлы с сайта arm файл STM32F429x.svd: CMSIS (вкладка CMSIS-SVD, требуется регистрация). Выбираем там нужную серию, ставим галку и жмём Download.
Потом файл нужно сконвертировать в понятный кейлу вид с помощью утилиты SVDConv.exe, которая есть в папке STM32F429I-Discovery_FW_V1.0.0\Libraries\CMSIS\SVD . Но перед выполнением команды надо скопировать компилятор кейловский SfrCC2.Exe из папки Keil\UV4 в папку, где происходит конвертирование. И в итоге:
SVDConv STM32F429x.svd --generate=sfr

Получим файл STM32F429x.SFR .

Отлично. Создадим проект на базе какого-нибудь близкого по духу контроллера, а потом поправим его параметры под нужные нам. Сделаем пустой проект как для stm32f4discovery, но без startup-файла (всё равно другой нужен).
1. Project -> New project.
Выбираем папку и называем проект. Сохраняем.
2. Предлагают выбрать микроконтроллер. Окай.
В папочке ST ищем какой-нмбудь STM32F4xx и выбираем (или базовый Cortex-M4). Если его нету - обновите Кейл, так как без поддержки ядра CM4 ловить особо нечего. Я выбрал stm32f407vg.
3. Предлагают скопировать в проект startup - нафиг, он не совсем подходит.

Можем назначить папочки, куда класть объектники (Options->Output->Select Folder for Objects) и листинги (Options->Listing->Select Folder for Listings).
Изменим пределы памяти (см. раздел Memory Mapping в даташите). ROM размером 0x200000 (2 Мб), быстрая RAM1 по адресу 0x10000000 размером 0x10000, обычная RAM2 по адресу 0x20000000 размером 0x30000 (их там три разных, но какая пока разница). Карту памяти взяли в в разделе 5 «Memory mapping».

На вкладке Debug выберем ST-Link Debugger (в его свойствах выбираем протокол SW). На вкладке Utilities также выбираем ST-Link Debugger и жамкаем Settings. Там добавляем алгоритм прошивки: Add -> STM32F4xx 1Mb Flash (если есть 2Mb, то супер). Для начала сойдёт, потом, видимо, придётся или обновить кейл, или стащить алгоритм для флеша побольше.

И добавим дефайн для выбора контроллера (библиотекам нужен, видимо) на вкладке C/C++: STM32F429_439xx .

Сохраняем проект и пока закроем его. Откроем проект (.uvproj) в текстовом редакторе и поправим всё остальное:
Device : STM32F429ZI;
Cpu : IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x81FFFFF) CLOCK(8000000) CPUTYPE("Cortex-M4") FPU2
StartupFile : "Startup\ST\STM32F4xx\startup_stm32f429_439xx.s" ("STM32F429 Startup Code")
SFDFile : SFD\ST\STM32F4xx\STM32F429x.sfr
OCR_RVCT4.Size : 0x200000

Можем, в общем-то, открывать проект и добавлять файлы:
startup_stm32f429_439xx.s
system_stm32f4xx.c
main.c

Всё, компилируем и получаем пустой собирающийся проект, с которого можно начать путь постижения премудростей новых контроллеров ст.


Статья, по большому счету, написана как напоминалка что нужно сделать чтобы создать чистый компилируемый проект на камнях STM32F10x.

Начнем с того что нужен сам Keil, у кого есть - молодцы, нету - . Для работы с каждой серией контроллеров, а их вот сколько -


нужен свой набор библиотек, все прелесть то что они в общем доступе непосредственно на странице у конкретного камня на сайте ST, раз уж мы пишем проект под STM32F100RB просто идем по его ссылке на ST, дальше переходим на вкладку Design Resources, ищем графу Related Tools and Software и в поле Discription, то бишь Описание, должны увидеть что-то подобное - STM32F10x standard peripheral library. Именно этот файлик и качаем. Ну а для ленивых - просто качаем отсюда (cкачиваний: 363) .

Кстати х в названии STM32F10x говорит о том что библиотеки подходят для контроллеров с любим числовым обозначением на его месте. В архиве есть куча не нужных примеров и еще мусор, нам нужна папка Libraries - именно там зарыта собака. Если серьезно собираемся заниматься камнями нужно запомнить минимальный список файлов который нужен для запуска проекта. Создадим отдельную папочку и назовем её, например, STM32F10x_Clear и в ней же папку с именем CMSIS. теперь из папки Libraries будем перекидывать нужные нам файлы. Очень важно что бы в полном пути не было кириллицы!

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport\core_cm3.с

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport\core_cm3.h

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.h

Еще нужен файл stm32f10x_conf.h - STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\ и вытяните его из любого проекта, можно просто вбить в поиск. Keil берет его обычно из своих папок, но часто бывает что из-за невиданных магнитных бурь находиться один счастливчик у которого его нужно подключать отдельно, сделаем это сразу.

Выглядеть всё это дело должно примерно так

Теперь в корне STM32F10x_Clear создаем вторую папку с именем SPL (Standard Peripheral Library) , и копируем туда папки inc и src, которые находятся в

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\ <--------

В итоге у вас должна быть папка STM32F10x_Clear в которой находятся папки CMSIS и SPL.

Папка CMSIS - содержит самые важные файлы, а SPL - готовые библиотеки периферии.

Вкратце о каждом из них:

Core_cm3 - файлы описания ядра M3

Stm32f10x.h - файл описания периферии

System_stm32f10x - файл начальной инициализации

Компилятор готов, библиотеки подготовлены, дело за малым, собрать всё это воедино.

Первый шаг - создание нового проекта в Keil. Ищем меню Project, в выпадающем списке - New uVision Project, называем и сохраняем проектик. Дальше или ищем по поиску либо по древовидному меню натыкаемся на наш камень, а именно - STM32F100RB, после выплывает сообщение о копировании стартап файла - там находятся файлы инициализации стека и таблицы векторов прерываний, в общем нужные вещи, жмем - ОК. Видим следующую картину

Теперь работаем с областью подключенных файлов - вот она

Там уже есть наши подключенные Startup файлы, теперь подключим остальное. Для наглядности переименуем SourceGroup1 в Startup.

Клацаем ПКМ на Target1 и жмем Add Group

Таким образом создаем еще 3 группы, походу называем их CMSIS, SPL, Source. Двойным кликом на имя группы мы открываем проводник для подключения файлов в группу, в CMSIS - добавляем все файлы из папки STM32F10x_Clear\CMSIS, в группу SPL из папки STM32F10x_Clear\SPL все файлы из inc и src. Итого осталась пустая папка группы Source - там будет хранится наш main, что бы его создать File-New, после File-Save as - в папку с нашим проектом сохраняем файл с именем main.c, теперь добавляем его через проводник группы Source. Все подключили, вроде можно пить пиво...а нет теперь - настройка.

Первым делом, идем к нашей папке STM32F10x_Clear и в ее Свойствах в Атрибутах снимаем галку Только для чтения, это нужно что бы менять содержимое подключенных файлов, ибо в окне файлов Keil"a напротив файлов будет стоят ключик и делайте что хотите. Идем дальше, клацаем на файлик stm32f10x.h в CMSIS и ищем строку

#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL) /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */ /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */ /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */ /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */ /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */ /* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD_VL: STM32 High density value line devices */ /* #define STM32F10X_XL */ /*!< STM32F10X_XL: STM32 XL-density devices */ /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */ #endif

Это директива выбора камня, делать это нужно обязательно, иначе не соберете проект. Так как у нас STM32 Medium density Value Line devices - её нужно раскомментировать убрав перед ней /*.

Следующая строка

#if !defined USE_STDPERIPH_DRIVER /** * @brief Comment the line below if you will not use the peripherals drivers. In this case, these drivers will not be included and the application code will be based on direct access to peripherals registers */ /*#define USE_STDPERIPH_DRIVER*/ #endif

Убираем комент на строке - #define USE_STDPERIPH_DRIVER

Теперь настройка компилятора. Клацаем ПКМ на Target1 - Options for Target "Target1". Видим следующее

Разделы которые нам нужны это:

Output - ставим галочку напротив Create HEX File

C/C++ - в поле Preprocessor Symbols указываем STM32F10X_MD_VL - именно его же мы раскомментировали, и USE_STDPERIPH_DRIVER через запятую, смотрим на скрин

Теперь нужно указать путь к папкам всех подключенных файлов, а это CMSIS и SPL. В поле Include Paths жмём на... потом New и добавляем папки CMSIS, SPL/inc, SPL/src, должно выйти так

Запомните на будущее, когда будете подключать сторонние библиотеки или другие файлы ОБЯЗАТЕЛЬНО! добавлять их в этом меню иначе ждите ерроры.

Раздел Debug - говорит за себя, делаем так как на картинке, а именно ставим галку и выбираем ST-Link Debugger

Давно, даже очень давно, не было новых статей на нашем статье, так что пришло время наверстывать 😉 Сегодня мы положим начало изучению STM32F4. И, наверное, начнем с создания нового проекта для этих контроллеров, хотя не хотел я, честно говоря, про это писать статью, так как новый проект тут создается, в принципе, так же как и для STM32F103 (). Но все-таки бывает, что именно с STM32F4 возникают некоторые трудности, так что, все-таки, рассмотрим этот процесс в подробностях)

Так что, запускаем Keil, создаем новый проект – Project -> New uVision Project. Сохраняем новый проект в какой-нибудь папке, и затем нам предложат выбрать используемый микроконтроллер. Что ж, выбираем, пусть это будет STM32F407VG:

Готово, в появившемся диалоговом окне тыкаем «Да» и к нам в проект добавится первый файл – startup_stm32f4xx.s . Также как и раньше, мы будем использовать библиотеки CMSIS и Standard Peripheral Library , но, естественно, уже для контроллеров STM32F4xx. Так что надо их обязательно скачать и добавить нужные файлы в наш пока еще пустой проект. Кстати не раз слышал от разных людей, что попадаются какие то «не такие» библиотеки для F4, и проект даже простейший не собирается. Сам я с таким не сталкивался, тем не менее, вот проверенные библиотеки, которые я сам использую:

Итак, скачали, все готово, теперь добавляем файлы в проект. На картинке видно, какие понадобятся:

Ну вот и закончена подготовка, теперь создадим новый.c файл, в котором и будет наш код. Идем в File->New , в Keil’е открывается пустой файл, жмем File->Save as и сохраняем его под именем test.c, например. Не забываем при сохранении указать расширение файла (.c). Файл создали, отлично, но надо его еще и в проект наш добавить. Ну, собственно, в этом ничего сложного нету 😉 В этот файл запишем тестовую пустую программу:

#include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" /*******************************************************************/ int main() { while (1 ) { __NOP() ; } } /*******************************************************************/

Почти все уже готово, осталось заглянуть в настройки проекта – Project->Options for target… Открывается окошко с множеством вкладок, нас тут интересуют лишь несколько. Открываем вкладку C/C++ и в поле Define прописываем:

Ну и внизу в поле надо добавить пути абсолютно ко всем файлам, включенным в проект. После выполнения этого шага можно давить на F7 (Build), и проект соберется без ошибок и предупреждений. Как видите, ничего сложного)

Но вообще я лично делаю несколько иначе. Смотрите в чем минус такого подхода. Вот мы скачали себе куда-то библиотеки CMSIS и SPL, добавили файлы из этих папок, прописали пути к файлам, все круто. НО! Проект не соберется на другом компьютере, поскольку пути все абсолютные, то есть указывают на конкретные папки на вашем компьютере. И на другой машине придется фактически заново выполнять действия по созданию нового проекта. Это огромнейший минус. Поэтому я обычно создаю отдельную папку для нового проекта, в ней создаю подпапки для CMSIS, SPL и других используемых библиотек и в эти папки запихиваю все файлы, которые мне понадобятся в каждом конкретном проекте. Вот, например, создадим папку STM32F4_Test для нашего нового проекта и в ней следующие папки:

В папки CMSIS и SPL я засунул все необходимые файлы, которые мы добавляли, создавая проект, в начале статьи. Теперь запускаем Keil, создаем новый проект и сохраняем его в нашу подпапку Project, чтобы все файлы проекта лежали в одном месте и не устраивали хаос)

Проект создан, теперь, как и раньше просто добавляем в него все файлы из папок STM32F4_CMSIS и STM32F4_SPL. В папку Source запихиваем наш тестовый.c файл с функцией main() и его тоже добавляем в проект. Осталось настроить настройки =) Все то же самое – в поле define прописываем:

USE_STDPERIPH_DRIVER,STM32F4XX



Собираем проект – ошибок нет, полет нормальный! В принципе в итоге получили то тоже самое, но теперь проект будет без проблем сразу собираться на любом другом компьютере, а это очень удобно и полезно) Абсолютно все файлы проекта теперь лежат рядом, в одной папке, а пути стали относительными и их не придется менять.
На этом то, собственно все, в ближайшее время что-нибудь поделаем для программирования STM32F4, обязательно, так что до скорого!;)

Полный проект из примера статьи –