Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/103: Рейтинг темы: голосов - 103, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 21

Кнопки

17.11.2012, 21:20. Показов 19684. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Прошу прощения, прямо не знаю в какой раздел идти,
Но раз делаю на STM32..
Обычно в мобильных? устройствах кнопок мало и на каждую возлагают много функций.
Соответственно требуется определять манипуляции разного рода .
Говоря про одну кнопку для себя я решил выделять следующие события:
1 нажата коротко "Click"
2 Отпущена после коротко "Off_Click"
3 Дабл клик
4 Отпущена после Дабл клик
5 Нажата Долго
6 Отпущена после Долго.
Написал с использованием SysTick и двух счетчиков на кнопку ( завтра выложу)
Но Дабл клик ловится плоховато да и вообще выгляди все корявенько.
Может подскажите примеры реализации подобного?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.11.2012, 21:20
Ответы с готовыми решениями:

Кнопки в контроллере - STM32VLDiscovery
Всем привет! :) Я недавно приобрёл очень интересную плату - STM32VLDyscovery, и уже научился мигать светодиодом. Но как только я решил...

Обработка тактовой кнопки
Вобщем решил поднять тему обработки тактовых кнопок. Какое самое лучшее решение и кто как подключает и обрабатывает процесс. Микросхемы...

Вибрация аналоговой кнопки
Здравствуйте ! Делаю проект на основе платы STM32L152RE. На данном этапе при нажатии внешней аналоговой кнопки должны попеременно...

24
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
18.11.2012, 07:50
Цитата Сообщение от Vovo_Oz
Прошу прощения, прямо не знаю в какой раздел идти,
Но раз делаю на STM32..
Обычно в мобильных? устройствах кнопок мало и на каждую возлагают много функций.
Соответственно требуется определять манипуляции разного рода .
Говоря про одну кнопку для себя я решил выделять следующие события:
1 нажата коротко "Click"
2 Отпущена после коротко "Off_Click"
3 Дабл клик
4 Отпущена после Дабл клик
5 Нажата Долго
6 Отпущена после Долго.
Написал с использованием SysTick и двух счетчиков на кнопку ( завтра выложу)
Но Дабл клик ловится плоховато да и вообще выгляди все корявенько.
Может подскажите примеры реализации подобного?
Показывай, посмотрим. Однако мне кажется что дабл клик это бред.
0
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.11.2012, 13:36
Отловить можно и трипл-клик. Проблема немного в другом, как все это использовать вместе.
Например, если хотим использовать клик и дабл-клик, то определить, что был одиночный клик можно только после некоторого таймаута, который собственно и определяет, это два разных клика или дабл. Представляешь этот интерфейс - ты нажал, отпустил, и только через полсекунды что-то произошло.

В компе с мышью проблем меньше, потому что чаще всего одиночный клик - это выбор, а двойной - это выбор и выполнение. Поэтому по одиночному клику всегда выполняем выбор, а если вдруг придет второй клик ранее определенного интервала, то тогда и запустим заодно.

В мобильном приложении на кнопках сложно найти такую пару действий, которые можно совместит на клик-дабл-клик

То же самое с долгим нажатием. Либо действия будут выполнятся при отпускании кнопки, что тоже не всегда воспринимается, либо надо искать такую же пару действий. Я использую долгое нажатие как автоповтор, например при выборе значений. При этом при нажатии кнопки значение меняется на единичку, если кнопку удерживать, то через секунду значения продолжат изменяться. Тут интуитивно понятно. А если нажал, значение изменилось, продолжаешь удерживать и выпадаешь в меню, то возникнет резонный вопрос - а сохранилось ли значение, а если сохранилось, то как попасть в меню без изменения и т.д.

Кстати, сталкивался с электронными сигаретами, там выбор функций происходит многократными нажатиями. Например однократное нажатие (длительное) - курить, двойное - выбор напряжения, тройное - блокировка, четверное - посмотреть напряжение аккума и т.д.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 21
18.11.2012, 17:54
Вот обещаннйе файлы в архиве.
Сразу хочу сказать, это это вырезки про кнопку .
Сами файлы много больше и пока напоминаюют бред тяжелобольного.
Сам я далеко не программист --> язык знаю плохо, так что....
Что касается строк типа put_string(28,20,"?? ",0xAFE0,0x0000,1)--- это функции вывода
надписей на экран от сотового, который "прикручен" к SPI2 и 3 GPIO STM32F100C8T6.
Все работает, но Дабл клик тяжело нажать и в прерывании как-то много кода... или нет?
Предполагаются 4 кнопки.

[1.88 Кб]
0
ovr495
19.11.2012, 00:11
Цитата Сообщение от Vovo_Oz
Прошу прощения, прямо не знаю в какой раздел идти,
Может подскажите примеры реализации подобного?
Вне зависимости от типа контроллера, рекомендую использовать конечные автоматы: отладка обычно не требуется и идея, если она правильная, работает сразу после перенесения автомата в программу. Здесь хорошо расписано: http://kit-e.ru/articles/circuit/2007_08_170.php
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
21.11.2012, 10:23
Отличная статья. Но возник вопрос. Возможно ли такая организация кнопок при которой будет одновременно 3 функции: короткое нажатие, долгое нажатие с автоповтором короткого нажатия и долгое нажатие как некая другая функция?
0
0 / 0 / 0
Регистрация: 03.02.2012
Сообщений: 106
21.11.2012, 16:26
Вы можете использовать обработку клавиатуры из альтернативной прошивки демо для PBII:
http://forum.iosyitistromyss.r... =23&t=9129
В основе алгоритма обработки нажатий и отжатий и противодребезга клавиш является счетчик заводимый для каждой клавиши. Этот же счетчик можно использовать для организации автоповтора. В обычном режиме при условии нажатия счетчик инкрементируется каждую миллисекунду, пока не достигнет значения 10. В этот момент генерируется событие нажатия клавиши. Никто не возбраняет и дальше инкрементировать счетчик и при достижении соответсвующей величины счетчика генерировать событие повторного нажатия на клавишу:
Code
1
if ((counter % 100)==0) gen_click_event();// Автоповтор каждые 100мс.(Псевдокод)
Таким же образом можно отследить ситуацию длительного удержания клавиши. При 16битном счетчике максимальная длительность удержания клавиши может достигать 65 секунд.

Единственное отличие от стандартного алгоритма обработки клавиш (декрементировать счетчик на единицу)необходимо из счетчика вычитать такое значение, чтобы счетчик обнулился за 10 циклов(10мс)...
0
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
22.11.2012, 08:21
В ваших исходниках для PBII реализован весьма простой алгоритм работы с кнопками. Имеется устранение дребезга при нажатии и отжатии. Больше я там ничего не увидел. Кроме того, уже и так понятно, что реализовать одновременно 3 функции (короткое нажатие, долгое нажатие с автоповтором короткого нажатия и долгое нажатие как некая другая функция) невозможно.
0
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
22.11.2012, 11:16
В данный момент у меня в одном проекте работа с кнопками реализована так:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void button_check(void)
{
event_e event = EV_IDLE;
static uint8_t button_enter = 0;
static uint8_t button_left = 0;
static uint8_t button_right = 0;
static uint8_t button_up = 0;
static uint8_t button_down = 0;
 
//----------------------------------------------------------------------
// Проверка кнопки ENTER
//----------------------------------------------------------------------
if((KBRD_PORT->IDR & KBRD_ENTER_PIN) == 0)         //Если кнопка нажата, то
{
if(!buttonlockout)               //Если время блокировки истекло, то
{
if(button_enter)               //Если кнопка была нажата, то
{
event = EV_LONGENTER;         //Событие долгого нажатия кнопки
buttonlockout = LONGKEY_LOCKOUT;   //Блокировка повторного нажатия
button_enter = 0;         //Кнопка отжата
}
else                  //Иначе
{
buttonlockout = LONGKEY_TIME;      //Длительность долгого нажатия
button_enter = 1;         //Кнопка нажата
}
}
}
else                         //Иначе кнопка отжата
{
if(button_enter)                  //Если перед этим была нажата, то
{
event = EV_ENTER;            //Событие нажатия кнопки
buttonlockout = BUTTON_LOCKOUT;      //Блокировка повторного нажатия
}
 
button_enter = 0;               //Кнопка отжата
}
 
//Код для остальных кнопок точно такой же, поэтому опущен
}
Функция button_check() вызывается каждые 100мс, поэтому в функции отсутствует подавление дребезга.
Если кнопка нажата в течении времени меньшего, чем LONGKEY_TIME, то это короткое нажатие и возникает событие EV_ENTER, при этом повторное нажатие кнопки возможно после интервала BUTTON_LOCKOUT. Если кнопка нажата в течении времени LONGKEY_TIME, то это долгое нажатие и возникает событие EV_LONGENTER, при этом повторное нажатие кнопки возможно после интервала LONGKEY_LOCKOUT. Переменная buttonlockout декрементируется каждые 100мс.
0
0 / 0 / 0
Регистрация: 03.02.2012
Сообщений: 106
22.11.2012, 12:16
Я не согласен с мнением эксперта:
Берем фрагмент исходного текста первоначальной альтернативной прошивки PBII:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 // key 1 section              //обработка состояния кнопок
{                             // генерация событий сопряженных с
// действиями кнопок
static uint8_t k1_cntr = 0; // счетчик антидребезга кнопки
static uint8_t k1_trigger=0;// флаг состояния кнопки 0-> кнопка отжата
// 1-> кнопка нажата
// алгоритмом обеспечивается гистерезис
// срабатывания кнопки
if (GPIO_ReadInputDataByt(GPIOA,GPIO_Pin_1)==0) // считать текущее сост.
// кнопки A01
{// если кнопка нажата
if (k1_cntr<10)           // если счетчик меньше макс. знач.
{
k1_cntr++;              // увеличить счетчик на 1
//если счетчик достиг макс. знач. и кнопка считается не нажатой
if ((k1_cntr==10)&&(k1_trigger==0))
{
k1_trigger=1;   // считать кнопку нажатой
if (k1_pressed==0) // если флаг события нажатия кнопки не активен
{
k1_pressed++;    // активизировать событие нажатия кнопки
}
}
}
}
else
{// иначе, если кнопка не нажата
if (k1_cntr > 0) // если счетчик антидребезга активен
{
k1_cntr--;    // уменьшить счетчик антидребезга на единицу
// если счетчик антидребезга стал пассивным и кнопка считается
// нажатой
if ((k1_cntr==0)&&(k1_trigger==1))
{
k1_trigger=0;         // считать кнопку отжатой
if (k1_depressed==0)  // если событие отжатия кнопки не активно
{
k1_depressed++;     // активизировать событие отжатия кнопки
}
}
}
}
}
и слегка ее модифицируем:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
uint8_t k1_pressed = 0;
uint8_t k1_outorepeat_pressed = 0;
uint8_t k1_20sec_pressed = 0;
 
// key 1 section              //обработка состояния кнопок
{                             // генерация событий сопряженных с
// действиями кнопок
static uint16_t k1_cntr = 0; // счетчик антидребезга кнопки
static uint8_t k1_trigger=0;// флаг состояния кнопки 0-> кнопка отжата
// 1-> кнопка нажата
// алгоритмом обеспечивается гистерезис
// срабатывания кнопки
if (GPIO_ReadInputDataByt(GPIOA,GPIO_Pin_1)==0) // считать текущее сост.
// кнопки A01
{
// если кнопка нажата
if (k1_cntr<65000)
{
k1_cntr++;              // увеличить счетчик на 1
}
if ((k1_cntr==10)&&(k1_trigger==0))
{
k1_trigger=1;   // считать кнопку нажатой
if (k1_pressed==0) // если флаг события нажатия кнопки не активен
{
k1_pressed++;    // активизировать событие нажатия кнопки
}
}
if ((k1_cntr > 500)&&((k1_cntr %100)==0))
{// события автоповтора начинают генерироваться
// спустя 500мс после первоначального нажатия на клавишу
if (k1_outorepeat_pressed==0)
{
k1_outorepeat_pressed++;
}
}
if (k1_cntr==20000)// проверка удержания кнопки 20сек
{
//генерация события удержания 20 сек
if (k1_20sec_pressed==0)
{
k1_20sec_pressed++
}
}
}
else
{// иначе, если кнопка не нажата
if (k1_cntr > 10)
{
k1_cntr=10;// обеспечение антидребезга отжатия
}
if (k1_cntr > 0) // если счетчик антидребезга активен
{
k1_cntr--;    // уменьшить счетчик антидребезга на единицу
// если счетчик антидребезга стал пассивным и кнопка считается
// нажатой
if ((k1_cntr==0)&&(k1_trigger==1))
{
k1_trigger=0;         // считать кнопку отжатой
if (k1_depressed==0)  // если событие отжатия кнопки не активно
{
k1_depressed++;     // активизировать событие отжатия кнопки
}
}
}
}
}
и вуаля!
Есть событие первоначального нажатия, есть событие автоповтора каждые 100мс, начинающееся через 500мс после первоначального нажатия на кнопку и есть событие 20сек удержания клавиши.
Смотрите внимательно: Руки свободные!
0
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
22.11.2012, 12:45
Нет там никакого вуаля. С модифицированным вариантом кода спорить не стану, имеет право существовать, но его жизнеспособность под вопросом. Собственно говоря, под вопросом жизнеспособность не конкретно этого кода, а самого принципа. Представим ситуацию. Вы коротко нажали кнопку, произошло событие EV_ENTER, обработалось в основной программе. Далее нажали и держите эту же кнопку, происходит событие EV_ENTER через интервалы автоповтора, в основной программе эти события обрабатываются. А вы все держите и держите эту кнопку. Додержали до того, что по вашей функции произошло событие долгого нажатия кнопки EV_LONGENTER. Замечательно. А что вы с ним будете делать теперь? Ведь вы уже до этого занимались автоповтором EV_ENTER, а тут вдруг оказалось, что теперь эти EV_ENTER были выполнены впустую и на самом то деле вам надо было EV_LONGENTER, причем функции по обработке EV_ENTER и EV_LONGENTER совершенно разные. Поэтому я считаю, что совместить автоповтор EV_ENTER и EV_LONGENTER невозможно.
0
0 / 0 / 0
Регистрация: 03.02.2012
Сообщений: 106
22.11.2012, 13:41
Приведенный пример кода выполняет почти все требования, заявленные в первоначальном топике. "Драйвер" клавиатуры генерирует соответствующие события. Использование данных событий или их игнорирование зависит от контекста выполнения основной программы. В одних случаях события автоповтора могут игнорироваться, в других может приниматься только событие удержания. Чтоже касаемо дабл клика, он тоже может отлавливаться после небольшой модификации драйвера, но ме не хочется напрягаться...
0
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
22.11.2012, 14:06
))) Таким ответом вы признали нежизнеспособность своего кода. Зачем ссылаться теперь на первоначальный топик? Вы же мне пытались доказать, что я не прав касаемо моих сообщений.
0
0 / 0 / 0
Регистрация: 03.02.2012
Сообщений: 106
22.11.2012, 14:13
Да, да, нежизнеспособный, вонючий код, не подходите и не трогайте его, чтобы не заразиться. И поищите себе дурачка, который вам будет помогать...
0
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
22.11.2012, 14:27
Цитата Сообщение от iukimi_i_m
Да, да, нежизнеспособный, вонючий код, не подходите и не трогайте его, чтобы не заразиться. И поищите себе дурачка, который вам будет помогать...
Мне помогать не надо, все сам делаю ))). Уточню, чтобы вы не обижались. Ваш код жизнеспособен, только нельзя в конретном контексте одновременно использовать автоповтор и долгое нажатие. И это не касаемо вашего кода уже утверждение, а самого принципа.
0
ovr495
25.11.2012, 04:36
Цитата Сообщение от 011119xx
Отличная статья. Но возник вопрос. Возможно ли такая организация кнопок при которой будет одновременно 3 функции: короткое нажатие, долгое нажатие с автоповтором короткого нажатия и долгое нажатие как некая другая функция?
конечно, главное сам алгоритм расписать на бумажке, продумать.
для примера, в начале нажатия на кнопку запустить два виртуальных таймера (счетчики которые инкрементируются в прерывании таймера). когда первый счетчик натикал, то обнулим его и пошлем событие повтора. когда второй счетчик натикает, уже его обнулим и пошлем событие долгого нажатия.
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
25.11.2012, 07:36
Чисто программно это реализуемо, а касаемо функционала устройства ... А???
0
0 / 0 / 0
Регистрация: 29.11.2012
Сообщений: 396
02.12.2012, 14:53
В телефонах это же работает, когда сообщения набираем - одно нажатие это буква, повторные нажатия это выбор нужной буквы, долгим нажатием вначале выводится первая буква а после определенного времени выводится цифра.

Идея была о двойном клике, но не повтор символов. Значит все зависит от человека, который пишет программу.
0
0 / 0 / 0
Регистрация: 22.04.2011
Сообщений: 223
02.12.2012, 15:01
Согласен с этим утверждением. Это частный случай текстового редактора. В данном случает такой функционал реализуем потому, что можно легко отмотать событие назад. Но как быть когда нельзя отмотать назад событие, которое уже ушло на исполнение по первоначальным событиям автоповтора?
0
0 / 0 / 0
Регистрация: 29.11.2012
Сообщений: 396
02.12.2012, 15:06
Если автоповтор, то события с долгим нажатием не возможны.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.12.2012, 15:06
Помогаю со студенческими работами здесь

hardware опрос кнопки.
Интересует есть ли железный опрос кнопки. Как энкодер самим процом обрабатывается. Хочу подключить 2 кнопки и что бы они 1 ячейку...

STM8L и сенсорные кнопки
Приветствую всех. Столкнулся со следующей проблемой: пишу на под STM8L152C8. Пишу без SPL. И понадобилось прикрутить сенсорные кнопки в...

обработка нажатия пользовательской кнопки
написал, чтобы при нажатии кнопки менялось состояние диодов. но что то не стабильно он работает. иногда надо нажимать 5-6 раз, чтобы...

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

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru