Обработка кнопок, EXTI[0]

Кто любит RISC в жизни, заходим, не стесняемся.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15569
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Обработка кнопок, EXTI[0]

Сообщение BOB51 »

Тут два варианта - или поштучно сканируем регистр данных на вопрос "ху из активен?" с последующей (также поштучной) обработкой обнаруженной активности (как последняя версия у aleksey chilov)
Или смахиваем все линии возврата клавиатуры в единый байт (проводим дополнительную обработку антидребезга и интервалов удержания/отсутствия активности) и декодируем комбинацию через switch/case где напрямую подставляются или исполнительные функции или указатели на те исполнительные функции.
Все зависит в том числе и от схемы да функционала программы устройства, для которого та программа пишется...
:roll:
Реклама
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Обработка кнопок, EXTI[0]

Сообщение jcxz »

[uquote="aleksey chilov",url="/forum/viewtopic.php?p=4648455#p4648455"]Gl.Registr = GPIOA->IDR;
switch(Gl.Registr){
case 0xFF76:
...[/uquote]Ужас.... :facepalm: Других слов нет. Складывается впечатление что вы вообще не понимаете что такое 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"]
jcxz писал(а):код этот ваш делает следующую операцию:

Код: Выделить всё

u32 *p = ...;
p[6] = ~p[4] & 0xE0 | 0xE00000;
Какое отношение это имеет к теме опроса ног - вообще непонятно.... :dont_know:
Также очевидно, что ноги подключенные к кнопкам, настроены на ввод. Какой смысл в них что-то писать? Что это даст?
Это же пример, скучно просто читать с порта ) Естественно пины были сконфигурированы на вывод.
В данном случае у нас 3 подряд идущих пина, а может быть 30, с разных портов, в любом порядке, и этот мой код продолжит работать без никаких модификаций. То что результат выглядит как простое чтение из порта с накладыванием маски и записью обратно лишь подтверждает оптимизирующую природу используемого алгоритма...[/uquote]Полный бред... :facepalm: Вы даже не понимаете что такое GPIO и как он работает.
Как можно что-то читать (состояние кнопок) с пинов "настроенных на вывод"???
Дальнейший ваш бред не вижу смысла даже читать... Ни работы микроконтроллера не понимаете ни в си не разбираетесь...

Добавлено after 5 minutes 35 seconds:
[uquote="aleksey chilov",url="/forum/viewtopic.php?p=4648657#p4648657"]Теперь критика ваша, жду...[/uquote]После всего написанного совет только один: Обратиться в раздел "Предлагаю работу".
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15569
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Обработка кнопок, EXTI[0]

Сообщение BOB51 »

Вобщем...
Обсуждать кнопки, о схемном решении и задачах которых ничего неизвестно - равноценно бесконечному гаданию.
Решения удобные в одном случае будут "костылями" в другом.
Конкретно схема, что хотим от тех кнопок получить... Плюс учитываем остальную часть программы, в которой те кнопы использовать намерены...
:roll:
Adrift
Вымогатель припоя
Сообщения: 543
Зарегистрирован: Вт окт 01, 2024 15:22:33

Re: Обработка кнопок, EXTI[0]

Сообщение Adrift »

[uquote="jcxz",url="/forum/viewtopic.php?p=4649371#p4649371"]Один пустой звон...
Я привёл код. Рабочий код. Который можно скомпилить и проверить. Который сам написал, а не стырил у какого-то "товарища". Раз я его написал - очевидно, что я его понимаю.[/uquote]
Вы мне морочили голову убеждая, что макросы могут сделать то что я хочу, в итоге оказалось, что все нужно писать ручками. 30 строк кода только для чтения IDR в переменные, если предполагается использование любого из десятка портов, а чтение битиков вы даже не стали дописывать, то есть реально код еще больше. Никто так делать не станет, любой нормальный человек просто прочитает 3 раза с порта.
jcxz писал(а):Вы приводите нечто невразумительное. Что ни проверить ни даже просто посмотреть - невозможно. И что очевидно и работать в принципе не может. И в чём сами же очевидно нифига не разбираетесь. При этом ещё сразу начинаете наезжать и пытаться чем-то меряться...
Что не может работать? Смотрите, 2010 год, либа для AVR, да на старом С++, да не настолько эффективна, но работает и уже можно было писать код типа:

Код: Выделить всё

typedef PinList<Pa1, Pa2, Pa3, Pb3, Pb4> MyPins;
MyPins::Write(0x55);
После этого стандарт C++ 5 раз существенно обновлялся и cейчас у меня read() выглядит так:

Код: Выделить всё

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_)); });
}
Где ports_ это:

Код: Выделить всё

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; });
А, например, unique() это:
Спойлер

Код: Выделить всё

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);
	}
}
Ну и помогла вам частичка кода? Склеивайте свои макросы в 2024 году и дальше, оставьте передовые технологии тем кто хотя бы хочет научиться чему-то новому )
jcxz писал(а):Чем докажете? Раз не можете сами написать, а тырите откуда-то - очевидно совершенно не понимаете.
Я не мог бы написать с нуля, но когда увидел как это работает, то думаю может чуть похуже, но могу и написать, по крайней мере на rp2350 портировать смог. А вы сейчас даже не можете поверить, что такое в принципе возможно )
jcxz писал(а):Полный бред... :facepalm: Вы даже не понимаете что такое GPIO и как он работает.
Как можно что-то читать (состояние кнопок) с пинов "настроенных на вывод"???
Я настроил на вывод, предварительно выполнив write(0b010) и проверил, что после write(~read()) в битах 7..5 порта оказывается 0b101, значит в том числе и чтение работает правильно. Пример демонстрировал работу с портами, одной строкой можно не только прочитать, но и записать, а если нужно только читать состояние кнопок, то настраиваем порты на вход и читаем, какие проблемы...
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15569
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Обработка кнопок, EXTI[0]

Сообщение BOB51 »

Насколько я понимаю С++ для АВРок прерогатива ардуиноIDE...
Так там уже свои "добавки" в референсе, коих вполне достаточно для работы...
:dont_know:
Зачем изворачиваться то? Чтоб потом долго вспоминать чего в прошлом месяце нашкарябано (и то с учётом всех "сопутствующих библиотек") или чтоб вражины долго выуживали истинное назначение написанного?
8)
Реклама
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Обработка кнопок, EXTI[0]

Сообщение jcxz »

[uquote="Adrift",url="/forum/viewtopic.php?p=4649417#p4649417"]Вы мне морочили голову убеждая, что макросы могут сделать то что я хочу, в итоге оказалось, что все нужно писать ручками. 30 строк кода только для чтения IDR в переменные, если предполагается использование любого из десятка портов, а чтение битиков вы даже не стали дописывать, то есть реально код еще больше.[/uquote]"30 строк кода" это что - много что-ль? :shock:
А сколько строк в тех си++ обёртках, что вы не показали?
[uquote="Adrift",url="/forum/viewtopic.php?p=4649417#p4649417"]Никто так делать не станет, любой нормальный человек просто прочитает 3 раза с порта.[/uquote]А человеки, использующие HAL по вашему - нормальные? А ведь в файлах HAL там не "30 строчек", а ГОРАЗДО больше! Может и все 30 тысяч строк.
"Любого нормального человека" такой объём не напрягает? Почему тогда "30 строк" напрягают? 8)
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15569
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Обработка кнопок, EXTI[0]

Сообщение BOB51 »

Обещаный черновик на 4 кнопы для адуринкоАВРки(нанка)... правда демка там примитивнейшая....
https://radiokot.ru/forum/viewtopic.php ... 6#p4649536
Ибо... ЛЕЕЕНЬ....
:sleep:
Sergi
Мучитель микросхем
Сообщения: 412
Зарегистрирован: Ср янв 04, 2012 11:57:40
Откуда: Алчевск

Re: Обработка кнопок, EXTI[0]

Сообщение Sergi »

Кнопки коммутируются на землю.
Завожу systick на 0,1сек. В обработчике читаю key = ((~GPIOA->IDR)>>5) & 0x07;
В основном цикле switch. Все.
И по дребезгу. Если нажатие не сработает - сработает через 0,1сек. А когда сработало - отпускаю или держу для повтора.
Если добавить счетчик можно обрабатывать и долгие нажатия, выключение например.
Adrift
Вымогатель припоя
Сообщения: 543
Зарегистрирован: Вт окт 01, 2024 15:22:33

Re: Обработка кнопок, EXTI[0]

Сообщение Adrift »

[uquote="jcxz",url="/forum/viewtopic.php?p=4649535#p4649535"]30 строк кода" это что - много что-ль? :shock:
А сколько строк в тех си++ обёртках, что вы не показали?[/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

  ......
}
Это ведь не универсальный код, он написан конкретно для 3 кнопок и привязан к пинам этих кнопок, сколько здесь мест в которых можно ошибиться? И как его дописать чтобы f() делала то же, что моя:

Код: Выделить всё

uint32_t val = pins.read();
Мало прочитать из порта в переменные, дальше что? ) Возьмем первую ветку:

Код: Выделить всё

  #if BTN_PORT_MAP & 1 << 0
  uint iA = GPIOA->IDR;
  #endif
Если мы попали внутрь, значит одна, две или три кнопки висят на этом порту, будет проверять все три по отдельности и переносить биты? Для каждого порта? Сколько десятков строк будет занимать законченная версия? )
jcxz писал(а):А человеки, использующие HAL по вашему - нормальные? А ведь в файлах HAL там не "30 строчек", а ГОРАЗДО больше! Может и все 30 тысяч строк.
"Любого нормального человека" такой объём не напрягает? Почему тогда "30 строк" напрягают? 8)
Человеки пользуются HAL потому что он уже написан и сколько там тысяч строк для них не имеет значения. Разницу между сложностью написания библиотек и сложностью их использования не видите?
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Обработка кнопок, EXTI[0]

Сообщение Martian »

эк куда вас всех занесло...
а я вот решил глянуть - а всё-таки есть генераторы меню, вот, первая попавшаяся ссылка: https://github.com/forntoh/LcdMenu здесь примерчиков кучка: https://lcdmenu.forntoh.dev/reference/s ... index.html
aleksey chilov
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Вс мар 27, 2022 09:38:17

Re: Обработка кнопок, EXTI[0]

Сообщение aleksey chilov »

Спасибо
Ответить

Вернуться в «ARM»