Используя в проектах большое количество кнопок, постоянно сталкиваюсь с проблемой нехватки количества внешних прерываний. Вроде выбрал подходящий по нафаршированности камень, есть все что надо – АЦП, 2 юарта, много флэша, а вот прерываний нехватает… Или чаще наоборот, небольшой проект, на который с лихвой хватит ресурсов tiny2313, и нужно обрабатывать много внешних событий (таких как нажатие на кнопки). Брать камень крупнее не спортивно, да и жалко когда ресурсы будут низачто простаивать :), поэтому был найден простой способ как, использовав всего один вход прерывания, обработать практически неограниченное количество кнопок.
Суть метода в том, чтобы одним прерыванием фиксировать нажатие любой кнопки. А уже в обработчике прерывания просканировать и узнать какая именно кнопка была нажата.
Для примера вот небольшая схемка:
Диоды D1-D4 предназначены для того чтобы разделить кнопки между собой. Резисторы можно ставить номиналом по 4,7-10 кОм.
и тестовая программка для микроконтроллера
$regfile = “attiny2313.dat”
$crystal = 1000000
$baud = 1200
Dim W As Byte ‘переменная с номером нажатой кнопки
‘кнопки
Config Portb.0 = Input
Config Portb.1 = Input
Config Portb.2 = Input
Config Portb.3 = Input
Config Portd.6 = Output ‘сюда подключается светодиод индикации
Portd.6 = 0
Config Int0 = Falling ‘прерывание по нисходящему фронту
On Int0 Button
Enable Interrupts ‘разрешаем прерывания
Enable Int0
‘Основной цикл программы
Do
Print W ‘печатаем номер нажатой кнопки
W = 0
Idle ‘и засыпаем
Loop
End
‘обработчик прерывания
Button:
‘здесь мы в цикле сканируем все подключенные кнопки
Do
If Pinb.3 = 0 Then
W = 1
End If
If Pinb.2 = 0 Then
W = 2
End If
If Pinb.1 = 0 Then
W = 3
End If
If Pinb.0 = 0 Then
W = 4
End If
Pulseout Portd , 6 , 2500 ‘мигнем светодиодом
Loop Until W <> 0 ‘если дребезг помешал вычислению нажатой кнопки, повторяем
Waitms 10
Gifr = 64 ‘сброс флага прерывания
Return
Светодиод на схеме не показан, из программы думаю ясно, что он подключается к ножке PortD.6
В программе организован спящий режим микроконтроллера, из которого его можно вывести прижав вывод INT0 к земле. Это делается нажатием любой кнопки. В обработчике прерывания происходит сканирование портов МК к которым подключены кнопки и если на одном из них ноль – значит нажата эта самая кнопка. Дальше присваиваем некой переменной значение соответствующее нажатой кнопки, мигаем светодиодом и уходим в основной цикл, где печатаем номер кнопки и снова даем команду микроконтроллеру “уснуть”.
Номер кнопки в примере печатается в терминал на скорости 1200 бод.
Как видно это очень простой способ, который подойдет под различные задачи. А поменяв немного алгоритм сканирования портов, можно организовать обработку одновременно нескольких кнопок.
Последние статьи
- Лучшая практика проектирования при размещении компонентов печатной платы
- Android 6.0 на lancer X
- Простой усилитель мощности класса АВ своими руками.
- Двухтактный ультралинейный ламповый УНЧ на EL84 (6П14П).
- Люксметр на ATmega8 и цифровом датчике BH1750
- Контроллер для светодиодной ленты с ИК управлением
- Самодельный LED светильник на основе ИК датчика HC-SR501
- Простой усилитель низкой частоты на TDA7377 и NE5532
- Простейший звонок с двумя мелодиями
- LED Cube 8x8x8 на Arduino с RTC