Обработка большого количества кнопок на одном прерывании

 Используя в проектах большое количество кнопок, постоянно сталкиваюсь с проблемой нехватки количества внешних прерываний. Вроде выбрал подходящий по нафаршированности камень, есть все что надо – АЦП, 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 бод.

 Как видно это очень простой способ, который подойдет под различные задачи. А поменяв немного алгоритм сканирования портов, можно организовать обработку одновременно нескольких кнопок. 

Тестовый код


Взято с: avrproject.ru


Категория: AVR
Метки:

Написать коментарий

*
= 5 + 1

Добавить изображение

Последние статьи