Top.Mail.Ru

Часть 1. STM32 и С++. Как избавиться от HAL и перейти на С++.

В интернете очень много информации, но по теме ООП + STM32 я её встречал мало. В серии статей я попытаюсь рассказать, как я пришёл к ООП ни как к таковому, а именно на микроконтроллерах от фирмы ST. Это не моё НоуХау. Это то, что я сумел собрать для себя и то, чем я пользуюсь для облегчения программирования в своих разработках.

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

Среда разработки: CubeMX, CubeIDE. Всегда последней версии.

Микроконтроллеры: Серия STM32

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

Все свои проекты я храню в каталоге WorkDevel. Он содержит подкаталоги:

  • AltiumLib - библиотеки Altium Designer;
  • Datasheet - даташиты на электронные компоненты;
  • Developer - каталог, хранящий все проекты;
    • Examples - примеры не привязанные к МК. Могу наполнять этот каталог без описания в статьях. Будет время заглядывайте, может найдёте что то интересное; 
    • Project_Lesson_01 - это тот первый каталог, в котором мы с вами будем работать;
      • Code_CPP - здесь будут подкаталоги с нашим кодом. На больших проектах там может быть не один каталог.
      • Output - сюда я вывожу Gerber файлы для заказа их в Китае;
      • Pcad - здесь хранятся проекты схем и плат. Так же как и в Code_CPP, на больших проектах может содержать несколько подкаталогов;
      • Source - сюда складываю первичную информацию. Техзадания, даташиты на элементы, участвующие именно в этом проекте. И так далее;
  • Tests MK - здесь храним примеры для разных МК, которые будут описаны в последующих статьях;
  • STM32Lib - каталог, где хранятся библиотеки и программные ядра на каждый тип микроконтроллера.
    • Device - библиотеки, зависимые от типа ядра МикроКонтроллера (МК);
    • Library - библиотеки, независимые от типа MK.

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

Вот теперь можно приступить.

Примечание: То, что я буду давать, будет применимо к любому ядру МК. В случае, если есть какие-то отличия между ядрами в инициализации периферии, я постараюсь на этом заострять внимание.

Вы можете проделать показанные мною операции для любого ядра МК. Я же покажу всю цепочку на STM32F407VET6. Так как для него у меня более полные библиотеки. Но никто не мешает вам, взяв его библиотеки за пример, дописать свои.

Создание проекта.

Загружаем CubeMX и выбираем нужный нам МК:

Никакую периферию мы не инициализируем, а сразу идём на закладку Project Manager:

Здесь нас интересуют только три поля:

  1. Project Name - имя проекта. Вводим имя, по которому будем идентифицировать проект.
  2. Project Location - выбираем каталог, в котором будет храниться наш проект. В данном случае С:\WorkDevel\Developer\Project_Lesson_01\Code_CPP
  3. Toolchain\IDE - выбираем STM32CubeIDE.

Затем слева выбираем Code Generator и ставим галку напротив первого пункта в разделе Generated files:

В данном проекте нам она погоды не сделает, но привычка позволит в более сложных проектах разбивать функции инициализации периферии по отдельным файлам. Что весьма удобно. Почему-то не все это любят. Есть такие, что пишут портянки по 5000 строк в одном файле. А можно было разбить код на отдельные логически блоки и раскидать их по файлам.

Подготовка закончена, генерируем код (кнопка справа вверху Generate Code):

Нам предлагается или открыть каталог с проектом, или открыть его сразу в IDE, или всё на этом. Выберем открытие проекта. Загружается выбранная IDE, в нашем случае CubeIDE. После загрузки проекта открываем main.c:

Пробуем компилить, никаких ошибок быть не должно:

Теперь начинаем методично уничтожать HAL. В каталоге Inc удаляем все файлы, в каталоге Src оставляем только те файлы, которые на картинке, в каталоге Drivers удаляем весь подкаталог STM32F4xx_HAL_Driver:

В main.c удаляем всё, кроме указанного на картинке:

Идём в меню Project>Properties>C/C++ Build>Settings, закладка Tool Settings, MCU GCC Compiler>PreprocessorВверху выбираем All Configurations и грохаем USE_HAL_DRIVER:

Нажимаем Apply. Идём в Include Paths, там удаляем всё упоминание о HAL:

Нажимаем Apply и Apply and Close. Пытаемся компилить и получаем одно предупреждение. Необходимо эту строку закомментировать. Не удалять ни в коем случае, она позже вам пригодится:

Нажимаем правой кнопкой на проекте и выбираем конвертацию в С++:

Вроде визуально ничего не изменилось. Но если посмотреть здесь:

У нас появился новый пункт: MCU G++ Compiler. Переименовываем main.c в main.cpp и пробуем компилить:

Выдаётся такая ошибка:

Ничего страшного. Идём сюда и выбираем Clean Project:

Компилируем снова и получаем 0 ошибок:

На этом пока всё. Позже покажу как подключать библиотеки находящиеся в STM32Lib.

Тема на форуме - перейти.

Подписаться
Уведомить о
guest

19 комментариев
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии
TQFP
2 лет назад

Спасибо, интересно, буду ждать следующие части.

Диман
Диман
2 лет назад

Да, да, да, как раз это я и искал в такой доступной форме. Жду продолжения

Валерий
Валерий
Ответ на комментарий  Эдуард
1 год назад

Все равно продолжает выскакивать ошибка error: '__disable_irq' was not declared in this scope
  16 |  __disable_irq();

Константин
Константин
2 лет назад

Спасибо за раскрытие этой темы! Очень интересно! Тоже жду следующие части.)

Igor_u
Igor_u
2 лет назад

Где сейчас можно скачать cube ide или mx, свежие версии?
st.com сейчас совсем не дают скачивать.

snowcumbia
2 лет назад

Доброго времени ) Подскажите пожалуйста, только заинтересовался темой . С чего начать, чтобы было понятнее содержание статей по STM & с++. Если у меня никакого HAL не было то я могу начать с этой статьи, пренебрегая действиями с HAL? спасибо.

Алексей
Алексей
1 год назад

Наконец то нашёл дельную статью, может поможет наконец то пересесть с Microchip IDE.

Алексей
Алексей
Ответ на комментарий  Эдуард
1 год назад

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

Алексей
Алексей
Ответ на комментарий  Эдуард
1 год назад

Вот и добрался я до экспериментов. И тут же впёрся в синтаксис HAL.
Думаю нужен вашь совет, не пойму что не так с простейшим кодом.
Написал 2 карианта управления пином, оба компилируются и загружаются в чип без ошибок. Но диод на макетке молчит.

 {
   /* USER CODE END WHILE */

    HAL_GPIO_WritePin(13_GPIOC_Port,13_Pin,1);            //1
    HAL_GPIO_WritePin(GPIOС, GPIO_PIN_13, GPIO_PIN_SET);  //2
    HAL_Delay(60);

    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); //2
    HAL_GPIO_WritePin(13_GPIOC_Port,13_Pin,0);            //1
    HAL_Delay(100);

   /* USER CODE BEGIN 3 */
 }
Где я что то не догоняю?
Макетка простенькая - STM32F103C8 (Blue Pill)
за ранее спасибо!

Алексей
Алексей
Ответ на комментарий  Эдуард
1 год назад

Всё, терпения моего на HAL не хватило, убил я его по инфе в вашей статье.
Если не трудно, не мешала бы статья для перешедших на классы по конфигурированию контроллера, желательно на примере какой нибудь простенькой мигалки диодом.
Что то пока тяжело CUBE даётся, но мы не сдаёмся!

Aveal
Администратор
Ответ на комментарий  Алексей
1 год назад

Попробуй как здесь, один в один сделать - https://microtechnics.ru/stm32cube-ispolzovanie-portov-vvoda-vyvoda-gpio/. Ну вывод другой только соответственно.

Алексей
Алексей
Ответ на комментарий  Aveal
1 год назад

К сожалению времени на изучение более не осталось!
Срочно нужен продукт.
К счастью пробный код проглотил и превосходно отработал в Platformio. Осталось почитать про активацию и настройку встроенных часов с внешним кварцем на 32.768.
Но, после, я продолжу добивать CUBE.
В любом случае спасибо за помощь!!!

19
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x