Freewaygrp.ru

Строительный журнал
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Как подключить одну кнопку к одному входу микроконтроллера

Подключение нескольких кнопок и потенциометра к одному выводу микроконтроллера

Конструкция и метод дают возможность считывать состояние нескольких кнопок и значение аналогового потенциометра подключенных к одному лишь выводу микроконтроллера, к одному из входных каналов АЦП. Т.е. аналоговый и цифровой сигнал подаются в микроконтроллер по одному выводу.

Схема для реализации данного метода показана на рисунке (2 кнопки, 1 птоенциометр).

В пользовательских приложениях кнопки могут использоваться для выбора режимов, опций, а потенциометр может использоваться для изменения параметров. Реализация данного метода требует анализа цепи параллельного резистора и делителя напряжения. Если точно подобрать номиналы резисторов, то схема обеспечивает аналоговый вход наряду с возможностью отслеживать несколько дискретных входных состояний.

Выбор номиналов резисторов – многошаговый процесс, таблица (форамат Office’2007, .xlsx) помогает в выполнении вычислений. Скажем, к примеру, Вы хотите использовать потенциометр номиналом 5 кОм (Radj) для возможности ввода значений в микроконтроллер в пределах 0 – 100%. Как правило, в этом случае значения в диапазоне 0 – 255 Вы бы привели к диапазону 0 – 100 для представления значений в процентах. Однако, выбирая значение резистора смещения Rbias, Вы центрируете значения в пределах, например, 78 – 178 (в диапазоне 0 – 255).

Чтобы вычислить значения верхнего и нижнего резисторов Rbias, следующие уравнения решают эту схему, как простой делитель напряжения:

Преобразовывая эти выражения и выделяя Rbias, учитывая, что значение максимального напряжения 255, значение низкого напряжения для нашего диапазона – 78, значение максимального высокого напряжения для нашего диапазона – 178, Radj – 5 кОм, мы получаем следующее выражение:

Полученное значение резистора Rbias – 3875 Ом. Используя стандартный номинал 3.3 кОм, получим диапазон для потенциометра 73 – 182. Этот диапазон приводит к большему динамическому диапазону, чем мы нуждаемся, но учитывает защищенный диапазон между значениями потенциометра и значениями при нажатии кнопок. Поскольку положение Radj воздействует на полное сопротивление схемы, микроконтроллер должен обрабатывать диапазон значений для каждой кнопки. Для определения сопротивления Rsw, для кажой кнопки S1 или S2, мы используем параллельное включение резисторов на обоих крайних положениях потенциометра.

Когда нажата S1 и Radj имеет максимальное значение, эффективное сопротивление нижнего плеча делителя напряжения – значение при параллельном включении Rsw с цепью Radj и Rbias (включенных последовательно). При минимальном значении Radj – эффективное сопротивление – значение при параллельном включении Rsw с Rbias:

Вы можете определить значение сопротивления при нажатии S1, используя делитель напряжения, который формируют Rbias и REFFMAX из выражения:

Заметьте, что когда Radj имеет максимальное значение и Вы нажимаете кнопку S1,это создает сопротивление меньше меньшего значения самого Radj – это тем самым уникально определяет, что нажата кнопка S1. Таким образом, максимальное значение эффективного сопротивления REFFMAX будет меньше чем значение низкого напряжения для нашего диапазона, как показывает нижеследующее выражение:

Замена и решение этого уравнения для сопротивления выключателя дает:

Используя таблицу, находим что сопротивление выключателя должно быть 1558 Ом, и можем использовать стандартный резистор номиналом 1.5 кОм. В итоге, применив такой резистор, мы получим значение АЦП в диапазоне: 28 – 71 при нажатии на кнопку S1 и в зависимости от положения потенциометра. Аналогично, выбрав такое же значение для S2, мы получим значение в диапазоне 184 – 227. Эти диапазоны – группы значений, которые Вы можете использовать для определения, какая кнопка была нажата, независимо от положения потенциометра. Выбирая симметричные значения резисторов, Вы можете сократить необходимые вычисления и упростить проект.

Пример программы для двух кнопок и потенциометра для определения нажатия кнопок и положения потенциометра. Пример показывает как организовать две кнопки, однако, их количество может быть разным. Входные диапазоны позволяют организовать 10 кнопок и 1 потенциометр и по прежнему, используя лишь один вывод АЦП микроконтроллера. Но здесь нужно учитывать, что вычисленные диапазоны не будут накладываться друг на друга (уникальны), но аппаратные средства микроконтроллера (АЦП) не всегда дадут возможность достоверно отличить эти группы. Выбор меньших номиналов резисторов отдаляет группы друг от друга.

Ограничения при такой реализации – пользователь не может нажать более одной кнопки одновременно. А также, микроконтроллер может считывать значение потенциометра, только если не нажата ни одна из кнопок.

Перевод: Vadim по заказу РадиоЛоцман

ОБОРУДОВАНИЕ
ТЕХНОЛОГИИ
РАЗРАБОТКИ

Блог технической поддержки моих разработок

Урок 18. Подключение матрицы кнопок к Ардуино. Библиотека MatrixKeys. Функция tone().

Научимся подключать к плате Ардуино матрицу кнопок, использовать для генерации звука стандартную функцию tone().

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

Существует другой способ подключения кнопок к плате Ардуино – объединение кнопок в матрицу.

Подключение матрицы кнопок к микроконтроллеру.

Вот пример схемы такой матрицы. Для подключения 16 кнопок требуется только 8 выводов микроконтроллера.

Кнопки подключены к вертикальным и горизонтальным линиям матрицы. Состояние кнопок для каждой вертикальной линии проверяется отдельно. На вертикальную линию подается сигнал высокого уровня (5 В) и считываются состояния горизонтальных линий. Высокий уровень в горизонтальной линии покажет, что соответствующая кнопка нажата. Далее проверяются остальные вертикальные линии.

Резисторы обеспечивают нулевое напряжение на входах микроконтроллера при разомкнутых кнопках.

Такая схема часто используется для подключения матрицы кнопок к плате Ардуино в практических приложениях. Что меня удивляет. Ведь эта схема работает некорректно при одновременном нажатии двух и более кнопок из одной горизонтальной линии. В этом случае:

  • Результат будет непредсказуемым. Через горизонтальную линию и две нажатые кнопки замкнутся вертикальные линии с высоким и низким уровнями сигнала. Какая вертикальная линия перетянет, такой уровень и будет на горизонтальной линии.
  • Произойдет замыкание выводов микроконтроллера с разными уровнями сигналов. В лучшем случае повысится потребляемый ток, и микроконтроллер будет нагреваться.

Для устранения этой проблемы достаточно подключить вертикальные линии через диоды. Тогда замыкание выводов контроллера невозможно при любом количестве одновременно нажатых кнопок. Также схема с диодами позволит корректно определять состояние матрицы с двумя одновременно нажатыми кнопками. При нажатых трех соседних кнопках произойдет замыкание четвертой.

Подключение матрицы кнопок к плате Ардуино.

Подключим матрицу кнопок 3×4 к плате Ардуино по такой схеме.

Хороший стиль — нажатие каждой кнопки сопровождать коротким звуковым сигналом. Для это подключим к плате звуковой пьезоизлучатель. У меня все это выглядит так.

Библиотека сканирования матричной клавиатуры 4 x 4.

Я разработал библиотеку для сканирования матричной клавиатуры MatrixKey.h.

Загрузить ее можно по ссылке:

Зарегистрируйтесь и оплатите. Всего 60 руб. в месяц за доступ ко всем ресурсам сайта!

Как установить написано в уроке 9.

  • определяет текущее состояние каждой кнопки;
  • вырабатывает признаки “была нажата” для каждой кнопки (клики);
  • устраняет дребезг контактов кнопок;
  • сканирование матрицы происходит параллельным процессом, основная программа работает только с готовыми признаками.

Библиотека имеет конструктор и только одну функцию.

MatrixKeys(byte verticalPin1, byte verticalPin2, byte verticalPin3, byte verticalPin4, byte horizontalPin1, byte horizontalPin2, byte horizontalPin3, byte horizontalPin4, byte numAckn)

Конструктор, создает объект с заданными параметрами.

  • verticalPin1,verticalPin2,verticalPin3,verticalPin4 — номера выводов подключения вертикальных линий матрицы 1, 2, 3 ,4;
  • horizontalPin1,horizontalPin2,horizontalPin3,horizontalPin4 — номера выводов подключения горизонтальных линий матрицы 1, 2, 3 ,4;
  • numAckn — число подтверждений состояния контактов.

/ / создаем объект матрица кнопок keys
// подключаем вертикальные линии к выводам 9, 10, 11, 12
// подключаем горизонтальные линии к выводам 4, 5, 6, 7
// число подтверждений состояния контактов = 6
MatrixKeys keys(9, 10, 11, 12, 4, 5, 6, 7, 6);

Отдельные выводы матрицы можно отключить, задав для них в конструкторе номера равные 255. Это может потребоваться при подключении матрицы меньшей размерности.

void scanState()

Метод сканирует состояние кнопок матрицы. Не имеет параметров, ничего не возвращает.

Для устранения дребезга кнопок используется способ ожидания стабильного состояния контактов, описанный в уроке 6. В параллельном процессе должен регулярно вызываться метод scanState() .

В результате формируются признаки массивов flagPress[4][4] и flagClick[4][4] :

  • при нажатой кнопке flagPress = true;
  • при отжатой кнопке flagPress = false;
  • при нажатии на кнопку flagClick = true.

Признак flagPress показывает текущее состояние кнопки и изменяет свое значение в зависимости от состояния кнопки.

Признак flagClick становится активным в момент нажатия кнопки и остается в таком состоянии до тех пор, пока не будет сброшен программой. Класс MatrixKeys только устанавливает его в активное состояние.

Типичная работа с флагом flagClick – это проверка признака в основном цикле, сброс его и выполнение определенного действия, запланированного по нажатию кнопки. Этот флаг запоминает, что было нажатие и хранит информацию об этом до его сброса.

В отличие от известной библиотеки Keypad библиотека MatrixKeys:

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

Стандартная функция генерации звука tone().

Для формирования звукового сигнала по нажатию кнопок можно использовать стандартную функцию tone(). Функция генерирует на заданном выводе сигнал прямоугольной формы.

void tone(pin, frequency)
void tone(pin, frequency, duration)

  • pin – номер вывода;
  • frequency – частота сигнала в Гц;
  • duration – длительность сигнала в миллисекундах.

Если длительность сигнала не задана третьим аргументом, то сигнал вырабатывается до тех пор пока не будет вызвана функция noTone().

Необходимо помнить, что для генерации сигнала функция tone() использует Таймер 2 платы Ардуино. Поэтому, если этот таймер уже используется в программе, например для формирования прерывания, то функция tone() приведет к конфликту обращения к таймеру 2. По этой причине я не создал в классе возможности сопровождения нажатия кнопок звуковым сигналом. Лучше это желать вне класса, используя в каждом конкретном случае свой способ.

Практическое использование библиотеки MatrixKeys.

Напишем простую программу для проверки и демонстрации библиотеки MatrixKeys.h. Программа передает на компьютер по последовательному порту состояние матрицы кнопок:

  • нажатая кнопка отображается как ”*”;
  • отжатая – ”.”;
  • момент нажатия кнопки (клик) отображается символом ”=” в течение 0,5 секунд.

// создаем объект матрица кнопок keys
// подключаем вертикальные линии к выводам 9, 10, 11, 12
// подключаем горизонтальные линии к выводам 4, 5, 6, 7
// число подтверждений состояния контактов 6
MatrixKeys keys(9, 10, 11, 12, 4, 5, 6, 7, 6);

void setup() <
Serial.begin(9600); // инициализируем порт, скорость 9600
MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс
MsTimer2::start(); // разрешаем прерывание по таймеру
>

// перебор строк
for (int i = 0; i

// перебор столбцов
for (int j = 0; j

Загрузите программу в плату. Не забудьте установить библиотеки MatrixKeys.h и MsTimer2.h. Откройте монитор последовательного порта. На экране, каждые 0,5 секунды, будут пробегать блоки состояния матрицы.

Нажимая на кнопки матрицы можно проверить работу программы.

Если необходимо передавать код нажатой клавиши, то можно преобразовать состояние массива признаков кликов keys.flagClick[4][4] в коды кнопок codKeys[4][4].

// создаем объект матрица кнопок keys
// подключаем вертикальные линии к выводам 9, 10, 11, 12
// подключаем горизонтальные линии к выводам 4, 5, 6, 7
// число подтверждений состояния контактов 6
MatrixKeys keys(9, 10, 11, 12, 4, 5, 6, 7, 6);

void setup() <
Serial.begin(9600); // инициализируем порт, скорость 9600
MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс
MsTimer2::start(); // разрешаем прерывание по таймеру
>

// вычисление кода нажатой кнопки
// перебор столбцов
for (int i = 0; i
// перебор строк
for (int j = 0; j
if (keys.flagClick[i][j] == true) <
keys.flagClick[i][j]=0;
Serial.println(codKeys[i][j]);
>
>
>
>

Если загрузить программу в плату и открыть монитор последовательного порта, то при каждом нажатии кнопки в окне монитора будет отображаться символ, соответствующий кнопке.

При необходимости Вы легко сможете переделать библиотеку на матрицу кнопок других размерностей.

В следующем уроке будем подключать к плате Ардуино семисегментные светодиодные индикаторы.

Подключение нескольких тактовых кнопок к одному выводу микроконтроллера

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

Однако существуют и другие методы, которые позволяют подключать множество кнопок к одному выводу микроконтроллера. В этом статье рассмотрим один из таких приемов на примере микроконтроллера PIC12F683. Забегая вперед, следует сказать, что этот метод будет работать и с другими микроконтроллерами PIC, AVR, имеющими в своем составе АЦП.

В нашем случае к микроконтроллеру PIC12F683 подключены четыре светодиода и четыре тактовые кнопки. Каждый светодиод управляется через отдельный вывод I/O, а все четыре кнопки подключены к одному выводу АЦП микроконтроллера PIC12F683.

Теория

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

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

Принципиальная схема, показанная ниже, вероятно, даст вам более четкое представление об этом методе. Четыре кнопки (SW1-Sw4) подключены к контакту AN0 микроконтроллера PIC12F683. Их один конец заземлен через общий резистор R (470 Ом), тогда как другой конец каждой кнопки подтянут через резисторы разного номинала (R1′-R4′), что обеспечивает разное напряжение на выходе делителя напряжения.

Таким образом, падение напряжения на резисторе R уникально для каждого нажатия кнопки. Когда ни одна из кнопок не нажата, на выводе AN0 через резистор R будет низкий уровень, и в идеале АЦП должен определить это как 0 В.

Четыре светодиода (LED1-LED4) подключены к контактам GP1, GP2, GP4 и GP5 микроконтроллера PIC12F683. Они будут включаться и выключаться четырьмя кнопками.

Расчет сопротивления подтягивающих резисторов

Мы знаем, что каждое значение резистора R1′-R4′ должно отличаться друг от друга, чтобы получить уникальный аналоговый выход для каждой кнопки. Но как подобрать их значения?

Следует иметь в виду, что резисторы имеют определенные значения допусков (отклонение от заявленного номинала). Также их сопротивление может незначительно меняться с изменением температуры. Следовательно, мы должны обеспечить достаточный промежуток между любыми двумя последовательными значениями на выходе делителя напряжения, чтобы избежать конфликта.

Лучшим решением было бы реализовать равномерно распределенные значения делителя напряжения для всех 4 кнопок. Помните, что когда вы нажимаете кнопку, вы не должны ожидать точного значения аналогового напряжения на резисторе R. Оно будет немного «плавать» в пределах определенного диапазона, который определяется значениями допуска резисторов, температурой, контактным сопротивлением кнопок, стабильностью напряжения питания и так далее.

Итак, чтобы идентифицировать нажатую кнопку, мы на самом деле смотрим на диапазон напряжения, в котором находится выход делителя напряжения.

В таблице ниже показаны диапазоны DN (делителя напряжения), определенные для всех четырех кнопок и соответствующие значения для резисторов R’. DN обозначает число (от 0 до 1024) 10-битного АЦП, который пропорционален входному аналоговому напряжению.

Предположим, мы задаем диапазон DN кнопки SW1 как 100-300. Наша цель — найти подходящее сопротивление R’, чтобы при нажатии SW1 результат 10-битного АЦП выход всегда находился в диапазоне от 100 до 300. Минимальное значение R’ будет соответствовать максимальному значению выбранного диапазона АЦП (300) для SW1. Уравнение для нахождения R’ для DN = 100:

1024 * R / (R + R ‘) = 100, где R = 470 Ом

Это дает R’= 4342,8 Ом. Точно так же для DN = 300 значение R’ должно быть 1134,3 Ом. Следовательно, R ‘= 2,2 кОм является подходящим значением для кнопки SW1. Остальные значения R’ для других кнопок показаны в таблице ниже.

Программного обеспечения

Программное обеспечение включает в себя несколько проверок, чтобы сравнить выход A/D с предварительно определенными диапазонами, чтобы определить, какая кнопка была нажата:

Примечание. Микроконтроллер работает на частоте 4,0 МГц, используя свой внутренний источник синхронизации, а MCLR отключен.

Резюме

На микроконтроллере PIC12F683 была продемонстрирована технология сопряжения нескольких тактовых кнопок с использованием одного вывода АЦП. Напряжение от нажатия кнопок считывается каналом АЦП AN0 и отображается посредством четырех светодиодов.

Хотя этот метод экономит контакты микроконтроллера и уменьшает размер схемы, одним из недостатков такой конструкции является обнаружение одновременного нажатия нескольких кнопок. В этом случае решением является особый расчет резисторов R’. Сопротивление этих резисторов следует подбирать очень тщательно, чтобы напряжение, возникающее в результате нажатия нескольких кнопок, было уникальным.

Скачать прошивку (13,8 KiB, скачано: 98)

Кнопка

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

Хотя у кнопки есть четыре ножки, фактически можно рассматривать их два участка цепи, который замыкается сверху. Следите за правильностью подключения, чтобы цепь была корректной.

Подключим кнопку без использования контроллера, пропустив ток из 5V. При нажатии кнопки цепь замкнётся и светодиод будет светиться. Ничего неожиданного.

В реальности нам нужно считывать сигнал с кнопки и реагировать на него. Поэтому попробуем изменить схему. Соединим один вывод кнопки с питанием и выводом 3 на плате. С вывода 3 мы будем считывать информацию: логический ноль или логическая единица. При нажатии на кнопку цепь замыкается, на выводе 3 будет логическая единица и мы включим светодиод.

Код прекрасно работает при нажатии кнопки. А когда мы отпускаем кнопку и создаём разрыв в цепи, то возникает проблема. Вывод 12 становится свободным и висит в неопределённом состоянии в режиме INPUT (вспоминаем урок про цифровые выводы). В результате мы получаем случайные значения и светодиод то включается, то выключается от наводок.

Чтобы избежать этой проблемы, можно добавить резистор от 10 до 100 кОм и прижать кнопку к земле. В этом случае цепь будет замкнута даже при отпущенной кнопке. В этом случае резистор называют стягивающим (pull down). Это рабочая схема, которую можно использовать в учебной программе.

Несмотря на рабочую схему с стягивающим резистором, мы получаем проблему при работе со сложным проектом. Дело в том, что возможна ситуация, когда многие устройства в схеме используют разные значения питания. И тогда придётся к каждой кнопке устройства подавать свой отдельный стягивающий резистор. На практике принято подключаться не к питанию, а к земле, которая всегда одинакова и равно 0. В этом случае сам резистор следует подключить к питанию — подтянуть. Резистор в этом случае является подтягивающим (pull up). Правда, при этом возникает другая проблема — поведение светодиода изменилось противоположным образом — при нажатии светодиод выключается, а при отпускании — включается. Решается проблема просто — меняем одну строчку кода.

Мы просто меняем значение переменной на противоположное. Это стандартный подход при работе с кнопкой. Теперь вам будет легче разобраться с примерами из Arduino IDE.

Стоит отметить, что у платы Arduino у выводов уже есть встроенные подтягивающие резисторы (кроме вывода 13) и мы можем убрать внешний резистор. Но тогда надо также явно указать использование данного резистора через код с параметром INPUT_PULLUP.

01.Basics: DigitalReadSerial (Чтение цифрового вывода)

Изучим пример DigitalReadSerial из File | Examples | 01.Basics.

Мы изучили, как правильно подключать кнопку и можем изучать встроенные примере. Будем считывать сигнал, идущий с цифрового вывода при нажатии кнопки.

Приблизительно собранная схема может выглядеть следующим образом:

Вкратце опишу на словах данную схему. Вставляем в центре макетной платы кнопку таким образом, чтобы между парными ножками проходил жёлоб макетной платы. Далее соединяем перемычками питание 5V и землю GND на Arduino с рельсами на макетной плате. Потом соединяем перемычкой цифровой вывод под номером 2 на Arduino с одной ножкой кнопки на макетной плате. Эту же ножку кнопки, но с другой стороны соединяем с резистором, который выполняет роль стягивающего резистора. После чего сам резистор соединяем с землёй. Третью ножку кнопки соединяем к положительной рельсе на макетной плате. Осталось только соединить между собой боковые рельсы на макетной плате, и мы готовы изучать новый пример.

Кнопка выполняет очень важную функцию — она замыкает цепь при нажатии. Когда кнопка не нажата, то ток не проходит между ножками кнопки, и не можем поймать сигнал с цифрового вывода под номером 2. Поэтому состояние вывода определяется системой как LOW или 0. При нажатии на кнопку его две ножки соединяются, позволяя току пройти от питания к цифровому выводу 2, а система считывает проходящий сигнал как HIGH или 1.

Разберём код по кусочкам

В функции setup() устанавливаем связь с портом для считывания данных на скорости 9600 бит в секунду с Arduino на ваш компьютер: Serial.begin(9600).

Вторая строчка нам уже знакома, но здесь теперь используется параметр INPUT — мы устанавливаем второй цифровой вывод на режим чтения данных, поступающих с кнопки: pinMode(pushButton, INPUT);

В цикле считываем поступающую информацию. Для начала нам понадобится новая переменная buttonState, которая будет содержать значения 0 или 1, поступающие от функции digitalRead().

Чтобы мы могли видеть поступающую информацию, нужно вывести получаемые результаты в окно Serial Monitor при помощи команды println().

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

Если вы сейчас запустите программу и откроете также окно Serial Monitor (меню Tools | Serial Monitor), то на экране увидите бесконечные нули. Программа постоянно опрашивает состояние нашей конструкции и выводит результат — отсутствие тока. Если нажать на кнопку и удерживать её, то увидите, что цифры сменяются с 0 на 1. Значит в нашей цепи появился ток и информация изменилась.

02.Digital: Button

Работа с кнопкой рассматривается также в примере File | Examples | 02.Digital | Button. Кнопка соединяется с выводом 2, а светодиод с выводом 13. К кнопке также следует подвести питание и землю через резистор на 10K. Сам принцип работы остался без изменений. Только на этот раз мы не будем выводить информацию о состоянии кнопки на экран, а будем включать светодиод. Такой вариант более наглядный. При нажатии и отпускании кнопки встроенный светодиод должен загораться или гаснуть.

Допустим, мы хотим изменить поведение — если кнопка не нажата — светодиод горит, а при нажатии — светодиод не горит. Достаточно изменить одну строчку кода.

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

Нужно поменять полярность цепи! Провод от резистора, который на землю, нужно воткнуть в 5V, а провод, который шёл из 5V к кнопке, перекинуть на землю. При включении ток пойдёт из питания на вывод 2 без всяких помех и будет получено значение HIGH. При нажатии кнопки получится другая цепь, и вывод 2 останется без питания.

02.Digital: StateChangeDetection

В примере File | Examples | 02.Digital | StateChangeDetection идёт подсчёт щелчков кнопки и состояние кнопки (включён или выключен). Схема осталась прежней. Кнопка соединяется с выводом 2, а светодиод с выводом 13 (можно использовать встроенный). К кнопке также следует подвести питание и стягивающий резистор к земле на 10K.

02.Digital: Debounce (Дребезг)

У кнопок существует такой эффект, как «дребезг». При замыкании и размыкании между пластинами кнопки возникают микроискры, провоцирующие до десятка переключений за несколько миллисекунд. Явление называется дребезгом (англ. bounce). Это нужно учитывать, если необходимо фиксировать «клики». Поэтому первичным показаниям верить нельзя. По этой причине часто в скетчах делают небольшую задержку, а уже потом считывают показания. В обычном состоянии, когда мы не нажимаем кнопку или держим кнопку нажатой, эффекта дребезга не наблюдается. Иногда для этих целей в учебных примерах используют функцию delay(), но на практике следует использовать функцию millis(), как в примере File | Examples | 02.Digital | Debounce. Схема подключения остаётся без изменений.

02.Digital: DigitalInputPullup (Встроенный подтягивающий резистор)

У цифровых выводов уже есть резисторы на 20 кОм, которые можно использовать в качестве подтягивающих при работе с кнопками. Рассмотрим пример File | Examples | 02.Digital | DigitalInputPullup.

Схема подключения — соединим первый вывод кнопки с выводом 2 на плате, а второй вывод кнопки с выводом GND. Во время работы скетча будем считывать показания второго вывода.

Если запустить скетч, то увидим, что на монитор выводятся числа 1 (HIGH). При нажатии на кнопку значения поменяются на 0 (LOW).

Как подключить одну кнопку к одному входу микроконтроллера

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

В МК ATMega16 есть три таймера/счетчика – два 8-битных (Timer/Counter0, Timer/Counter2) и один 16-битный (Timer/Counter1). Каждый из них содержит специальные регистры, одним из которых является счетный регистр TCNTn (n – это число 0, 1 или 2). Каждый раз, когда процессор выполняет одну команду, содержимое этого регистра увеличивается на единицу (либо каждые 8, 64, 256 или 1024 тактов). Потому он и называется счетным. Помимо него, есть еще и регистр сравнения OCRn (Output Compare Register), в который мы можем сами записать какое-либо число. У 8-битного счетчика эти регистры 8-битные. По мере выполнения программы содержимое TCNTn растет и в какой-то момент оно совпадет с содержимым OCRn. Тогда (если заданы специальные параметры) в регистре флагов прерываний TIFR (Timer/Counter Interrupt Flag Register) один из битов становится равен единице и процессор, видя запрос на прерывание, сразу же отрывается от выполнения бесконечного цикла и идет обслуживать прерывание таймера. После этого процесс повторяется.

Ниже представлена временная диаграмма режима CTC (Clear Timer on Compare). В этом режиме счетный регистр очищается в момент совпадения содержимого TCNTn и OCRn, соответственно меняется и период вызова прерывания.

Это далеко не единственных режим работы таймера/счетчика. Можно не очищать счетный регистр в момент совпадения, тогда это будет режим генерации широтно-импульсной модуляции, который мы рассмотрим в следующей статье. Можно менять направление счета, т. е. содержимое счетного регистра будет уменьшаться по мере выполнения программы. Также возможно производить счет не по количеству выполненных процессором команд, а по количеству изменений уровня напряжения на «ножке» T0 или T1 (режим счетчика), можно автоматически, без участия процессора, менять состояние ножек OCn в зависимости от состояния таймера. Таймер/Счетчик1 умеет производить сравнение сразу по двум каналам – А или В.

Далее представлена функциональная схема таймера/счетчика0:

Для запуска таймера нужно выставить соответствующие биты в регистре управления таймером TCCRn (Timer/Counter Control Register), после чего он сразу же начинает свою работу.

Мы рассмотрим лишь некоторые режимы работы таймера. Если вам потребуется работа в другом режиме, то читайте Datasheet к ATMega16 – там все подробнейше по-английски написано, даны даже примеры программ на С и ассемблере (недаром же он занимает 357 страниц печатного текста!).

Теперь займемся кнопками.

Если мы собираемся использовать небольшое количество кнопок (до 9 штук), то подключать их следует между «землей» и выводами какого-либо порта микроконтроллера. При этом следует сделать эти выводы входами, для чего установить соответствующие биты в регистре DDRx и включить внутренний подтягивающий резистор установкой битов в регистре PORTx. При этом на данных «ножках» окажется напряжение 5 В. При нажатии кнопки вход МК замыкается на GND и напряжение на нем падает до нуля (а может быть и наоборот – вывод МК замкнут на землю в отжатом состоянии). При этом меняется регистр PINx, в котором хранится текущее состояние порта (в отличие от PORTx, в котором установлено состояние порта при отсутствии нагрузки, т. е. до нажатия каких-либо кнопок). Считывая периодически состояние PINx, можно определить, что нажата кнопка.

ВНИМАНИЕ! Если соответствующий бит в регистре DDRx будет установлен в 1 для вашей кнопки, то хорошее нажатие на кнопку может привести к небольшому пиротехническому эффекту – возникновению дыма вокруг МК. Естественно, МК после этого придется отправить в мусорное ведро…

Перейдем к практической части. Создайте в IAR новое рабочее пространство и новый проект с именем, например, TimerButton. Установите опции проекта так, как это описано в предыдущей статье. А теперь наберем следующий небольшой код.

Давайте посмотрим, как это работает. В функциях init_timern задаются биты в регистрах TCCRn, OCRn и TIMSK, причем такой способ может кому-нибудь показаться странным или незнакомым. Придется объяснить сначала, что означает запись «(1 © KERNELCHIP 2006 — 2021

голоса
Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector
Яндекс.Метрика