В начало | Зарегистрироваться | Заказать наши киты почтой
 
 
 
 

Грызём микроконтроллеры. Урок 8. Программирование кнопок, клавиатуры, энкодера

📆21 декабря 2009   ✒️Spirit   🔎28.674   💬15  
Здравствуйте, дорогие Датагорцы!
По некоторым слабо зависящим от меня причинам не мог участвовать в жизни нашего города. Вы наверное уже и не надеялись на продолжение моих статей... Приношу вам свои глубочайшие извинения! И обещаю закончить свой курс!

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

Начнем с простейшей схемы с двумя кнопками:

Список всех частей:
Грызём микроконтроллеры. Урок 1. Моргаем 8-ю светодиодами. CodeVision, Proteus, ISIS
Грызём микроконтроллеры. Урок 2. CodeVision и С
Грызём микроконтроллеры. Урок 3. Циклы, прерывания и массивы
Грызём микроконтроллеры. Урок 4. Мерим температуру или напряжение
Грызём микроконтроллеры. Урок 5. Кодовый замок
Грызём микроконтроллеры. Урок 6. Прошиваем МК
Грызём микроконтроллеры. Урок 7. Подключение к МК кнопок, клавиатуры, энкодера
Грызём микроконтроллеры. Урок 8. Программирование кнопок, клавиатуры, энкодера
Грызём микроконтроллеры. Урок 9. Клавиатура вглубину


Поставим себе следующую задачу: При нажатии на кнопку BTN1 светодиод должен загораться, а при нажатии на кнопку BTN2 - гаснуть.

Задача простейшая, но, как ни странно, имеет минимум ТРИ способа реализации!

Исключён фрагмент. Полный вариант доступен меценатам и полноправным членам сообщества.


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


Способ 1.
Создаем проект, генерируем и сохраняем его:

Исключён фрагмент. Полный вариант доступен меценатам и полноправным членам сообщества.


Обратите внимание на третий рисунок. Я специально выделил строку желтым цветом, т.к. в ней отключена внутренняя подтяжка бита №3, т.к. при отпущенной кнопке на этом выводе должен быть лог. "0", который обеспечивается внешним резистором PullDown.

В начале нашей программы ( например после строки #include"mega8.h" ) добавим строки

#define LED PORTB.0 
#define BTN1 PIND.2
#define BTN2 PIND.3


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

Далее, используя эти обозначения, в основной цикл программы впишем следующее:
 if(BTN1==0)LED=1;
 if(BTN2==1)LED=0;


Теперь, каждый раз, когда выполнение программы будет доходить до этих строк (а т.к. они у нас единственные, то просто будут выполняться по очереди), сначала будет проверяться состояние кнопки BTN1, и если она нажата (т.е., вход соединен с общим проводом) то на входе, к которому она подключена, будут логический "0". В этом случае условие BTN1==0 истинно, и выполняется код, расположенный за скобками (выходу LED присваивается значение "1"), что приводит к загоранию светодиода. То же самое происходит далее с кнопкой BTN2, с той лишь разницей, что если она нажата, светодиод тухнет.

Компилируем программу и проверяем ее в ISIS. Радуемся первым результатам. wink

Способ 2.
Создаем новый проект:
Исключён фрагмент. Полный вариант доступен меценатам и полноправным членам сообщества.


При указанной частоте входного сигнала для таймера (0,977 kHz) период его переполнения, а соответственно и срабатывания его прерывания будет равен примерно 261 мс., т.е., кнопки будут опрашиваться ~3,83 раза в секунду.

Теперь, как и в предыдущем примере вписываем в начало программы
#define LED PORTB.0 
#define BTN1 PIND.2
#define BTN2 PIND.3


А в обработчик прерывания Timer 0 overflow вписываем
if(BTN1==0)LED=1;
if(BTN2==1)LED=0;


Эффект будет тот же самый, что и в предыдущем примере, с одним лишь различием - кнопки будут опрашиваться через равные промежутки времени.
Компилируем, проверяем в ISIS. Снова поражаемся результату своих трудов. tongue

Способ 3.
И опять создаем проект...

Исключён фрагмент. Полный вариант доступен меценатам и полноправным членам сообщества.


На последней картинке вы видите установку параметров внешних прерываний.
Напомню, что:
Low level - срабатывание прерывания при низком уровне (лог "0") на входе INTх
Any change - срабатывание прерывания при любом изменении на входе INTх
Falling edge - срабатывание прерывания при переходе от "1" к "0" (т.н. задний фронт импульса) на входе INTх
Rising edge - срабатывание прерывания при переходе от "0" к "1" (т.н. передний фронт импульса) на входе INTх

Почему я выбрал именно такие параметры попробуйте разобраться сами fellow

Теперь, изменим своей привычке и в начале программы напишем только
#define LED PORTB.0 


Кнопки описывать теперь нет никакой необходимости lol
Далее, в прерывании External Interrupt 0 пишем
LED=1;


А в External Interrupt 1
LED=0;


Пояснение: при нажатии кнопки BTN1 срабатывает прерывание, в котором всего одна строчка "LED=1;", которая и включает светодиод. А при нажатии на BTN2 выполняется строчка "LED=0;", соответственно выключая светодиод.


С одиночными кнопками разобрались. Пора переходить к чему-то посложнее fellow

Соблюдая последовательность предыдущей статьи, разберем взаимодействие с валкодером. Если кто-то не помнит принцип его действия, советую освежить свою память, прочитав ту самую статью: Микроконтроллеры. Связь с внешним миром. Клавиатура.

Самый удобный способ взаимодействия с валкодером - подключение одного из его сигнальных выводов ко входу внешнего прерывания. Именно его я и предлагаю рассмотреть.

К сожалению, в ISIS нет модели валкодера, а проверить программку виртуально хотелось бы, поэтому представим его двумя кнопками, в соответствии с принципом работы:

Исключён фрагмент. Полный вариант доступен меценатам и полноправным членам сообщества.


Предположим, что общий контакт COM валкодера мы подключим к общему проводу, тогда при нажатии кнопки LEFT, лог. "0" появится только на выводе A, а при нажатии кнопки RIGHT, благодаря диоду, лог. "0" будет на обоих выводах (A и B). Таким образом, вывод A в этой схеме будет "тактовым" (т.к. на нем появляется сигнал при нажатии на любую кнопку), а вывод B - "сигнальным" (уровень на нем определяет направление).

Теперь составим схему нашего будущего устройства:



Для простоты схемы я использовал семисегментный индикатор со встроенным дешифратором, на который будет выводиться число от 0 до F (в шестнадцатичной системе счисления). Представление валкодера описанной ранее схемой накладывает некоторые ограничения, из-за которых ко входу внешнего прерывания нужно подключать именно вывод A. При использовании реального валкодера таких ограничений нет. Его выводы A и B можно спокойно менять местами, при этом изменится только кодирование направления (т.е., если раньше было "влево", то станет "вправо" и наоборот smile).

Итак, со схемой разобрались, теперь по ней и будем писать программу.
Создаем проект, указывая PORTB - все выходы, PORTD - все входы с подтяжкой. А на вкладке внешних прерываний выберем только INT1 и установим его "по заднему фронту" (картинок больше не будет - разбирайтесь по предыдущим примерам am).

Создали? Вот и отлично! wink

Далее создадим глобальную переменную для счетчика counter (глобальной она будет, если определить ее вне функции в начале кода программы).
char counter=0;


И там же сопоставим вход МК, к которому подключен вывод B валкодера с константой DIRECTION
#define DIRECTION PIND.4


Теперь в основном цикле будем записывать значение переменной counter в порт B:
PORTB=counter;


Почему именно в основном цикле? Да потому, что мне так захотелось lol
Хотя есть и еще причины, например, если в прерывании написать слишком большой код, то это может затормозить выполнение основной программы, т.к. МК в каждый момент времени может обрабатывать только одно прерывание, другие прерывания будут ожидать окончания обработки текущего. А если обработки ожидает прерывание, которое сообщает об отключении питания устройства и нужно сохранит данные в EEPROM? Это прерывание может так и не дождаться своей очереди, так что делайте выводы. winked

А теперь самое интересное - обработка сигналов от валкодера.
Прерывание INT0 срабатывает при нажатии любой кнопки (вращении валкодера в любую сторону), а направление определяется состоянием второго, т.е. "сигнального" вывода.
Значит, если DIRECTION - "1", крутим влево, а если "0" - крутим вправо.

Так и запишем в функции обработки прерывания:
if(DIRECTION==1)counter--;
else counter++;


И, по уже сложившейся традиции, компилируем и проверяем lol

Думаю на сегодня впечатлений достаточно. Остальные способы рассмотрим в следующей статье.

Все исходники и схемы можете взять тут: 🎁keys2.rar  209.42 Kb ⇣ 228
Хотя я настоятельно рекомендую попробовать сделать всё самому с нуля! fellow

С уважением, Владимир bully

Камрад, рассмотри датагорские рекомендации

🌼 Полезные и проверенные железяки, можно брать

Опробовано в лаборатории редакции или читателями.




 

Читательское голосование

Нравится

Статью одобрили 9 читателей.

Для участия в голосовании зарегистрируйтесь и войдите на сайт с вашими логином и паролем.
 

Поделись с друзьями!

 

 

Связанные материалы

 

Схема на Датагоре. Новая статья Грызём микроконтроллеры. Урок 3. Циклы, прерывания и массивы... Эту статью я начну с провокационного вопроса… А какую конструкцию на основе МК хотите создать ВЫ?...
Схема на Датагоре. Новая статья Анатомия микроконтроллеров ATmega - 3. Прерывания.... Итак, наши светодиоды мигают, но мы не можем никак повлиять на программу, давайте добавим в схему...
Схема на Датагоре. Новая статья Грызём микроконтроллеры. Урок 9. Клавиатура вглубину... И снова приветствую Вас в моей лекционной! На этот раз я расскажу Вам как "сэкономить"...
Схема на Датагоре. Новая статья Программный валкодер... Это не новость и не статья. Это просто развёрнутый комментарий к датагосркой статье "Что есть...
Схема на Датагоре. Новая статья Грызём микроконтроллеры. Урок 7. Подключение к МК кнопок, клавиатуры, энкодера... Очень давно обещал продолжить цикл статей по работе с микроконтроллерами, но не было физической...
Схема на Датагоре. Новая статья Кнопочный выключатель для УНЧ на JK-триггере CD4027... Обычно использовать маленький красивый выключатель для подачи питания на силовой трансформатор нет...
Схема на Датагоре. Новая статья Грызём микроконтроллеры. Урок 5. Кодовый замок... Третий свой урок я начинал с вопроса "А какую конструкцию на основе МК хотите создать...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 7... Поговорим о прерываниях. Слово прерывание говорит само за себя, происходит остановка какого — то...
Схема на Датагоре. Новая статья PIC микроконтроллеры. Все, что вам необходимо знать. Сид Катцен... PIC микроконтроллеры. Все, что вам необходимо знать. Сид Катцен пер. с англ. Евстифеева А. В. — М.:...
Схема на Датагоре. Новая статья Блок автоматического селектора входов и управления питанием усилителя на PIC12F675... Хочу предложить продолжение проекта Автоматическое включение/выключение сабвуфера на...
Схема на Датагоре. Новая статья Зарядное устройство Li-Ion аккумуляторов с проверкой ёмкости, PIC12F675... У меня скопилось около двух десятков Прочитав датагорскую статью «Автоматическое...
Схема на Датагоре. Новая статья Контроллер управления кухонной электроплитой. Регулятор мощности и таймер отключения... Благодаря идее и участию Юрия Зинченко (ZenitSoft) было разработано и построено устройство,...
 

Комментарии, вопросы, ответы, дополнения, отзывы

 

<
Читатель Датагора

Datagor

<
Читатель Датагора

dimamukhin

<
Читатель Датагора

VaL

<
Читатель Датагора

zud

<
Читатель Датагора

zhu4ara

<
Читатель Датагора

GRafGRay

<
Читатель Датагора

Spirit

<
Читатель Датагора

GRafGRay

<
Читатель Датагора

Spirit

<
Читатель Датагора

Valeron

<
Читатель Датагора

xtrason

<
Читатель Датагора

Spirit

<
Читатель Датагора

MerBas

<
Читатель Датагора

mr_smit

Добавить комментарий, вопрос, отзыв 💬

Камрады, будьте дружелюбны, соблюдайте правила!

  • Смайлы и люди
    Животные и природа
    Еда и напитки
    Активность
    Путешествия и места
    Предметы
    Символы
    Флаги
 
 
В начало | Зарегистрироваться | Заказать наши киты почтой