Урок 14. Создание и использование библиотек для STM32. Библиотека Debounce.

Уроки STM32

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

Предыдущий урок     Список уроков     Следующий урок

В предыдущем уроке мы разработали класс Debounce для обработки дискретных сигналов. С помощью него можно устранять дребезг контактов, фильтровать сигнал, ослаблять влияние электромагнитных помех и т.п.

 

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

Выход очевиден – оформить класс библиотекой. Давайте этим и займемся.

 

Последовательность действий для создания библиотеки STM32.

Библиотека, по крайней мере, на нашем уровне программирования, это тот же класс, только размещенный в других файлах. В текст программы файлы библиотеки включаются директивой препроцессора #include. Таким образом, текст библиотеки в нашей программе мы не видим. А на этапе компиляции он “подсовывается” компилятору директивой #include . И благополучно транслируется вместе с остальным исходным кодом.

Я скопировал проект предыдущего урока Lesson13_1 в новую папку Lesson14.

Переименовал его в Lesson14_1.

Открыл в Atollic TrueStudio и переименовал его в IDE еще раз. Все это мы уже делали.

Atollic TrueStudio

Получился проект с классом Debounce из предыдущего урока. Этот класс мы будем оформлять библиотекой.

Библиотека состоит как минимум из двух файлов:

  • заголовочного файла, с расширением .h ;
  • файла исходного текста, расширение .cpp.

Заголовочный файл должен содержать описание класса, объявление переменных, константы. Программный код в нем не размещают.

Второй файл (.cpp) содержит код методов класса.

Давайте создадим файлы библиотеки. Чтобы в структуре проекта не было путаницы, создадим для всех пользовательских библиотек папку Libraries. А в ней папку Debounce, уже для нашей библиотеки.

Правой кнопкой мыши нажимаем на имя проекта, New -> Folder.

Создание новой папки

Задаем имя папки Libraries.

Теперь нажимаем на Libraries, New -> Folder.

Создаем папку Debounce.

Теперь выбираем папку Debounce, New -> File.

Создаем в ней файлы Debounce.h  и Debounce.cpp.

IDE

 

Заголовочный файл Debounce.h.

Неплохо в начале файла поместить краткую информацию о библиотеке. У кого, на что хватит фантазии. Естественно, надо оформить этот блок комментариями.

/*
* Debounce.h - библиотека обработки дискретных сигналов STM32.
*
* Может быть использована для устранения дребезга контактов, цифровой фильтрации сигналов от помех.
*
* Работает в фоновом режиме.
*
* В параллельном процессе регулярно должен вызываться один из методов обработки:
*
* void scanStability(void); // метод ожидания стабильного состояния сигнала
* void scanAverage(void); // метод фильтрации сигнала по среднему значению
*
* В результате формируются признаки состояния сигнала:
*
* uint8_t flagLow; // признак СИГНАЛ В НИЗКОМ УРОВНЕ
* uint8_t flagRising; // признак БЫЛ ПОЛОЖИТЕЛЬНЫЙ ФРОНТ
* uint8_t flagFalling; // признак БЫЛ ОТРИЦАТЕЛЬНЫЙ ФРОНТ
*
* Признаки могут быть прочитаны функциями:
*
* uint8_t readFlagLow(void); // чтение признака СИГНАЛ В НИЗКОМ УРОВНЕ
* uint8_t readFlagRising(void); // чтение признака БЫЛ ПОЛОЖИТЕЛЬНЫЙ ФРОНТ
* uint8_t readFlagFalling(void); // чтение признака БЫЛ ОТРИЦАТЕЛЬНЫЙ ФРОНТ
*
* Пример создания объекта:
* Debounce button(GPIOC, 1 << 11, 10); // экземпляр класса Debounce
*
* Подробно описана http://mypractic.ru/uroki-stm32 в уроках 12, 13, 14
*
* Разработана Калининым Эдуардом.
*
* http://mypractic.ru
*/

Дальше следует объявление класса, которое надо заключить в конструкцию.

/* Проверка, что библиотека не подключена */
#ifndef DEBOUNCE_H
#define DEBOUNCE_H

. . . . . . . . . . . . . . . . . . . 

#endif/* DEBOUNCE_H */

Это предотвратит повторное подключение библиотеки.

И еще необходимо подключить файл stm32f103xb.h. В нем содержатся CMSIS-имена регистров.

/* Проверка, что библиотека не подключена */
#ifndef DEBOUNCE_H
#define DEBOUNCE_H

#include "stm32f103xb.h"

class Debounce {

    . . . . . . . . .

};

#endif /* DEBOUNCE_H */

 

В файл Debounce.cpp мы копируем код методов. И в самом начале подключаем заголовочный файл. В нем содержится определение класса.

#include "Debounce.h"

//----------------- методы класса Debounce

. . . . . . . . . . . . . . .

 

Все библиотека создана. Теперь необходимо подключить ее.

Прежде всего, удаляем из main.cpp все то, что мы переместили в библиотечные файлы. А именно: объявление класса и код методов.

Подключаем нашу библиотеку.

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "../Libraries/Debounce/Debounce.h"

Мы указали полный путь к папке библиотеки.

Можно написать короче:

#include "Debounce.h"

Но тогда путь к папке необходимо сообщить компилятору:

Project -> Build Settings -> Tool Settings -> C++ Compiler -> Directories -> Add (зеленый плюсик сверху).

Atollic TrueStudio

В списке появится путь к нашей библиотеке

../Inc
../Libraries/Debounce
../Drivers/STM32F1xx_HAL_Driver/Inc
../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy
../Drivers/CMSIS/Device/ST/STM32F1xx/Include
../Drivers/CMSIS/Include

Еще вариант той же операции:

Правой кнопкой мыши нажимаем на папку Debounce в проекте, Add/Remove Include Path -> OK

В списке путей для include появится

"${workspace_loc:/${ProjName}/Libraries/Debounce}"

Транслируем проект. Получаем сообщения об ошибках компиляции.

Сообщение об ошибках

Компилятор не нашел коды для методов класса. Мы не сообщили ему, где находится файл Debounce.cpp.

Можно поместить этот  файл в папку Src. Компилятор привык там искать исходные тексты. Но мы не будем ломать стройности проекта.

Сделаем так: Project -> Build Settings -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder -> Libraries -> OK

Atollic TrueStudio

 

Другой способ, немного проще:

Правой кнопкой по Libraries, Properties -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder -> Apply

Свершилось. Теперь компилируется без ошибок.

Вот ссылка на полный проект:

 

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!
 

 

Применение библиотеки.

Давайте в этом разделе научимся использовать готовые библиотеки. Повторим часть действий из первой половины урока.

Нам надо реализовать задачу – на каждое нажатие кнопки светодиод меняет свое состояние.

Мы собираемся воспользоваться готовой библиотекой Debounce.

Загружаем ее архив.

 

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!
 

В нем 2 файла в папке Debounce.

С помощью STM32CubeMX создаем проект Lesson14_2.

  • Устанавливаем конфигурацию системы тактирования.
  • Вывод PB13 конфигурируем на активный выход.
  • Вывод PB12 (кнопка) не трогаем.

Конвертируем проект в C++.

Создаем папку Libraries и копируем в нее папку Debounce с файлами библиотеки.

Задаем в IDE путь к библиотеке. Правой кнопкой по Libraries, Properties -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder -> Apply

Открываем main.cpp.

Подключаем библиотеку Debounce.

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "../Libraries/Debounce/Debounce.h"

Создаем объект button.

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

Debounce button(GPIOB, 1 << 12, 10); // экземпляр класса Debounce

Лучше запустить компиляцию, убедиться, что ошибок нет.

Теперь мы можем использовать объект button.

/* Infinite loop */
/* USER CODE BEGIN WHILE */

while (1)
{
    if(button.readFlagFalling() != 0)
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);

    button.scanAverage();
    HAL_Delay(1);
}

Все. Компилируем, загружаем в плату, проверяем.

Вот ссылка на проект:

 

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!
 

Папку Libraries со своим библиотеками удобно копировать в проект целиком, а не выбирать нужные библиотеки. Не подключенные директивой #include файлы компилироваться не будут.

 

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

 

Предыдущий урок     Список уроков     Следующий урок

0

Автор публикации

не в сети 7 часов

Эдуард

285
Комментарии: 1945Публикации: 197Регистрация: 13-12-2015

15 комментариев на «Урок 14. Создание и использование библиотек для STM32. Библиотека Debounce.»

      • Здравствуйте. А можно ли вынести в отдельное место папку libraries и просто указывать путь к ней в настройках проекта, а не копировать каждый раз? Например, библиотека в C:\libraries, а проекты в ..user\…\workspace. и в настройках прописывать путь C:\libraries. Если да,то какие плюсы и минусы

        0
        • Здравствуйте!
          При желании вы можете указать полный путь к библиотечным файлам, использую директиву include с двойными кавычками.

          0
  1. Invalid project path: Include path not found (LCD_I2C BOBR_STM32\#undef __ARM_FEATURE_SIMD32). да и ещё.Мне пишет ошибку.add folder-как добавить папку её не видно?

    0
  2. Здравствуйте. А если файлы Debounce.h и Debounce.cpp располагаются в разных директориях, то в «Project -> Build Settings -> Tool Settings -> C++ Compiler -> Directories -> Add» нужно добавлять обе директории для файлов?

    0
  3. И можно ли как то сделать что бы необходимые мне файлы подключались из указанной мной папки рекурсивно? т.е. к примеру если у нас много #include, и все они находятся в разных папках (при условии что все имена подключаемых файлов разные) сделать рекурсивный поиск и подключить все что нашло?

    0
  4. При добавлении новых путей в «Project -> Build Settings -> Tool Settings -> C++ Compiler -> Directories -> Add» где в файлах проекта хранится эта информация?

    0
  5. пробую добавить файлы библиотек с этого сайта .h .c в свой проект (stm32cubeide 1.3.0)
    указанные действия на мою логику не ложатся((
    все получается с ошибками, до этого работал только с АВР на си, сохдавал и добавлял файлы проектов, всегда было гладко и понятно, с ИДЕ для stm32 — черный ящик((

    0
  6. по привычке создал в папке— core/inc/myDelay.h
    core/src/myDelay.c
    и скопировал в файлы содержимое файлоф DelayDWT, добавил в main.c — myDelay.h
    После компиляции == ../Core/Src/main.c:31:10: fatal error: myDelay.h: No such file or directory
    #include «myDelay.h»

    0
  7. На всякий случай напишу если вдруг кто сталкивается с ошибкой из разряда unknown type name ‘class’.
    Подключать новосозданную библиотеку на с++ нужно только из файла main.cpp а не из main.h. Как пишут сами ST в этом файле может быть только Си код.
    Что бы добавить путь до своей библиотеки зайдите в Project/Properties -> C/C++ General -> Path and symbols и нажмите кнопку Add там уже сами разберетесь как хотите добавить путь/пути.
    PS заметил особенность если через функцию класса создать объект класса и инициализировать в нем сразу 2 пина то потом нужно нажать одновременно обе кнопки))

    0
  8. Выдаёт такой варнинг:
    Invalid project path: Include path not found (Lesson14-2\#undef __ARM_FEATURE_DSP).
    Где это убрать пока не нашёл. В дереве проекта папка Includes там есть эта строка, горит серым. Вроде всё компилит. Но с чем варнинг связан — непонятно. В скаченом проекте этого нет. Версия куба аналогичная. А вот ТS новее, но думается это не с ней связано. И да старый Куб что-то сам выгружаться не хочет, тоже не понятно.

    0
  9. Добрый день. Все сделал как в уроке Lesson14_2, однако компилятор выдает сообщение:

    17:51:06 **** Incremental Build of configuration Debug for project Lesson14_2 ****
    make -j4 all
    arm-none-eabi-g++ «../Core/Src/main.cpp» -mcpu=cortex-m3 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../Libraries/Debounce/ -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF»Core/Src/main.d» -MT»Core/Src/main.o» —specs=nano.specs -mfloat-abi=soft -mthumb -o «Core/Src/main.o»
    arm-none-eabi-g++ -o «Lesson14_2.elf» @»objects.list» -mcpu=cortex-m3 -T»C:\Users\Admin\STM32CubeIDE\workspace_1.10.1\Lesson14_2\STM32F103C8TX_FLASH.ld» -Wl,-Map=»Lesson14_2.map» -Wl,—gc-sections -static —specs=nano.specs -mfloat-abi=soft -mthumb -Wl,—start-group -lc -lm -lstdc++ -lsupc++ -Wl,—end-group
    C:/ST/STM32CubeIDE_1.10.1/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.11.3.rel1.win32_1.1.100.202309141235/tools/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: ./Core/Src/main.o: in function `__static_initialization_and_destruction_0(int, int)’:
    C:/Users/Admin/STM32CubeIDE/workspace_1.10.1/Lesson14_2/Debug/../Core/Src/main.cpp:50: undefined reference to `Debounce::Debounce(GPIO_TypeDef*, unsigned short, unsigned long)’
    collect2.exe: error: ld returned 1 exit status
    make: *** [makefile:88: Lesson14_2.elf] Error 1
    «make -j4 all» terminated with exit code 2. Build might be incomplete.

    17:51:08 Build Failed. 2 errors, 0 warnings. (took 1s.430ms)

    В чем может быть проблема? Уже все пересмотрел, ошибок не нашел.

    0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".