Содержание
Главная›Программирование STM32›STM Урок 1. Установка Keil μVision
 
 
 
Урок 1
Вводим на поисковом сайте строку stm32f4 spl
Попадаем сюда http://www.st.com/web/en/catalog/tools/PF257901
Скачиваем отсюда библиотеку
Использовать мы будем отладочную плату STM32F4-DISCOVERY.
Запускаем Keil5
Запускаем там pack installer
Слева выбираем наш контроллер
А справа затем Device Specific и жмем Install.
После загрузки пакета выбираем справа еще ARM::CMSIS также жмем Install.
Создаем новый проект Project->New uVision Project
Даем ему имя, выбираем контроллер
Появляется Manage Run-Time Enveroment
Выбираем CMSIS->CORE и Device->Startup, ставим галки напротив и жмем «ОК»
В Target1 добавляем новую папки pl, а папку Source Group 1 переименовываем в user
Такие же папки создаем в физическом каталоге проекта.
Распаковываем библиотеку
Копируем файл STM32F4xx_DSP_StdPeriph_Lib_V1.6.1LibrariesCMSISDeviceSTSTM32F4xxIncludestm32f4xx.h
в папку pl и снимаем с него атрибут «для чтения».
Также в данную папку копируем две папки (inc и src) из STM32F4xx_DSP_StdPeriph_Lib_V1.6.1LibrariesSTM32F4xx_StdPeriph_Driver
Можно также снять с этих папок тот же атрибут, включая их содержимое.
Также из любого примера в STM32F4xx_DSP_StdPeriph_Lib_V1.6.1Project
Копируем в папку pl файл stm32f4xx_conf.h
В проекте в группу pl добавляем все файлы из папки plsrc, кроме файла stm32f4xx_fmc.c,
а также тот файл stm32f4xx_conf.h, который мы копировали выше.
В папке user создаем новый пустой файл main.c
Подключаем его в группу user в проекте
Пишем туда подключение добавленного хедер-файла вот таким образом (нажмите на картинку для увеличения размера)
Затем пропишем пути, выбрав контекстное меню на группе Target 1 и выбрав там следующий пункт
На закладке C/C++ нажмем … справа от поля Include Paths и в открывшийся диалог добавим пути
Добавим в main.c функцию main с бесконечным циклом
int main(void)
{
while(1)
{
}
}
Вызовем контекстное меню на объявлении заголовочного файла
И внесем следующие исправления
Разкоментируем
#define STM32F40_41xxx
и /*#define USE_STDPERIPH_DRIVER */
изменить 25000000 на 8000000 здесь
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
Чтобы включить возможность писать комментарии на русском языке,
в панели инструментов нажимаем пункт «Configuration»
И выбираем там кодовую страницу
Также вот здесь можно поменять размер и тип шрифта в редакторе
Добавим код в main()
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // включим тактирование порта
GPIOD->MODER = 0x55000000; // включим ножки 12,13,14,15 на выход
GPIOD->OTYPER = 0; //подтянем резистор ко всем ножкам порта
GPIOD->OSPEEDR = 0; //установим скорость LOW на все лапки порта
GPIOD->ODR = 0xF000; // 12,13,14,15 лапки установим в 1, тем самым зажжем светодиод
Полный код
#include «stm32f4xx.h»
//GPIO_InitTypeDef GPIO_InitStructure;
int main(void)
{
uint32_t i;
RCC->AHB1ENR|=RCC_AHB1ENR_GPIODEN;
GPIOD->MODER = 0x55000000;
GPIOD->OTYPER = 0;
GPIOD->OSPEEDR = 0;
while(1)
{
GPIOD->ODR = 0x8000;
for(i=0;ii++){}
GPIOD->ODR = 0x4000;
for(i=0;ii++){}
GPIOD->ODR = 0x2000;
for(i=0;ii++){}
GPIOD->ODR = 0x1000;
for(i=0;ii++){}
}
}
Соберём код, прошьём контроллер и посмотрим результат
Купить плату можно здесь STM32F4-DISCOVERY
Смотреть ВИДЕОУРОК
Статья посвящается Пановой Ксении.
Все картинки в этой статье кликабельны.
STM32 — это семейство 32-разрядных микроконтроллеров фирмы STMicroelectronics.
Микроконтроллеры содержат микропроцессорное ядро ARM, точнее ARM Cortex-M. Это ядро присуще не только микроконтроллерам STM32, оно существует само по себе, и на его основе выпускается множество микроконтроллеров от разных производителей.
Keil MDK-ARM (произносится «Кеил эм-ди-кей арм») — это среда разработки для микроконтроллеров с ядром ARM Cortex-M.
Среда продается за большие деньги, но существует бесплатная ограниченная версия, которую можно скачать с официального сайта.
Существует множество других сред разработки. Например, последнее время автор пользуется средой, которую описал в другой статье. Но в этой пойдет речь о Keil MDK-ARM, потому что она имеет большую популярность и достаточно проста.
Первым делом качаем последнюю версию Keil MDK-ARM с официального сайта. Она имеет ряд ограничений, которые не влияют на большинство задач. Самое существенное ограничение состоит в том, что среда не сгенерирует программу объемом больше 32 КБ, но такую программу надо постараться написать. Хотя микроконтроллеры STM32 часто имеют намного больший объем, вплоть до 2 МБ.
На момент написания статьи последняя версия Keil MDK-ARM — 5.18 (от 5 февраля 2016).
Чтобы скачать среду, надо заполнить форму на сайте Keil:
Следует ввести настоящий адрес электронной почты, иначе сайт будет ругаться. После заполнения и нажатия Submit, дается ссылка для скачивания:
Если вы хотите избежать заполнения формы, то воспользуйтесь страницей, которую сделал автор, чтобы облегчить скачивание.
Качаем и устанавливаем. Установленная среда занимает на диске около 1,3 ГБ. После установки автоматически запускается менеджер пакетов:
Он нужен, чтобы качать, устанавливать и обновлять различные дополнения (пакеты).
Менеджер пакетов появился в MDK-ARM версии 5, что уменьшило объем установочного файла почти в два раза (версия 4.71 была объемом 550 МВ, а версия 5.00 — 300 МБ).
В левой части менеджера мы выбираем устройства (микроконтроллеры), а в правой соответствующие им пакеты.
Допустим, нам надо вести разработку под микроконтроллер STM32F407VG, который установлен на отладочной плате STM32F4-Discovery.
Тогда находим этот микроконтроллер в списке слева и устанавливаем соответствующий пакет DFP:
Можно заметить, что среди установленных пакетов есть CMSIS. CMSIS — это библиотека для ядра Cortex-M, общая для всех микроконтроллеров. Библиотека разрабатывается фирмой ARM и доступна для скачивания с официального сайта после регистрации. Можно было бы не устанавливать этот пакет, а пользоваться официальным выпуском библиотеки, но это дополнительные сложности.
Закрываем менеджер пакетов и запускаем Keil uVision5 (произносится мю-вижен):
Keil uVision5 — это часть MDK-ARM, графический интерфейс среды, который включает редактор кода:
Я рекомендую произвести небольшую настройку редактора. Выбираем меню «Edit -> Configuration…», и производим следующие настройки:
- Кодировка UTF-8.
- Правая граница кода в 80 символов.
- Отступы по 4 пробела.
Эти настройки довольно спорные. У каждого разработчика свои предпочтения.
Теперь создаем проект. Для этого выбираем меню «Project -> New uVision Project…». В открывшемся окне выбираем расположение и имя проекта. Для проекта лучше создать отдельную папку и сохранить проект туда.
После сохранения появится окно выбора устройства. Выбираем нужный микроконтроллер и нажимаем «ОК». Если бы мы не установили нужный пакет, то микроконтроллера не было бы в списке:
В следующем окне предстоит выбрать компоненты, которые будут использоваться в проекте. Необходимо выбрать «CMSIS:CORE» и «Device:Startup»:
После нажатия «OK» процесс создания проекта завершится.
В дальнейшем вы всегда сможете запустить окно выбора компонентов, чтобы добавить или удалить их. Для этого надо выбрать меню «Project -> Manage -> Run-Time Evironment…».
При выборе компонентов может оказаться, что какой-то компонент зависит от других компонентов, которые вы не выбрали. Об этом вы узнаете из сообщений в нижней части окна. Необходимо будет выбрать зависимые компоненты.
После создания проекта описанным способом, в окне справа вы увидите следующую структуру проекта:
Здесь мы видим название проекта «example», цель проекта «Target 1», пустую группу файлов «Source Group 1», компоненты CMSIS и Device.
Целей проекта может быть сколько угодно. Цель включает в себя важнейшие настройки проекта в том числе выбор микроконтроллера. Цели нужны, чтобы можно было собрать программу разными способами для одних и тех же файлов исходного кода. Например, вам может понадобиться, чтобы проект охватывал множество микроконтроллеров.
Группы файлов нужны, чтобы красиво группировать файлы исходного кода. Группы помогают легко ориентироваться в файлах в большом проекте. Например, у вас может быть группа файлов, отвечающих за светодиоды, и отдельная группа с файлами для взаимодействия с USB.
В структуре мы видим два файла. Один с расширением «s». Он содержит исходный код на языке ассемблера. Другой с расширением «с». Он содержит исходный код на языке Си.
Собрать проект и получить файл прошивки можно нажав клавишу F7. Но в таком виде проект не будет собран и вы получите ошибку, потому что отсутствует функция «main()».
Функция «main()» — это точка входа в вашу программу, то с чего начинается программа. Ее наличие обязательно если вы пишите программу на языке Си.
Давайте создадим эту функцию. Кликнем на группе «Source Group 1» правой кнопкой и выберем «Add New Item to ‘Source Group 1’…» (перевод: добавить новый элемент в группу ‘Source Group 1’). Создадим файл «main.c»:
В созданный файл добавим код:
int main() { return 0; }
В конец файла стоит добавить пустую строку, иначе при сборке вы получите предупреждение «warning: #1-D: last line of file ends without a newline».
Теперь проект можно собрать клавишей F7. В результате вы получите файл «Objectsexample.axf» (по умолчанию имя файла совпадает с именем проекта). Файл располагается в папке с проектом.
Обычно разработчику требуется файл прошивки в формате Intel HEX. Чтобы получить его, надо произвести настройку цели. Чтобы увидеть настройки цели нажмите Alt-F7, перейдите на вкладку «Output» и выберите «Create HEX File».
После очередной сборки вы получите файл «Objectsexample.hex».
Сейчас программа не делает ничего, и прошивать ее бессмысленно. Давайте напишем программу, которая управляет состоянием ножки микроконтроллера.
Запустим выбор компонентов с помощью меню «Project -> Manage -> Run-Time Evironment…» и выберем компонент «Device:STM32Cube Hal:GPIO».
В нижней части окна мы увидим неудовлетворенную зависимость «Device:STM32Cube Hal:Common». Выберем этот компонент и увидим еще больший список зависимостей. Необходимо выбрать все требуемые зависимости:
- Device:STM32Cube Hal:Common
- Device:STM32Cube Hal:RCC
- Device:STM32Cube Hal:PWR
- Device:STM32Cube Hal:Cortex
- Device:STM32Cube Framework:Classic
STM32Cube — это библиотека, которую предоставляет STMicroelectronics.
При выборе компонентов мы выбираем какие возможности этой библиотеки использовать.
Микроконтроллер, кроме ядра, содержит большое количество периферийных устройств: АЦП, ЦАП, таймеры, различные интерфейсы и многое другое. Каждое периферийное устройство имеет свое название. Например, устройство для работы с портами микроконтроллера называется GPIO, об этом можно узнать из документации на микроконтроллер.
Библиотека STM32Cube многоуровневая, то есть включает в себя множество промежуточных библиотек. Одна из промежуточных библиотек называется STM32Cube HAL, или просто HAL. Она поделена на модули и каждый модуль соответствует какому-нибудь периферийному устройству. Название модуля совпадает с названием устройства, например, имеется модуль GPIO.
Существует большое количество документации по STM32Cube. Но основное описание по работе с периферийными устройствами содержится в руководстве по HAL. Это руководство разработчик использует большую часть времени. Обратимся к нему, чтобы заставить шевелиться ножки микроконтроллера.
Для начала подключим HAL в нашей программе, добавив строчку перед определением функции «main()»:
#include "stm32f4xx_hal.h"
В самом начале функции «main()» вызовем функцию «HAL_Init()», которая инициализирует библиотеку.
Таким образом мы получим следующий код в файле «main.c»:
#include "stm32f4xx_hal.h" int main() { HAL_Init(); return 0; }
Продолжение следует…
На этом я вынужден прервать свою статью, так как в данный момент мне не на чем отлаживать программу, то есть нет под рукой отладочной платы.
Я написал программу, которая собирается и теоретически должна работать, но я не хочу вводить в заблуждение читателя. Выше изложенный материал считаю полезным и без конечного результата.
В статье я хотел еще привести конечный код и объяснить, как он работает. Могу лишь поделиться непроверенной программой:
#include "stm32f4xx_hal.h" int main() { HAL_Init(); // Разрешить тактирование порта A. __HAL_RCC_GPIOA_CLK_ENABLE(); // Настройки порта. GPIO_InitTypeDef s; s.Pin = GPIO_PIN_0; // Вывод 0. s.Mode = GPIO_MODE_OUTPUT_PP; // Цифровой выход. s.Pull = GPIO_NOPULL; // Без подтяжки. s.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // Максимальная скорость. // Настроить вывод 0 порт A. HAL_GPIO_Init(GPIOA, &s); // Бесконечно переключать состояние порта с максимальной скоростью. while(1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); } //return 0; } void SysTick_Handler(void) { HAL_IncTick(); }
Ссылки
- Скачать продукты Keil без заполнения формы.
- Скринкаст «Eclipse и GNU Tools для разработки под ARM-микроконтроллеры«.
- Микроконтроллер STM32F407VG.
- Отладочная плата STM32F4-Discovery.
- Библиотека STM32CubeF4.
- Руководство по STM32CubeF4 HAL.
- Библиотека CMSIS.
- Отсчет времени в STM32Cube.
- Tutorial
Вступление
В прошлой статье я поделился личными впечатлениями о полученном мною наборе и запрограммировал контроллер демонстрацонным проектом с помощью MT-LINK (так же был предоставлен). Теперь, когда мы детально рассмотрели весь комплект, настало время начать его осваивать. Для нетерпеливых — итог.
Создаем пустой проект в Keil 5 для К1986ВЕ92QI.
Для начала следует создать чистый проект. Можно конечно использовать демонстрационный проект как основу, но проект с номером «2» так и не запустился, а в проекте «3» почему-то в меню выбора контроллера чистый лист. Это меня как-то насторожило. Проекта с номером «1» нет в принципе.
- 1. Заходим в Project -> New uVision Project…
- 2. Создаем папку для проекта (в пути не должно быть русских букв), пишем имя (так же на английском) и сохраняем.
- 3. Выбираем наш контроллер.
- 4. В появившемся окне просто жмем «Ок». Честно сказать, мне никогда не удавалось настроить проект через этот редактор так, чтобы все скомпилировалось с 1-го раза. Всегда приходилось что-то менять. Чаще всего оказывалось, что проще сделать самому.
- 5. В левом верхнем углу появилось дерево проекта. Теперь нам нужно создать необходимые подкатегории. Для этого по самой верхней папке жмем правой кнопкой мыши и выбираем «Manage Project items…»
- 6. В данном меню 2 раза нажимаем левой кнопкой мыши на папку, название которой хотим изменить и пишем то, что хотим. Опять же, лучше на английском. Для добавления новый папок служит иконка слева от «красного крестика». Нам понадобятся минимум 4 папки:
- 1. Под пользовательские данные (наши файлы).
- 2. Под драйвера LCD (те, что в комплекте).
- 3. Для кода работы с Flash.
- 4. Под SMSIS и подобие SPL.
- 7. После того, как переименовали все папки, жмем «ОК». Каталог должен иметь примерный вид.
- 8. Далее нам нужно достать все эти файлы. Брать мы их будем из рабочего демонстрационного проекта. Кстати. Только сейчас заметил, что проект был написан под keil 2. Это меня немного поразило. Еще одним интересным фактом стало то, что между демонстрационным проектом «2» и «3», судя по информации последнего изменения — прошло 3 месяца. Причем к нашему времени ближе работающий проект. Из него и будем брать файлы (где достать этот демонстрационный проект – сказано в предыдущей статье-обзоре). Скопировать нужно выделенные файлы. Причем main.c (как и любые свои файлы) лучше убрать в отдельную папку. Я для этого создал папку User и туда поместил main.c (его мы изменим и будем базироваться на нем).
- 9. Далее нам нужно добавить файлы библиотеки в проект. Добавление происходит следующем образом. Щелкаем правой кнопкой по нужной папке в дереве проекта и выбираем «Add Existing Files to Group ‘Имя группы’…». В открывшемся окне нужно выбрать тип файлов «All files (*.*)». После чего выбрать 1 или выделить несколько файлов. Добавить нужно:
- 1. В папку User -> «User -> main.c». Это наш самый главный файл. Чуть изменив его, мы начнем писать свой код именно в нем.
- 2. В папку Flash -> «flash -> MilFlash.c». Здесь хранится библиотека для работы с Flash контроллера.
- 3. В папку LCD -> «mlt -> mlt_lcd.c». Библиотека работы с LCD, который установлен на плате.
- 4. В папку SMSIS_and_Drivers -> «Libraries1986BE9x_StdPeriph_Driversrc -> все файлы .c». Тут хранится аналог SPL у STM32. Проще говоря, это «обертки», которые позволяют не вдаваясь в структуру контроллера управлять его периферией (выводы, uart и т. д.).
- 5. В папку SMSIS_and_Drivers -> « LibrariesCMSISCM3DeviceSupport1986BE9xstartuparm -> startup_1986be9x.s». Это файл «стартап». Тут прописаны все «вектора переходов». Иначе говоря, по любому прерыванию (к примеру, нажатие кнопки) контроллер возвращается к этой таблице и смотрит, куда ему перейти, чтобы выполнять код дальше.
- 6. В папку SMSIS_and_Drivers -> «LibrariesCMSISCM3DeviceSupport1986BE9xstartuparm -> system_1986BE9x.c».
Итогом должно стать такое дерево.
- 10. Далее нам нужно немного почистить файл main.c. Для этого кликаем на него щелчком левой мыши в дереве каталога. Удаляем все, кроме оболочки функции main и #include файлов. Должно остаться так.
- 11. Как можно было заметить, около самого верхнего #include файла стоит крестик. Keil просто не видит данного файла. Для того, чтобы исправить это, мы должны указать ему, где ему брать этот файл. Для этого жмем Alt+F7. В открывшемся окне переходим во вкладку C/C++. Маленькое отвлечение. В будущем я часто буду использовать приемы, которые keil не будет понимать по умолчанию. Для того, чтобы исправить это, нужно нажать галочку около надписи «C99 Mode». Это даст возможность писать на более совершенном стандарте языка Си, чем это можно было делать изначально. Далее следует нажать на прямоугольник с «…» внутри. Справа около строчки с подписью «Include Paths».
- 12. В открывшемся окне нажимаем на иконку с прямоугольником, слева от крестика. Это создаст пустую строку. В правом углу созданной строчки жмем на «…». После чего указываем нужную папку, в которой лежат интересующие нас файлы. После этого жмем «ОК». Папка будет добавлена. Необходимо добавить все эти пути. Если вы заметили, то все ссылки кроме одной – относительные. То есть идут от корневого каталога. Но 1 идет начиная от «C:». Это ссылка на сам каталог с проектом. Его тоже следует указать. Жмем «ОК» и переходим в файл main.c.
Компилируем простейшую программу.
Вставим в функцию main бесконечный цикл с увеличением счетчика на 1. Теперь наш файл должен выглядеть так. Не забываем о том, что в конце каждого файла должна быть пустая строка. Keil считает это как предупреждение, которое частенько действует на нервы. Конечно компилироваться будет, но сам факт предупреждения – настораживает. На этом настройка закончена. Мы можем перекомпилировать наш проект нажав F7. Если все прошло хорошо, ты мы увидим это. Теперь осталось лишь в настройках настроить J-LINK и можно заливать. О том, как его настраивать – было подробно рассказано в предыдущей статье. Кстати. J-LINK видит чип и без подключения дополнительного питания, а так же позволяет отлаживать чип. Так что внешнее питание не особо нужно. При переходах по строкам кода видно, как мелькает подцветка экрана.
Настраиваем ножку контроллера для работы со светодиодом
Пробежавшись по оглавлению документации, я не увидел ничего про тактирование переферии, поэтому сразу же принялся настраивать ее. Вспоминая обо всех ужасах SPL в плане настройки портов ввода-вывода в STM32, мысль об использовании библиотек, шедших в комплекте, отпала сразу же. Да и не хорошо это, вот так сразу, не успев поиграться с регистрами, прятаться за библиотеками, в которых, кстати, не исключены ошибки. Для начала поймем, какой именно порт нам нужно настроить. В «Отладочная плата 1986ВЕ92У, К1986ВЕ92QI (MDR32F9Q2I)Печатная плата 1986EvBrd_LQFP64» есть файл 1986EvBrd_64_Rev2.pdf, в котором приведена схема платы. На ней мы можем увидеть, что 2 светодиода подключены к пинам PC0 и PC1. Отлично. Не придется мучиться со смещением. Очень понравилось, что у Миландра вся информация о линейке чипов в одном документе. В STM32 очень путался в документах… Взглянем на схему порта ввода-вывода. Чем-то отдаленно напоминает схему порта у STM32. Не увидев ничего, что бы бросилось в глаза, идем настраивать регистры. Так как я не знал, как именно Миландр назвал свои порты, я полез в библиотеку настройки портов. Там увидел следующее. Ну и чуть выше. Убедившись, что адрес порта C совпадает с адресом в датащите, я создал новую функцию в файле main.c (Обязательно выше функции main! Иначе придется описывать прототипы функции в .h файле. А это лишние пока что заморочки.). Начинаю писать PORTC-> (по привычке), зажимаю ctrl+пробел и вижу следующее. Вот это уже знакомая картина. Очень обрадовался. Далее начал смотреть, какие регистры нужно изменить. Нам нужен светодиод на порту «0», так что можем записать: PORTC->RXTX |= 1; Этим мы переводим 0-й бит порта в 1. Тем самым зажигая диод на порту 0. Но перед его включением стоит его настроить… Так что данное действие выполняем в последнюю очередь, а перед. У нас выход, так что: PORTC->OE |= 1; Оставляем без изменений, так как по умолчанию везде нули. А вот тут нам нужен цифровой: PORTC->ANALOG |= 1; Подтяжка нам не нужна, так что, пропускаем. Ну и это нам тоже не надо… А вот тут нам нужно выбрать скорость. По умолчанию – все. Выбираем медленный фронт. Для светодиода его вполне хватит: PORTC->PWR |= 1; Ну и последний регистр. Вообще неведомая для меня ранее вещь. С этим еще предстоит разобраться. Ну вот, с настройкой мы закончили. НО, если мы сейчас зашьем этот код, то у нас ничего не заработает. Я долго пытался понять, в чем проблема, пока еще раз внимательно не прочитал про систему тактирования. В разделе о портах нет ни слова о тактировании. Зато есть отдельная глава, в которой написано, как и что нужно тактировать. Зашел туда и увидел следующее. Нам нужны порты. Это вполне подходит под описание «периферийные блоки». Ищем этот регистр и вот. Оставалось только понять, как в keil называется этот регистр. Так как в библиотеках толком ничего не нашел, то пошел подбором. В итоге выяснилось, что он именуется RST_CLK. Ну а дальше нам нужно лишь записать «1» в нужный блок. RST_CLK->PER_CLOCK |=(1<; На «PER_CLOCK» вышел случайно. Когда написал «RST_CLK» нажал ctrl+пробел и после появления списка, «p». После выбрал подходящий вариант. В итоге получился такой код. Код компилируется и мы получаем.
Русские комментарии в keil 5
Сейчас стоит расставить комментарии по коду, но на русском этого сделать не получается. Выходят непонятные символы, для того, чтобы можно было писать русский комментарии, нужно зайти Edit -> Configuration. И там сменить кодировку, как показано на рисунке. После чего нажать «ОК».
Мигаем светодиодом
Теперь напишем код, который будет с помощью цикла мигать светодиодом. Зашиваем и радуемся! Скорость взята по опыту мигания светодиодом на STM32. Светодиод мигает с частотой примерно раз в секунду. Все. Вроде бы ничего не упустил. Советую этот проект сразу же заархивировать. Чтобы потом использовать как заготовку. Проект на github. Еще раз напоминаю. В настройках проекта есть одна ссылка к директории проекта относительно «C:». Так что проект будет работать лишь по тому же пути, что и в статье. Вы легко можете сменить путь и свободно пользоваться. Спасибо sguwenka за исправления.Используемые источники:
- http://narodstream.ru/stm-urok-1-ustanovka-keil-μvision/
- https://bravikov.wordpress.com/2016/02/21/начало-работы-с-stm32-в-keil-mdk-arm/
- https://habr.com/post/255323/