» » Микроконтроллеры. Связь с внешним миром. Часть 2

 
 
 
15

Микроконтроллеры. Связь с внешним миром. Часть 2

Разместил Spirit 21 декабря 2009. Просмотров: 24 369

Здравствуйте, дорогие Датагорцы!
По некоторым слабо зависящим от меня причинам не мог участвовать в жизни нашего города. Вы наверное уже и не надеялись на продолжение моих статей... Приношу вам свои глубочайшие извинения! И обещаю закончить свой курс!

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

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

Поставим себе следующую задачу: При нажатии на кнопку 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 загружен 200 раз.
Хотя я настоятельно рекомендую попробовать сделать всё самому с нуля! fellow

С уважением, Владимир bully
Владимир (Spirit)
Старый Оскол
Профиль Spirit
Электронщик-практик, в основном занимаюсь микроконтроллерами. Есть неплохой опыт и в аналоговой технике (все мы начинали с УМЗЧ =)).
Одержим идеей автоматизации жилища а-ля "Умный дом" =)
 

Понравилось? Палец вверх!

  • всего лайков: 15

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

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


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

Игорь Петрович Котов / Datagor

  • С нами с 25.02.2011
  • Ушёл в реал Пользователь offline
  • 1 631 комментарий
  • 261 публикация
 
  • 0
Володя, с возвращением!
Спасибо за достойное продолжение серии статей.

<
  • Гражданин
21 декабря 2009 03:02

Николай / foxit

  • С нами с 9.09.2008
  • Ушёл в реал Пользователь offline
  • 8 комментариев
  • 0 публикаций
 
  • 0
УРА!

Spirit has come back!

<
  • Гражданин
21 декабря 2009 04:55

Дима / dimamukhin

  • С нами с 9.04.2009
  • Ушёл в реал Пользователь offline
  • 12 комментариев
  • 0 публикаций
 
  • 0
Молодец ! Так держать !

Буду с нетерпением ждать продолжения smile

<
  • Прохожий
21 декабря 2009 05:02

/ VaL

  • С нами с --
  • 0 комментариев
  • 0 публикаций
 
  • 0
Спасибо, Володя, что ты есть! Ты хороший человек.

<
  • Гражданин
21 декабря 2009 16:26

Алексей / zud

  • С нами с 25.03.2009
  • Ушёл в реал Пользователь offline
  • 72 комментария
  • 0 публикаций
 
  • 0
Вова, для нас, для чайников - ты есть всё.
А вот и предложение
Соедени все уроки, и общей книжкой (можно в электронном виде) выложи!
Можно платно (в меру, конечно) wink

<
  • Прохожий
21 декабря 2009 17:46

/ zhu4ara

  • С нами с --
  • 0 комментариев
  • 0 публикаций
 
  • 0
Тёзка, с возвращением! По твоим статьям научился грызть микроконтроллеры - вкусно и полезно bully ;) Так держать! Готовлю уже статью про термостат для бойлера. На форуме есть ветка.

<
  • Гражданин
21 декабря 2009 20:42

Максим / GRafGRay

  • С нами с 20.10.2009
  • Ушёл в реал Пользователь offline
  • 32 комментария
  • 1 публикация
 
  • 0
яб к BTN1 + питания резюком подтянул бы
бо в ненажатом состоянии на PD2 какой уровень будет?

<
  • Прохожий
21 декабря 2009 23:55

/ Spirit

  • С нами с --
  • 0 комментариев
  • 0 публикаций
 
  • 0
Всем большое спасибо за добрые слова! feel

2 GRafGRay
В AVR-ах (и не только) есть очень удобная штука - называется она "внутренняя подтяжка". Ее можно включить для любого входа. Она эквивалентна подключению резистора ~50к именно между +питания и входом.
Этот вопрос я уже описал в следующей статье, которая пока ждет модерации.
Вот упрощенная схема одного из цифровых выводов МК.
//datagor.ru/uploads/posts/2009-12/1261019327_sh2.jpg

2 zud
Была такая мысль... Но сделаю это не раньше, чем закончу статьи по "внешним интерфейсам", т.к. все эти темы очень сильно переплетены и полноценно рассмотреть их отдельно практически невозможно. К тому же, я регулярно получаю письма, в которых люди указывают мои ошибки и рассказывают о возникших проблемах. Это, так сказать, бэта тестирование smile Творением займусь тогда, когда выловлю большую часть тараканов bully

<
  • Гражданин
22 декабря 2009 02:30

Максим / GRafGRay

  • С нами с 20.10.2009
  • Ушёл в реал Пользователь offline
  • 32 комментария
  • 1 публикация
 
  • 0
С теоретической точки зрения Вы полностью правы, pull-up резисторы в конкретной схеме выполнят свою роль на ура. Но ... :) на практике, в более сложных устройствах, этих "подтяжек" зачастую не достаточно.
Стоят резюки не дорого - зато есть гарантия что не погорят внутренние.

<
  • Прохожий
23 декабря 2009 00:19

/ Spirit

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

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

Давным-давно делал сенсорный переключатель на К561ЛА7. Там в подтяжке стояли резисторы на 1МОм + провода по 10см. И никаких помех схема не ловила bully

<
  • Прохожий
23 декабря 2009 21:52

/ Valeron

  • С нами с --
  • 0 комментариев
  • 0 публикаций
 
  • 0
С обработкой кнопок в прерываниях типа INT0 есть один минус - обработка дребезга контактов. Задержку в перываниях делать не рекомендуется, поэтому нужно будет програмно реализовывать мажоритарный алгоритм типа 8 из 10 раз был низкий уровень, значит кнопка замкгута.
Или перенос считывания кнопки в основной цикл.
В Протеусе этого заметить нельзя, а на практике - сколько угодно, сталкивался уже.

<
  • Гражданин
24 декабря 2009 21:08

Игорь / xtrason

  • С нами с 4.10.2009
  • Ушёл в реал Пользователь offline
  • 6 комментариев
  • 0 публикаций
 
  • 0
Ну вот, Вова наконец-то вернулся!!! Ура! Давно ожидал продолжение статей. Просьба к автору: Володя, пожалуйста учти пожелания, написанные в первой части "МК - Связь с внешним миром". Заранее спасибо! Статьи офигительные!

<
  • Прохожий
25 декабря 2009 18:57

/ Spirit

  • С нами с --
  • 0 комментариев
  • 0 публикаций
 
  • 0
Valeron
Полностью с Вами согласен. Но алгоритм будет значительно сложнее... В целях упрощения образовательного процесса я об этом пока не пишу. Но в скором времени эта тема обязательно будет рассмотрена.

xtrason
Спасибо feel
Все пожелания уже учтены. Следующая статья заканчивает тему "ввода с кнопок", а после нее будет "вывод информации", где я всё и опишу fellow

<
  • Гражданин
22 января 2011 13:58

Александр / MerBas

  • С нами с 8.12.2010
  • Ушёл в реал Пользователь offline
  • 19 комментариев
  • 0 публикаций
 
  • 0
Володя,огромное спасибо за статьи!Всё работает и мигает!!Несу все свои запасы радиодедалей обратно в гараж и покупаю ATMEGA8!!!

<
  • Гражданин
6 марта 2011 18:57

Дмитрий / mr_smit

  • С нами с 22.03.2009
  • Ушёл в реал Пользователь offline
  • 5 комментариев
  • 0 публикаций
 
  • 0
Предположим, что общий контакт COM валкодера мы подключим к общему проводу, тогда при нажатии кнопки LEFT, лог. "0" появится только на выводе A, а при нажатии кнопки RIGHT, благодаря диоду, лог. "0" будет на обоих выводах (A и B).


Может наоборот???? При нажатии LEFT лог. "0" появится только на выводах A и B. При нажатии RIGHT лог. "0" появится только на выводе В. Вы напутали с диодом на схеме видно. Не в ту сторону он включен. Либо я что то не понимаю.

Информация
Вы не можете участвовать в комментировании. Вероятные причины:
— Администратор остановил комментирование этой статьи.
— Вы не авторизовались на сайте. Войдите с паролем.
— Вы не зарегистрированы у нас. Зарегистрируйтесь.
— Вы зарегистрированы, но имеете низкий уровень доступа. Получите полный доступ.