Сегодня мы рассмотрим: Настоящие ценители музыки знают, что для качественного...
Давно, даже очень давно, не было новых статей на нашем статье, так что пришло время наверстывать 😉 Сегодня мы положим начало изучению 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, обязательно, так что до скорого!;)
Полный проект из примера статьи –
С этой статьи я начинаю приводить практические примеры. И первый из них будет - создание базового проекта. Для чего я это делаю? Ответ прост: чтобы упростить сборку нужной мне программы. Структура этого проекта рассчитана на полную автономность по отношению к другим заголовочным файлам и библиотекам, поэтому он достаточно переносим.
Также следует заметить, что в том решении которое я выбрал, есть два больших плюса:
- Проект расширяем, т.е. вы можете легко добавить в него как простой код, так и целые библиотеки.
- Изменением минимального количества файлов можно изменять модель МК (чуть позднее я проработаю этот момент получше, чтобы можно было менять семейства МК).
Makefile
Для управления сборкой, очисткой и загрузкой проекта используется система make . Перейдя по ссылке можно узнать как она работает, я же сконцентрирую внимание на некоторых особенностях моей версии системы сборки:
# Include common config
include lib/make/Makefile.common - включает общий конфигурационный файл проекта (ниже я опишу его устройство чуть подробнее). Позволяет быстро добавлять глобальные флаги и пути.# Making libs
lib :
$(MAKE ) -C lib ROOTDIR = $(ROOTDIR ) - при сборке библиотек я передаю путь корня проекта во все нижележащие Makefile.# Rules for write firmware to mcu
write : firmware.bin
qstlink2 -cewV ./firmware.bin - для записи я использую приложение QSTLink о котором рассказывал в .
# Project root path
ROOTDIR = $(realpath . ) - данная опция указывает что считать корнем проекта, очень удобно дабы не плодить в каждом звене иерархии проекта тучу относительных путей. Применяется для включения заголовочных файлов и указания путей библиотек.stm32f4xxxg_flash.lg
Скрипт построения бинарного образа программы с экспортом абсолютных адресов регионов для инициализации. Скопирован из стандартного скрипта сборки, с добавлением некоторых опций, а также изменений активных областей.
Общие заголовочные файлы проекта. Собственно помимо заголовочного файла для каждого файла исходного кода в src, есть директории в которых находятся специфичные для проекта определения. Вот краткое описание содержимого этой директорииx:
all :
$(MAKE ) -C std_periph - для сборки библиотекиclean :
$(MAKE ) clean -C std_periph - для её очистки
Также, в этой директории присутствует 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); }
Кто-то любит пирожки, а кто-то - нет.
И так, есть отладочка 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
Всё, компилируем и получаем пустой собирающийся проект, с которого можно начать путь постижения премудростей новых контроллеров ст.