Обработка кнопок, EXTI[0]
Да, есть варианты. Но то, что можно читать вместе, лучше/и легче/ читать вместе (например состояние 3 пинов в одном порту).
- Реклама
Тут два варианта - или поштучно сканируем регистр данных на вопрос "ху из активен?" с последующей (также поштучной) обработкой обнаруженной активности (как последняя версия у aleksey chilov)
Или смахиваем все линии возврата клавиатуры в единый байт (проводим дополнительную обработку антидребезга и интервалов удержания/отсутствия активности) и декодируем комбинацию через switch/case где напрямую подставляются или исполнительные функции или указатели на те исполнительные функции.
Все зависит в том числе и от схемы да функционала программы устройства, для которого та программа пишется...

Или смахиваем все линии возврата клавиатуры в единый байт (проводим дополнительную обработку антидребезга и интервалов удержания/отсутствия активности) и декодируем комбинацию через switch/case где напрямую подставляются или исполнительные функции или указатели на те исполнительные функции.
Все зависит в том числе и от схемы да функционала программы устройства, для которого та программа пишется...
- Сообщения: 1856
- Зарегистрирован: Вт авг 15, 2017 10:51:13
[uquote="aleksey chilov",url="/forum/viewtopic.php?p=4648455#p4648455"]Gl.Registr = GPIOA->IDR;
switch(Gl.Registr){
case 0xFF76:
...[/uquote]Ужас....
Других слов нет. Складывается впечатление что вы вообще не понимаете что такое GPIO. Все советы - напрасны.
Добавлено after 9 minutes 43 seconds:
[uquote="Adrift",url="/forum/viewtopic.php?p=4648476#p4648476"]Очевидно, что я посчитал число строк исключая "f() {}", то есть только строки где идет работа с пинами. Код не мой, писал товарищ, могу спросить можно ли его выложить, надо? Впрочем, я его понимаю на 90%, большинство остальных поймут на 10% ) Ваша недооценка возможностей C++ пропорциональна его незнанию, еще и помноженная на скептицизм, в таком случае за подобной сложности код можно даже и не браться.[/uquote]Один пустой звон...
Я привёл код. Рабочий код. Который можно скомпилить и проверить. Который сам написал, а не стырил у какого-то "товарища". Раз я его написал - очевидно, что я его понимаю.
Вы приводите нечто невразумительное. Что ни проверить ни даже просто посмотреть - невозможно. И что очевидно и работать в принципе не может. И в чём сами же очевидно нифига не разбираетесь. При этом ещё сразу начинаете наезжать и пытаться чем-то меряться...
Что тут можно ещё сказать? По вашим постам всё ясно.
[uquote="Adrift",url="/forum/viewtopic.php?p=4648476#p4648476"]Очевидно, что я посчитал число строк исключая "f() {}", то есть только строки где идет работа с пинами. Код не мой, писал товарищ, могу спросить можно ли его выложить, надо? Впрочем, я его понимаю на 90%[/uquote]Чем докажете? Раз не можете сами написать, а тырите откуда-то - очевидно совершенно не понимаете.
Я точно также могу про вас сказать - что вы нифига не понимаете вообще си, поэтому тырите чужие примеры.
[uquote="Adrift",url="/forum/viewtopic.php?p=4648476#p4648476"]
В данном случае у нас 3 подряд идущих пина, а может быть 30, с разных портов, в любом порядке, и этот мой код продолжит работать без никаких модификаций. То что результат выглядит как простое чтение из порта с накладыванием маски и записью обратно лишь подтверждает оптимизирующую природу используемого алгоритма...[/uquote]Полный бред...
Вы даже не понимаете что такое GPIO и как он работает.
Как можно что-то читать (состояние кнопок) с пинов "настроенных на вывод"???
Дальнейший ваш бред не вижу смысла даже читать... Ни работы микроконтроллера не понимаете ни в си не разбираетесь...
Добавлено after 5 minutes 35 seconds:
[uquote="aleksey chilov",url="/forum/viewtopic.php?p=4648657#p4648657"]Теперь критика ваша, жду...[/uquote]После всего написанного совет только один: Обратиться в раздел "Предлагаю работу".
switch(Gl.Registr){
case 0xFF76:
...[/uquote]Ужас....
Добавлено after 9 minutes 43 seconds:
[uquote="Adrift",url="/forum/viewtopic.php?p=4648476#p4648476"]Очевидно, что я посчитал число строк исключая "f() {}", то есть только строки где идет работа с пинами. Код не мой, писал товарищ, могу спросить можно ли его выложить, надо? Впрочем, я его понимаю на 90%, большинство остальных поймут на 10% ) Ваша недооценка возможностей C++ пропорциональна его незнанию, еще и помноженная на скептицизм, в таком случае за подобной сложности код можно даже и не браться.[/uquote]Один пустой звон...
Я привёл код. Рабочий код. Который можно скомпилить и проверить. Который сам написал, а не стырил у какого-то "товарища". Раз я его написал - очевидно, что я его понимаю.
Вы приводите нечто невразумительное. Что ни проверить ни даже просто посмотреть - невозможно. И что очевидно и работать в принципе не может. И в чём сами же очевидно нифига не разбираетесь. При этом ещё сразу начинаете наезжать и пытаться чем-то меряться...
Что тут можно ещё сказать? По вашим постам всё ясно.
[uquote="Adrift",url="/forum/viewtopic.php?p=4648476#p4648476"]Очевидно, что я посчитал число строк исключая "f() {}", то есть только строки где идет работа с пинами. Код не мой, писал товарищ, могу спросить можно ли его выложить, надо? Впрочем, я его понимаю на 90%[/uquote]Чем докажете? Раз не можете сами написать, а тырите откуда-то - очевидно совершенно не понимаете.
Я точно также могу про вас сказать - что вы нифига не понимаете вообще си, поэтому тырите чужие примеры.
[uquote="Adrift",url="/forum/viewtopic.php?p=4648476#p4648476"]
Это же пример, скучно просто читать с порта ) Естественно пины были сконфигурированы на вывод.jcxz писал(а):код этот ваш делает следующую операцию:Какое отношение это имеет к теме опроса ног - вообще непонятно....Код: Выделить всё
u32 *p = ...; p[6] = ~p[4] & 0xE0 | 0xE00000;![]()
Также очевидно, что ноги подключенные к кнопкам, настроены на ввод. Какой смысл в них что-то писать? Что это даст?
В данном случае у нас 3 подряд идущих пина, а может быть 30, с разных портов, в любом порядке, и этот мой код продолжит работать без никаких модификаций. То что результат выглядит как простое чтение из порта с накладыванием маски и записью обратно лишь подтверждает оптимизирующую природу используемого алгоритма...[/uquote]Полный бред...
Как можно что-то читать (состояние кнопок) с пинов "настроенных на вывод"???
Дальнейший ваш бред не вижу смысла даже читать... Ни работы микроконтроллера не понимаете ни в си не разбираетесь...
Добавлено after 5 minutes 35 seconds:
[uquote="aleksey chilov",url="/forum/viewtopic.php?p=4648657#p4648657"]Теперь критика ваша, жду...[/uquote]После всего написанного совет только один: Обратиться в раздел "Предлагаю работу".
Вобщем...
Обсуждать кнопки, о схемном решении и задачах которых ничего неизвестно - равноценно бесконечному гаданию.
Решения удобные в одном случае будут "костылями" в другом.
Конкретно схема, что хотим от тех кнопок получить... Плюс учитываем остальную часть программы, в которой те кнопы использовать намерены...

Обсуждать кнопки, о схемном решении и задачах которых ничего неизвестно - равноценно бесконечному гаданию.
Решения удобные в одном случае будут "костылями" в другом.
Конкретно схема, что хотим от тех кнопок получить... Плюс учитываем остальную часть программы, в которой те кнопы использовать намерены...
- Сообщения: 626
- Зарегистрирован: Вт окт 01, 2024 15:22:33
[uquote="jcxz",url="/forum/viewtopic.php?p=4649371#p4649371"]Один пустой звон...
Я привёл код. Рабочий код. Который можно скомпилить и проверить. Который сам написал, а не стырил у какого-то "товарища". Раз я его написал - очевидно, что я его понимаю.[/uquote]
Вы мне морочили голову убеждая, что макросы могут сделать то что я хочу, в итоге оказалось, что все нужно писать ручками. 30 строк кода только для чтения IDR в переменные, если предполагается использование любого из десятка портов, а чтение битиков вы даже не стали дописывать, то есть реально код еще больше. Никто так делать не станет, любой нормальный человек просто прочитает 3 раза с порта.
После этого стандарт C++ 5 раз существенно обновлялся и cейчас у меня read() выглядит так:
Где ports_ это:
А, например, unique() это:
Ну и помогла вам частичка кода? Склеивайте свои макросы в 2024 году и дальше, оставьте передовые технологии тем кто хотя бы хочет научиться чему-то новому )
Я привёл код. Рабочий код. Который можно скомпилить и проверить. Который сам написал, а не стырил у какого-то "товарища". Раз я его написал - очевидно, что я его понимаю.[/uquote]
Вы мне морочили голову убеждая, что макросы могут сделать то что я хочу, в итоге оказалось, что все нужно писать ручками. 30 строк кода только для чтения IDR в переменные, если предполагается использование любого из десятка портов, а чтение битиков вы даже не стали дописывать, то есть реально код еще больше. Никто так делать не станет, любой нормальный человек просто прочитает 3 раза с порта.
Что не может работать? Смотрите, 2010 год, либа для AVR, да на старом С++, да не настолько эффективна, но работает и уже можно было писать код типа:jcxz писал(а):Вы приводите нечто невразумительное. Что ни проверить ни даже просто посмотреть - невозможно. И что очевидно и работать в принципе не может. И в чём сами же очевидно нифига не разбираетесь. При этом ещё сразу начинаете наезжать и пытаться чем-то меряться...
Код: Выделить всё
typedef PinList<Pa1, Pa2, Pa3, Pb3, Pb4> MyPins;
MyPins::Write(0x55);Код: Выделить всё
static uint32_t _inline_ read()
{
return ports_.accumulate(readDummy(pins_), [](auto port) __inline__ {
return readWrite<PinShift::Read>(GpioT<unbox<port>::port, 0xFFFF>::read(), getIndexedPins<unbox<port>::port>(pins_)); });
}Код: Выделить всё
static constexpr auto pins_ = TypeList<Pins...>::accumulate(TypeList<>{}, [](auto pin) { return expandPL<unbox<pin>>(); });
static constexpr auto realPins_ = pins_.remove([](auto pin) { return IsDummyPin<unbox<pin>>; });
static constexpr auto ports_ = realPins_.unique([](auto pin1, auto pin2) { return unbox<pin1>::port == unbox<pin2>::port; });Спойлер
Код: Выделить всё
static consteval auto unique(auto pred) { return unique_(pred, TypeList<Ts...>{}); }
template<typename... In, typename... Out>
static consteval auto unique_(auto pred, TypeList<In...> in, TypeList<Out...> out = {})
{
if constexpr (in.empty())
{
return out;
}
else
{
if constexpr (!out.contains(in.head(), pred))
return unique_(pred, in.tail(), out.pushBack(in.head()));
else
return unique_(pred, in.tail(), out);
}
}Я не мог бы написать с нуля, но когда увидел как это работает, то думаю может чуть похуже, но могу и написать, по крайней мере на rp2350 портировать смог. А вы сейчас даже не можете поверить, что такое в принципе возможно )jcxz писал(а):Чем докажете? Раз не можете сами написать, а тырите откуда-то - очевидно совершенно не понимаете.
Я настроил на вывод, предварительно выполнив write(0b010) и проверил, что после write(~read()) в битах 7..5 порта оказывается 0b101, значит в том числе и чтение работает правильно. Пример демонстрировал работу с портами, одной строкой можно не только прочитать, но и записать, а если нужно только читать состояние кнопок, то настраиваем порты на вход и читаем, какие проблемы...jcxz писал(а):Полный бред...Вы даже не понимаете что такое GPIO и как он работает.
Как можно что-то читать (состояние кнопок) с пинов "настроенных на вывод"???
- Реклама
Насколько я понимаю С++ для АВРок прерогатива ардуиноIDE...
Так там уже свои "добавки" в референсе, коих вполне достаточно для работы...
Зачем изворачиваться то? Чтоб потом долго вспоминать чего в прошлом месяце нашкарябано (и то с учётом всех "сопутствующих библиотек") или чтоб вражины долго выуживали истинное назначение написанного?

Так там уже свои "добавки" в референсе, коих вполне достаточно для работы...
Зачем изворачиваться то? Чтоб потом долго вспоминать чего в прошлом месяце нашкарябано (и то с учётом всех "сопутствующих библиотек") или чтоб вражины долго выуживали истинное назначение написанного?
- Сообщения: 1856
- Зарегистрирован: Вт авг 15, 2017 10:51:13
[uquote="Adrift",url="/forum/viewtopic.php?p=4649417#p4649417"]Вы мне морочили голову убеждая, что макросы могут сделать то что я хочу, в итоге оказалось, что все нужно писать ручками. 30 строк кода только для чтения IDR в переменные, если предполагается использование любого из десятка портов, а чтение битиков вы даже не стали дописывать, то есть реально код еще больше.[/uquote]"30 строк кода" это что - много что-ль?
А сколько строк в тех си++ обёртках, что вы не показали?
[uquote="Adrift",url="/forum/viewtopic.php?p=4649417#p4649417"]Никто так делать не станет, любой нормальный человек просто прочитает 3 раза с порта.[/uquote]А человеки, использующие HAL по вашему - нормальные? А ведь в файлах HAL там не "30 строчек", а ГОРАЗДО больше! Может и все 30 тысяч строк.
"Любого нормального человека" такой объём не напрягает? Почему тогда "30 строк" напрягают?
А сколько строк в тех си++ обёртках, что вы не показали?
[uquote="Adrift",url="/forum/viewtopic.php?p=4649417#p4649417"]Никто так делать не станет, любой нормальный человек просто прочитает 3 раза с порта.[/uquote]А человеки, использующие HAL по вашему - нормальные? А ведь в файлах HAL там не "30 строчек", а ГОРАЗДО больше! Может и все 30 тысяч строк.
"Любого нормального человека" такой объём не напрягает? Почему тогда "30 строк" напрягают?
Обещаный черновик на 4 кнопы для адуринкоАВРки(нанка)... правда демка там примитивнейшая....
https://radiokot.ru/forum/viewtopic.php ... 6#p4649536
Ибо... ЛЕЕЕНЬ....

https://radiokot.ru/forum/viewtopic.php ... 6#p4649536
Ибо... ЛЕЕЕНЬ....
Кнопки коммутируются на землю.
Завожу systick на 0,1сек. В обработчике читаю key = ((~GPIOA->IDR)>>5) & 0x07;
В основном цикле switch. Все.
И по дребезгу. Если нажатие не сработает - сработает через 0,1сек. А когда сработало - отпускаю или держу для повтора.
Если добавить счетчик можно обрабатывать и долгие нажатия, выключение например.
Завожу systick на 0,1сек. В обработчике читаю key = ((~GPIOA->IDR)>>5) & 0x07;
В основном цикле switch. Все.
И по дребезгу. Если нажатие не сработает - сработает через 0,1сек. А когда сработало - отпускаю или держу для повтора.
Если добавить счетчик можно обрабатывать и долгие нажатия, выключение например.
- Сообщения: 626
- Зарегистрирован: Вт окт 01, 2024 15:22:33
[uquote="jcxz",url="/forum/viewtopic.php?p=4649535#p4649535"]30 строк кода" это что - много что-ль?
А сколько строк в тех си++ обёртках, что вы не показали?[/uquote]
В C++ обертках кода много, однако когда ими пользуешься, то написать придется всего несколько строк. Одной строкой описал используемые пины, другой прочел значение с порта, третьей можно настроить режим всех пинов сразу. Потом будет какой-нибудь дисплей с 8/16 битной шиной и точно так же можно передать все пины одной строкой, внутри записать все данные вместе с RS и WR, т.е. 10 или 18 бит, одной write(). Все оптимизировано и протестировано, написав несколько строк тяжело накосячить. Теперь возвращаемся к вашему варианту... Я посчитал, что на моих STM32 максимум 8 разных портов может быть, соответственно получаем такое:
Это ведь не универсальный код, он написан конкретно для 3 кнопок и привязан к пинам этих кнопок, сколько здесь мест в которых можно ошибиться? И как его дописать чтобы f() делала то же, что моя:
Мало прочитать из порта в переменные, дальше что? ) Возьмем первую ветку:
Если мы попали внутрь, значит одна, две или три кнопки висят на этом порту, будет проверять все три по отдельности и переносить биты? Для каждого порта? Сколько десятков строк будет занимать законченная версия? )
А сколько строк в тех си++ обёртках, что вы не показали?[/uquote]
В C++ обертках кода много, однако когда ими пользуешься, то написать придется всего несколько строк. Одной строкой описал используемые пины, другой прочел значение с порта, третьей можно настроить режим всех пинов сразу. Потом будет какой-нибудь дисплей с 8/16 битной шиной и точно так же можно передать все пины одной строкой, внутри записать все данные вместе с RS и WR, т.е. 10 или 18 бит, одной write(). Все оптимизировано и протестировано, написав несколько строк тяжело накосячить. Теперь возвращаемся к вашему варианту... Я посчитал, что на моих STM32 максимум 8 разных портов может быть, соответственно получаем такое:
Спойлер
Код: Выделить всё
//.h
#define PIN_BUTTON1 A, 7
#define PIN_BUTTON2 A, 6
#define PIN_BUTTON3 A, 5
//.cpp
#define PIOIX_A 0
#define PIOIX_B 1
#define PIOIX_C 2
#define PIOIX_D 3
#define PIOIX_E 4
#define PIOIX_F 5
#define PIOIX_G 6
#define PIOIX_H 7
#define PORT_IX2(port, pin) PIOIX_##port
#define PORT_IX(port_pin) PORT_IX2(port_pin)
#define BTN_PORT_MAP (1u << PORT_IX(PIN_BUTTON1) | 1u << PORT_IX(PIN_BUTTON2) | 1u << PORT_IX(PIN_BUTTON3))
void f()
{
#if BTN_PORT_MAP & 1 << 0
uint iA = GPIOA->IDR;
#endif
#if BTN_PORT_MAP & 1 << 1
uint iB = GPIOB->IDR;
#endif
#if BTN_PORT_MAP & 1 << 2
uint iC = GPIOC->IDR;
#endif
#if BTN_PORT_MAP & 1 << 3
uint iD = GPIOD->IDR;
#endif
#if BTN_PORT_MAP & 1 << 4
uint iE = GPIOE->IDR;
#endif
#if BTN_PORT_MAP & 1 << 5
uint iF = GPIOF->IDR;
#endif
#if BTN_PORT_MAP & 1 << 6
uint iG = GPIOG->IDR;
#endif
#if BTN_PORT_MAP & 1 << 7
uint iH = GPIOH->IDR;
#endif
......
}Код: Выделить всё
uint32_t val = pins.read();Код: Выделить всё
#if BTN_PORT_MAP & 1 << 0
uint iA = GPIOA->IDR;
#endifЧеловеки пользуются HAL потому что он уже написан и сколько там тысяч строк для них не имеет значения. Разницу между сложностью написания библиотек и сложностью их использования не видите?jcxz писал(а):А человеки, использующие HAL по вашему - нормальные? А ведь в файлах HAL там не "30 строчек", а ГОРАЗДО больше! Может и все 30 тысяч строк.
"Любого нормального человека" такой объём не напрягает? Почему тогда "30 строк" напрягают?
- Сообщения: 167
- Зарегистрирован: Вс мар 27, 2022 09:38:17


