Обработка нажатий тактовой кнопки.
Обычно первая программа программиста — выводит на экран строку “Hello word”, а эмбеддер мигает светодиодом, может ещё и кнопку прикрутить и с её помощью изменять состояние светодиода. Вот как раз про кнопку и хотел рассказать, обычно кнопку, которая что-либо переключает, называют тактовой кнопкой и подключают её по одной из схем, изображённых ниже.
![Обработка нажатий тактовой кнопки. Обработка нажатий тактовой кнопки.](https://hubstub.ru/uploads/posts/2015-12/1450358667_screenshot_3.png)
На двух верхних схемах подтягивающие резисторы не изображены, но этот не значит, что их нет, просто они находятся внутри микросхемы.
Но гораздо более интересный вопрос заключается в том, как опрашивать кнопку, чтобы не пропускать нажатия? Вариант первый — в цикле опрашивать вывод, к которому подключена кнопка, этот способ будет работать пока программа небольших размеров (вкл-выкл светодиод), но по мере разрастания программы начнут пропускаться нажатия. Второй вариант, это настроить таймер, чтобы он переполнялся каждые 30 ms, а по переполнению возникало прерывание и в нём опрашивались выводы, к которым подключены кнопки, ну или кнопка. Почему время опроса 30 ms? Дело в том что кнопка подвержена дребезгу, а такой временной интервал между опросами, позволяет его не чувствовать, давайте рассмотрим этот момент подробнее.
![Обработка нажатий тактовой кнопки. Обработка нажатий тактовой кнопки.](https://hubstub.ru/uploads/posts/2015-12/1450361761_screenshot_1.png)
Стрелки на картинке — это моменты возникновения прерываний, на верхней картинке изображен самый простой вариант развития событий, за счёт паузы между опросами, мы проскакиваем дребезг.
На средней картинке прерывание возникает в момент дребезга и как-будто бы кнопка не была нажата, но нас это не смущает, при следующем опросе кнопки фиксируем нажатие.
На нижней картинке прерывание снова возникает в момент дребезга, фиксируем нажатие и проскакиваем дребезг.
С отпусканием кнопки всё происходит по тому же сценарию и ещё если кнопка сильно дребезжит время между опросами можно увеличить.
Вот мы в прерывании, давайте рассмотрим варианты обработки нажатия. Первый выставляем флаг, что кнопка нажата, дальше в основном цикле проверяем его и там же сбрасываем, второй — заводим переменную и инкрементируем, её значение в прерывании если кнопка нажата, по отпусканию кнопки проверяем сколько натикало, то есть длительность удержания. Если натикало хотя бы один, то фиксируем короткое нажатие, если больше 10 — фиксируем длинное нажатие. Ещё раз поясню отличие первого способа от второго, в первом способе воздействие на систему происходит в момент нажатия кнопки, во втором — в момент отпускания, а какой способ выбрать решает сам программист, в зависимости от поставленной задачи.
Eщё можно попробовать реализовать двойное нажатие, и здесь мне видется два варианта, первый — после того как отпустили кнопку запускаем таймер и определённый промежуток времени ждём второго нажатия, если оно произошло, то фиксируем double_click. Второй способ — вести лог нажатий, то есть если кнопка была нажата и отпущена, то в нашей переменной будет храниться 0b00000010, если удерживается в течение 3 опросов, то 0b00000111, реализовать это просто: в прерывании сдвигаем значение переменной на одну позицию влево и в последний разряд записываем текущее состояние. Потом экспериментально(быстро нажимая два раза на кнопку) находим несколько значений переменной при двойном нажатии, например, у нас получилось 0b00110011, записываем это значение в double_click, теперь, для того чтобы определить двойное нажатие сравниваем значение нашей переменной с double_click. Первый вариант точно работает, а второй — просто мысли вслух.
![Обработка нажатий тактовой кнопки. Обработка нажатий тактовой кнопки.](https://hubstub.ru/uploads/posts/2015-12/1450358667_screenshot_3.png)
На двух верхних схемах подтягивающие резисторы не изображены, но этот не значит, что их нет, просто они находятся внутри микросхемы.
Но гораздо более интересный вопрос заключается в том, как опрашивать кнопку, чтобы не пропускать нажатия? Вариант первый — в цикле опрашивать вывод, к которому подключена кнопка, этот способ будет работать пока программа небольших размеров (вкл-выкл светодиод), но по мере разрастания программы начнут пропускаться нажатия. Второй вариант, это настроить таймер, чтобы он переполнялся каждые 30 ms, а по переполнению возникало прерывание и в нём опрашивались выводы, к которым подключены кнопки, ну или кнопка. Почему время опроса 30 ms? Дело в том что кнопка подвержена дребезгу, а такой временной интервал между опросами, позволяет его не чувствовать, давайте рассмотрим этот момент подробнее.
![Обработка нажатий тактовой кнопки. Обработка нажатий тактовой кнопки.](https://hubstub.ru/uploads/posts/2015-12/1450361761_screenshot_1.png)
Стрелки на картинке — это моменты возникновения прерываний, на верхней картинке изображен самый простой вариант развития событий, за счёт паузы между опросами, мы проскакиваем дребезг.
На средней картинке прерывание возникает в момент дребезга и как-будто бы кнопка не была нажата, но нас это не смущает, при следующем опросе кнопки фиксируем нажатие.
На нижней картинке прерывание снова возникает в момент дребезга, фиксируем нажатие и проскакиваем дребезг.
С отпусканием кнопки всё происходит по тому же сценарию и ещё если кнопка сильно дребезжит время между опросами можно увеличить.
Вот мы в прерывании, давайте рассмотрим варианты обработки нажатия. Первый выставляем флаг, что кнопка нажата, дальше в основном цикле проверяем его и там же сбрасываем, второй — заводим переменную и инкрементируем, её значение в прерывании если кнопка нажата, по отпусканию кнопки проверяем сколько натикало, то есть длительность удержания. Если натикало хотя бы один, то фиксируем короткое нажатие, если больше 10 — фиксируем длинное нажатие. Ещё раз поясню отличие первого способа от второго, в первом способе воздействие на систему происходит в момент нажатия кнопки, во втором — в момент отпускания, а какой способ выбрать решает сам программист, в зависимости от поставленной задачи.
Eщё можно попробовать реализовать двойное нажатие, и здесь мне видется два варианта, первый — после того как отпустили кнопку запускаем таймер и определённый промежуток времени ждём второго нажатия, если оно произошло, то фиксируем double_click. Второй способ — вести лог нажатий, то есть если кнопка была нажата и отпущена, то в нашей переменной будет храниться 0b00000010, если удерживается в течение 3 опросов, то 0b00000111, реализовать это просто: в прерывании сдвигаем значение переменной на одну позицию влево и в последний разряд записываем текущее состояние. Потом экспериментально(быстро нажимая два раза на кнопку) находим несколько значений переменной при двойном нажатии, например, у нас получилось 0b00110011, записываем это значение в double_click, теперь, для того чтобы определить двойное нажатие сравниваем значение нашей переменной с double_click. Первый вариант точно работает, а второй — просто мысли вслух.
Похожие статьи