В своё время я наткнулся на сайт Гайвера, и мне подарили Arduino NANO. Я почитал его статьи. Поморгал диодом и бросил всё это дело. Тогда я программировал на ASM под PIC контроллеры и для меня было мучением найти или разработать простейшие библиотеки. Работа с кнопками, дисплеями и т. д. Купил несколько Ардуин и быстро наваял проекты, мне понравилось, насколько просто и логично можно пользоваться библиотеками. Зарегистрировался на сайте и стал мониторить форум. Немного выполнил заказов и на одном сильно споткнулся. Не тянет Ардуинка, да и сама логика этих МК мне не нравилась. Тут мне подогнали STM32F050, и я поразился, какая мощь в этом невзрачном квадратике, после чего начал изучать STM. Но под HAL мне не хватало того, что можно было сделать на Ардуине - классов. Сначала я скрестил HAL и классы. Но HAL жрёт очень много и очень медлителен, поэтому я решил полностью перейти на CMSIS и классы. Но из-за сложности периферии пока не получается это сделать. Я списался с Гайвером и предложил создать ветку про STM, где я буду выкладывать его библиотеки переделанные под STM. Но эта тема там не встретила понимания. Правда у меня осталось согласие Гайвера на использование его кода, чем я и воспользуюсь, так что выкладываю одну из своих первых переделок.
Библиотека GyverButton, переделанная под STM и названная SButton.
Эта библиотека им больше не поддерживается, но она должна быть вылизана до упора. Он продолжил работу над этой библиотекой, но она называется по-другому и работает также с энкодерами. Но при этом она умеет работать только с кнопками и энкодерами, которые замыкаются на землю. Но есть задачи, которые требуют, чтобы кнопка изначально подключалась к питанию и работала с МК подачей питания на управляемый вход.
Небольшое отступление: в самом МК есть подтяжка входов к земле и к питанию. Данная возможность очень хороша для отладки на макетке, но в конечном устройстве лучше использовать внешнюю схему подтяжки и подавления дребезга. Так как наводки в промышленном использовании не дремлют и могут неплохо попортить нервы. Схема подтяжки с подавлением дребезга весьма проста:
Переименовываем оба файла в SButton. Внутри заголовочного файла и файла с кодом исправляем GButton
на SButton
, в описании структуры GyverButtonFlags
правим на SButtonFlags
. Все переменные boolean
исправляем на bool
.
Теперь из библиотеки Гайвера нам нужно убрать элементы, относящиеся к Ардуино, и добавить или переделать некоторые функции под STM:
#ifndef GyverButton_h #define GyverButton_h #include <Arduino.h> #if defined(__AVR__) #define _buttonRead() bool(*_pin_reg & _bit_mask) #else #define _buttonRead() digitalRead(_PIN) #endif
Убираем этот кусок вообще и вместо него пишем:
#ifndef _SBUTTON_H #define _SBUTTON_H #include "STM32.h" #include <gpio_main.h>
В файле заголовка переписываем конструктор:
GButton(int8_t pin = BTN_NO_PIN, bool type = HIGH_PULL, bool dir = NORM_OPEN);
Делаем его таким:
SButton(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN, bool type, bool dir);
И в разделе private добавляем пару своих переменных:
private: GPIO_TypeDef *_GPIOx_IN; uint16_t _GPIO_Pin_IN;
Теперь берёмся за файл, содержащий сами функции работы с кнопками. Заменяем include
и конструктор:
#include "GyverButton.h" // ==================== CONSTRUCTOR ==================== GButton::GButton(int8_t pin, bool type, bool dir) { if(pin != BTN_NO_PIN) { _PIN = (uint8_t) pin; flags.noPin = false; } else { flags.noPin = true; } setType(type); flags.mode = false; flags.tickMode = false; flags.inv_state = dir; }
на наш конструктор:
// ==================== CONSTRUCTOR ==================== SButton::SButton(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN, bool type, bool dir) { _GPIOx_IN = GPIOx; _GPIO_Pin_IN = GPIO_PIN; flags.noPin = false; if(type) _SetPin(_GPIOx_IN, _GPIO_Pin_IN, Input, Pull_Down); else _SetPin(_GPIOx_IN, _GPIO_Pin_IN, Input, Pull_Up); flags.type = type; flags.mode = false; flags.tickMode = true; //false; flags.inv_state = dir; }
Здесь мы инициализируем ранее введённые нами переменные и вызываем ранее написанные функции инициализации порта. Обратите внимание на flags.tickMode = true
, в отличие от оригинала, мы устанавливаем флаг в другое значение. Мне показалось, что так будет удобнее пользоваться инициализацией. Эта переменная заставляет опрашивать клавиатуру автоматически, при любом обращении к классу. Если это будет не нужно, можно будет уже в самой функции main()
отключить эту возможность и инициировать опрос вручную.
Нам осталось только заменить в функции чтения порта void GButton::tick()
одну строчку на свою:
// читаем пин if(!flags.mode && !flags.noPin) btn_state = !_buttonRead() ^ (flags.inv_state ^ flags.type);
Изменяем на:
// читаем пин if(!flags.mode && !flags.noPin) btn_state = !_DigitalReadBit(_GPIOx_IN, _GPIO_Pin_IN) ^ (flags.inv_state ^ flags.type);
Вот и всё, библиотека готова, можно пользоваться. Пример в каталоге WorkDevel\Developer\Tests MK\F407\F407VExx_Button. Как всегда исходники на Яндекс диске и архивом WorkDevel. Кроме этого добавлены исходники библиотеки Гайвера в каталог WorkDevel\Developer\Source.
Особая благодарность владельцу ресурса https://alexgyver.ru!
Тема на форуме - перейти.