Site Loader

Содержание

Урок 8. Ввод информации в МК. Подключение кнопки к МК BASCOM-AVR « схемопедия


В предыдущих уроках были проведены способы вывода информации из микроконтроллера: подключение светодиода и ЖК индикатора. Но как, же вводить информацию в микроконтроллер? Существует множество вариантов и устройств для этого. Но пока что рассмотрим самый простой вариант, это обычная кнопка. Кнопки бывают двух видов: тактовые и фиксирующие. Тактовые кнопки работают по такому принципу: нажал – контакты замкнулись, отпустил – контакты разомкнулись. Следует учесть, что существуют тактовые кнопки, которые изначально замкнуты, а при нажатии размыкаются. Фиксирующие кнопки (их иногда называют: тумблеры, выключатели, переключатели) в отличии от тактовых фиксируют своё положение при нажатии, то есть: нажал – контакты замкнулись, еще раз нажал – контакты разомкнулись. В общем, с кнопками разобрались, теперь будем разбираться, как подключить эти кнопки к микроконтроллеру. А подключить на самом деле очень даже просто! Смотрим схему:

Возможно, вы спросите: Зачем резистор R1? А затем, что без резистора R1, когда кнопка S1 будет разомкнута, микроконтроллер на порте, к которому всё это подключено, будет видеть то логическую 1, то логический 0 тем самым будут производиться ложные срабатывания кнопки.

Чтобы этого не происходило необходимо этот порт “подтягивать” сопротивлением к плюсу питания. Сопротивление резистора R1 может быть в интервале от 4,7кОм до 10кОм. С резистором получается такая картина: кнопка S1 нажата – на порте МК возникает логический 0, кнопка S1 не нажата – на порте МК возникает логическая 1 за счёт сопротивления R1. Конечно, нужно знать, что в некоторых AVR микроконтроллерах есть встроенные подтягивающие резисторы сопротивление порядка 50кОм, по умолчанию они отключены. В BASCOM-AVR эти резисторы можно включить, записав в необходимый порт логическую 1. Но я крайне не рекомендую использовать эти встроенные, гораздо надёжнее использовать внешние, как показано на схеме выше. Ну что, со схематическим решением разобрались, теперь будем разбираться программно. Для работы с кнопкой сначала нужно сконфигурировать порт микроконтроллера на вход, в BASCOM-AVR это делается вот так:

Config (порт микроконтроллера) = input

Пример:

Config PINB.

3 = input

Обратите внимание, что для работы порта на вход, имя порта должно начинаться с PIN, а не с PORT как для конфигурации порта на вход!

После конфигурации порта на вход мы можем считать с него значение 1 или 0, в нашем случае 0 – кнопка нажата, 1 – кнопка не нажата. А проверить, что кнопка нажата, мы можем так:

If (порт микроконтроллера) = 0 then

(если кнопка нажата, то выполняем, действия описанные здесь)

End if

Можно и наоборот, проверить, не нажата ли кнопка:

If (порт микроконтроллера) = 1 then

(если кнопка не нажата, то выполняем, действия описанные здесь)

End if

Пример:

If PINB.3 = 0 then

PORTB.2 = 1 «если кнопка нажата, то включаем светодиод подключенный к PB.2

End if

Просто, не правда ли? Итак, теперь попробуем реализовать подключение кнопки к микроконтроллеру в “железе”. За основу возьмём микроконтроллер Attiny13 и отладочную плату для него сделанную немного ранее. Для того кто не делал отладочную плату, вот схема:

Алгоритм работы программы такой: кнопка S1 нажата – светодиод не горит, кнопка S1 не нажата – светодиод горит. А вот и сама программа на BASCOM-AVR:

$regfile = “attiny13.dat” $crystal = 8000000 Config Pinb.3 = Input Config Portb.2 = Output Do If Pinb.3 = 0 Then Portb.2 = 0 If Pinb.3 = 1 Then Portb.2 = 1 Loop End

Вот такая простая программа. Скомпилированная прошивка находится в архиве ниже. Фьюз биты можно не выставлять, так как в такой простой программе тактовая частота не особо важна. Для ленивых собирать в железе есть проект в нашем любимом симуляторе Proteus, скачать можно в архиве ниже. Работа в схемы в симуляторе Proteus:

Видео работы:

Скачать файлы для урока (проект в Proteus, исходник, прошивка)

Автор: Яковлев Александр Вячеславович (г.Витебск, Беларусь)

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

Идея предлагаемого решения была изложена в [1]. Суть его — в подключении максимального числа контактных датчиков (герконов, кнопок) к микроконтроллеру с использованием минимального числа его выводов. Реализована эта идея с помощью универсального таймера КР1441ВИ1. Время-задающая RC-цепь таймера составлена из конденсатора и набора резисторов, соединённых последовательно с каждой кнопкой. Определённой замкнутой кнопке соответствует своя частота следования генерируемых таймером импульсов, которую и измеряет микроконтроллер [2].

Оригинальный вариант имеет два существенных недостатка. Один из них — использование двух входов микроконтроллера. На один из них поданы генерируемые импульсы. Второй служит для определения факта замыкания кнопки, хотя это легко может быть сделано программно, за счёт чего этот вход микроконтроллера можно использовать для других целей. Другой недостаток — измерение частоты, а не периода повторения импульсов. Вследствие этого для получения линейной зависимости частоты от номеракнопки использовано большое число времязадающих резисторов разных номиналов.

Рис. 1. Схема конструкции

 

Предлагаемое техническое решение, схема которого показана на рис. 1, свободно от этих недостатков. Таймер КР1441ВИ1 структуры КМОП (аналог LMC555) работает в автоколебательном режиме со скважностью импульсов 2 [3]. В этом режиме период повторения импульсов равен

T = 2·ln2·C·R,

где C и R — соответственно ёмкость и сопротивление элементов времязадающей цепи. При C = C1 и R = R1·N, состоящем из N (по числу кнопок) одинаковых резисторов сопротивлением R1, соединённых последовательно, период T равен:

T≈1,39·C1·R1·N

Он получается пропорциональным числу резисторов между конденсатором C1 и первой замкнутой кнопкой SB1 — SB32 и легко может быть измерен микроконтроллером. Как и в первоисточнике, при одновременном замыкании нескольких кнопок та, что имеет меньший номер, обладает приоритетом.

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

Демонстрационная программа микроконтроллера по прерыванию IRQ0 измеряет длительность периода T, переводит его в номер кнопки и выводит наЖКИ MT-16S2S [4]. Связь микроконтроллера с ЖКИ организована по трёхпроводному последовательному интерфейсу. Вводом и выводом информации заняты всего четыре вывода микроконт-роллера, остальные могут быть применены для других целей.

Для измерения периода использован восьмиразрядный таймер-счётчик 0 микроконтроллера. По нарастающему перепаду уровня на входе запроса прерывания IRQ0 программа считывает длительность измеренного периода и обнуляет счётный регистр. Для повышения точности измерения обнуляется и предделитель счётчика. Поскольку предделитель всех таймеров-счётчиков в микроконтроллерах серии ATtiny общий, это может влиять на длительность временных интервалов, формируемых таймером-счётчиком 1 в случае его использования с предделителем, отличным от единицы. При разомкнутых контактах всех кнопок происходит переполнение счётчика, измеряющего период. По соответствующему прерыванию и определяется разомкнутое состояние.

Максимальное число распознаваемых кнопок зависит от нестабильности интервалов времени, формируемых таймером и микроконтроллером. При тактировании микроконтроллера от внутреннего RC-генератора и применении во времязадающей RC-цепи таймера плёночного конденсатора с малым ТКЕ, резисторов с малым ТКС и отклонением от номинала не более 1 % число кнопок может достигать 12-16. При более точной подборке резисторов удалось распознавать 32 кнопки. Ещё больше увеличить их число может позволить стабилизация частоты тактового генератора микроконтроллера кварцевым резонатором.

В макете устройства применены импортный плёночный конденсатор C1 (аналог К73-17) и резисторы R1 — R32 для поверхностного монтажа CR1206-FX-5621ELF сопротивлением 5,62 кОм ±1 %. Из 50 резисторов с одной ленты отобраны 32 штуки с разницей максимального и минимального сопротивления не более 20 Ом. Для уменьшения влияния на период колебаний зависимости выходного напряжения таймера DA1 от числа подключённых резисторов R1-R32 резисторы с меньшим сопротивлением имеют меньшие позиционные номера, а выходы таймера 3 и 7 соединены вместе.

Подстроечный резистор R35 должен быть многооборотным, например, СП5-3 или подобным. Подстройку выполняют следующим образом. Замыкают кнопку с позиционным номером на единицу меньше максимального (в данном случае SB31) и находят два положения движка подстроечного резистора R35, соответствующих изменению показаний ЖКИ с 31 на 32 и с 31 на 30. Устанавливают движок в среднее между найденными положение.

Рис. 2. Проверка устройства и отладка программы микроконтроллера

 

Проверка устройства и отладка программы микроконтроллера выполнена на макете, изображённом на рис. 2. Байты конфигурации микроконтроллера были запрограммированы следующим образом: младший — 0xBF, старший — 0xD4, дополнительный — 0xFF. Поскольку нужного числа кнопок для макета не нашлось, пришлось вместо них использовать переключатель ПП7-4ЛВ. Резисторы для поверхностного монтажа напаяны непосредственно на платы переключателя. При подобранных резисторах в комнатных условиях номера замкнутых контактов переключателя определялись правильно, хотя микроконтроллер работал от внутреннего RC-генератора.

Программу микроконтроллера можно скачать здесь.

Литература

1. 2-Wire Keypad Interface Using a 555 Timer. — URL: http://www.radiolocman.com/ shem/schematics.html?di = 88598 (12.07.16).

2. Евстифеев А. В. Микроконтроллеры AVR семейства Tiny — М.: «ДОДЭКА-XXl», 2007.

3. LMC555 CMOS Timer. — URL: http:// pdf1 .alldatasheet.com/datasheet-pdf/ view/9100/NSC/LMC555CN.html (12.07.16).

4. MT-16S2S. Жидкокристаллический индикатор буквенно-цифровой 2 строки по 16 символов. — URL: http://www.melt.com.ru/ docs/MT-16S2S.pdf (12.07.16).

Автор: С. Иванов, г. Москва

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

Методическое указание к лабораторной работе на учебном стенде LESO1.

1 Цель работы
  1. Изучить особенности работы параллельных портов микроконтроллера.
  2. Изучить схемы подключения кнопок и матричной клавиатуры к микроконтроллеру.
  3. Научиться определять состояние кнопок при помощи программы.
  4. Изучить способы отладки программ на лабораторном стенде LESO1.
  5. Изучить принцип работы матричной клавиатуры.

2 Предварительная подготовка к работе
  1. По конспекту лекций и рекомендуемой литературе изучить схемы параллельных портов микроконтроллеров.
  2. По конспекту лекций и рекомендуемой литературе изучить схемы подключения кнопок и клавиатуры к параллельным портам.
  3. Изучить архитектуру микроконтроллера ADuC842.
  4. Изучить принципиальную схему лабораторного стенда LESO1.
  5. Составить алгоритм работы программы: при нажатии на кнопку, согласно варианту, загорается комбинация светодиодов, соответствующая в бинарном виде номеру кнопки; при отпускании кнопки, светодиоды должны погаснуть.
  6. Составить программу на языке программирования С.

3 Краткие теоретические сведения

3.1 Применение матричной клавиатуры для ввода информации в микропроцессорную систему

Для реализации взаимодействия пользователя с микропроцессорной системой используют различные устройства ввода-вывода информации. В самом простом случае в роли устройства ввода может выступать кнопка, представляющая собой элементарный механизм, осуществляющий замыкание-размыкание контактов под действием внешней механической силы. Схема подключения кнопки к линии ввода параллельного порта ввода микроконтроллера показана на рисунке 1. Когда контакты кнопки S1 разомкнуты через резистор R1 на вход контроллера поступает высокий логический уровень «1», когда же контакты замкнуты, то вход оказывается соединенным с общим проводом, что соответствует логическому уровню «0». Если параллельный порт микроконтроллера имеет встроенный генератор тока, то в схеме можно обойтись без резистора R1.

Рисунок 1 – Подключение одиночной кнопки к параллельному порту

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

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

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

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

Временная диаграмма напряжений на портах вывода при выполнении программы опроса клавиатуры приведена на рисунке 3.

Рисунок 3 – Временные диаграммы работы порта вывода

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

3.2 Рекомендации к составлению программы

Программа для микроконтроллера жестко зависит от принципиальной схемы разрабатываемого устройства. Невозможно написать программу для микроконтроллерного устройства не имея перед глазами его схемы. Поэтому, перед началом работы по принципиальной схеме учебного стенда LESO1 следует изучить способ подключения клавиатуры и светодиодов к микроконтроллеру: определить, к каким портам подключены светодиоды, столбцы и строки клавиатуры. Затем по таблице SFR нужно узнать адреса регистров задействованных портов ввода-вывода.

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

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

При написании программы нужно помнить об особенности параллельного порта P1 в микроконтроллере ADuC842. Этот порт по умолчанию настроен на ввод аналоговых сигналов (функция АЦП). Для того чтобы перевести порт в режим цифрового входа, в соответствующий бит порта необходимо записать логический ноль. Сделать это нужно один раз при инициализации микроконтроллера. Порт не имеет внутреннего усиливающего транзистора, и потому при вводе дискретной информации через него не требуется записывать в разряды логическую единицу.

4 Задание к работе в лаборатории
  1. По принципиальной схеме установите, к каким портам микроконтроллера подключены светодиоды, а также столбцы и строки клавиатуры.
  2. По таблице регистров специальных функций (SFR) определите адреса регистров требуемых портов.
  3. Войдите в интегрированную среду программирования Keil-C.
  4. Создайте и настройте должным образом проект.
  5. Введите текст программы в соответствии с заданием: При нажатии на кнопку, согласно варианту, загорается комбинация светодиодов, соответствующая в бинарном виде номеру кнопки; при отпускании кнопки, светодиоды должны погаснуть.
  6. Оттранслируйте программу, и исправьте синтаксические ошибки.
  7. Загрузите полученный *.hex файл в лабораторный стенд LESO1.
  8. Убедитесь, что программа функционирует должным образом.

5 Указания к составлению отчета

Отчет должен содержать:

  1. Цель работы.
  2. Принципиальную схему подключения клавиатуры к микроконтроллеру.
  3. Графическую схему алгоритма работы программы.
  4. Исходный текст программы.
  5. Содержимое файла листинга программного проекта.
  6. Выводы по выполненной лабораторной работе.

Схемы, а также отчет в целом, выполняются согласно нормам ЕСКД.

Подключение до 15 кнопок к одному выводу PIC

В статье мы рассмотрим один простой способ, позволяющий контролировать до 15 кнопок, подключенных лишь к одному выводу микроконтроллера. Единственным требованием для реализации этого метода является наличие в микроконтроллере внутреннего аналогового компаратора с функцией настройки значения опорного напряжения (VREF). Большинство 8-разрядных микроконтроллеров PIC компании Microchip имеют один или два таких компаратора.

В качестве простого и практичного примера в изображенной на рисунке схеме используется микроконтроллер PIC12F683 и 4 светодиода, в двоичном формате индицирующие номер нажатой кнопки. Кнопки подключены к выводу GP1 микроконтроллера (вход CIN— аналогового компаратора). Для тактирования микроконтроллера используется внутренний генератор.

Контроль состояния кнопок выполняется в обработчике прерываний от аналогового компаратора, который вызывается при нажатии любой кнопки. В обработчике прерываний выполняется пошаговое изменение значения опорного напряжения компаратора до тех пор, пока на выходе компаратора СOUT не появится «лог. 1».

В краткой форме алгоритм можно описать следующим образом.

  1. Исходное состояние: режим пониженного энергопотребления (Idle). Опорное напряжение компаратора VREF устанавливается на уровне VREF = (1/24)Vdd, напряжение VCIN— на входе компаратора CIN— равно 0 – меньше значения опорного напряжения, на выходе компаратора COUT «лог. 1».
  2. В случае нажатия любой кнопки напряжение VCIN— становится больше опорного напряжения и на выходе компаратора появляется «лог. 0», что вызывает прерывание.
  3. В обработчике прерывания выполняется пошаговое изменение опорного напряжения согласно выражению VREF = (i/24)Vdd, где i принимает значения от 2 до 15. Изменение опорного напряжения выполняется одновременно с проверкой условия VREF > VCIN-, и как только оно выполняется, на выходе компаратора COUT появится «лог. 1», указывающая на то, что нажата кнопка с индексом Btn(i-1). Если же опорное напряжение остается меньше входного VCIN— при значении i = 16, значит, нажата кнопка Btn15.
  4. Четыре светодиода отображают двоичный номер (индекс) нажатой кнопки.

Исходный код программы микроконтроллера на ассемблере с подробными комментариями занимает менее 100 слов. Он легок для понимания и может использоваться на других микроконтроллерах.

STM32. Подключение кнопки | CUSTOMELECTRONICS.RU

В этой статье мы сделаем еще один небольшой шаг в ознакомлении с возможностями микроконтроллеров STM32. А именно будем использовать выводы микроконтроллера в режиме входа.
Перед работой с этой статьей обязательно необходимо проделать задачу из предыдущего примера, в котором рассматривалась настройка среды и решалась задача с миганием светодиодом.
К счастью, именно эту задачу будет решить очень просто, действуя по той же схеме, что и ранее.
Так как мы используем готовую плату и заранее настроенный для нее в CubeMX проект, мы уже имеем физически подключенную голубую кнопку. Подключена она к выводу PC13. Последнее утверждение можно проверить на вкладке Pin Configuration в программе CubeMX.
Чтобы опросить состояние этой кнопки, в первую очередь, необходимо найти в файле драйвера с именем stm32f0xx_hal_gpio.c строку в которой описывается функция чтения состояния вывода HAL_GPIO_ReadPin(). Вот как выглядит эта функция:

Этой функции необходимо сообщить два параметра:

  1. Номер порта в формате GPIOx, где x — буквенное обозначение порта. В нашем случае это порт С
  2. Номер вывода в формате GPIO_PIN_x, где x — номер вывода. В нашем случае 13

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

На всякий случай уточним что именно делает каждая из строчек кода.
Функция HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) после вызова возвращает нам значение, которое тут же инвертируется при помощи оператора «!». Если функция вернула значение ноль (то есть кнопка нажата), то ноль инвертируется в единицу и условие становится истинным и при помощи вызова функции HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET) включается светодиод на плате.
Если кнопка не нажата, то условие ложно и выполняется функция HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET), которая выключает светодиод.
И вот так вот на максимальной скорости, без задержек, в бесконечном цикле контроллер будет включать или выключать светодиод. То есть пользователь будет видеть, что при нажатии на кнопку светодиод включается, а при ее отпускании — выключается.

Пользовательский светодиод на плате

Ссылки на остальные статьи цикла можно найти здесь.
Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

Подключение клавиатуры к AVR | avr

На этой страничке рассказывается, как подключать 12-кнопочную клавиатуру к микроконтроллеру AVR, и как считывать клавиатурные нажатия на языке ассемблера. Это перевод статьи «Connecting a keypad to an AVR» [1]. Как работать с матрицей клавиатуры на языке C, см. [2].

[1. Как работает клавиатура]

Клавиатура представляет собой просто набор замыкателей. Нажали кнопку клавиатуры — соответствующий контакт замкнулся. Для того, чтобы уменьшить количество проводов, которые идут от клавиатуры, и тем самым упростить схему подключения, используют соединение замыкателей в матрицу. В нашем примере с 12-кнопочной клавиатурой матрица имеет 3 столбца (Column, провода столбцов пронумерованы как Col3..Col1) и 4 строки (Row, провода строк пронумерованы как Row4..Row1).

К примеру, если нажата кнопка «1», то замыкаются друг на друга Col1 и Row1, если нажата кнопка «2», то замыкаются Col2 и Row1, и так далее.

Чтобы определить, что нажата хотя бы одна кнопка из 12, можно соединить все столбцы на землю, а все строки подключить через нагрузочный резистор (pull-up) к + питания. Тогда на выходе Output появится лог. 0, если будет нажата любая кнопка.

Однако обычно в реальной жизни нужно не только знать, что нажата любая кнопка, нужно определить, какая именно кнопка из 12 была нажата. Для этого не все сразу столбцы подключаются к лог. 0, они подключаются к 0 поочередно, друг за другом. Такая процедура пробегания лог. 0 по столбцам называется сканированием клавиатуры. Один цикл сканирования происходит очень быстро, за время порядка 1..10 миллисекунд. Кроме того, для каждой строки используют отдельный нагрузочный резистор.

Событие нажатия определяется по чтению состояния всех строк (Row4..Row1). Если на всех RowX уровень лог. 1, то это что ни одна из клавиш не нажата. Если на одной из строк RowX появился уровень лог. 0, то сканирование прекращается, и код нажатой клавиши определяется по таблице.

Столбцы Строки Код кнопки
Col1 Col2 Col3 Row1 Row2 Row3 Row4 Символ Двоичный код
0 0 0 1 1 1 1 нет нажатия 1111
0 1 1 0 1 1 1 1 0001
1 0 1 0 1 1 1 2 0010
1 1 0 0 1 1 1 3 0011
0 1 1 1 0 1 1 4 0100
1 0 1 1 0 1 1 5 0101
1 1 0 1 0 1 1 6 0110
0 1 1 1 1 0 1 7 0111
1 0 1 1 1 0 1 8 1000
1 1 0 1 1 0 1 9 1001
0 1 1 1 1 1 0 * 1010
1 0 1 1 1 1 0 0 0000
1 1 0 1 1 1 0 # 1011

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

• генератор, регистр сдвига и декодер запуска/останова для генерации сигналов столбцов,
• детектор появления нуля на сигналах строк,
• декодер для преобразования 7 цифровых сигналов в код нажатой клавиши.

Лучше всего с такой задачей справится микроконтроллер, например AVR.

[2. Подключение AVR к матрице клавиатуры]

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

На этой картинке в качестве примера показано подключение матрицы к 7 младшим разрядам порта P микроконтроллера AVR. Можно конечно также использовать любые другие порты в любой комбинации. В нашем примере GPIO PB4..PB6 работают как выходы, они обеспечивают сигналы для столбцов (сканирующий бегущий лог. 0). GPIO PB0..PB3 используются как входы, через них читается состояние строк. На этих входах программно включены внутренние нагрузочные резисторы микроконтроллера (pull-up), так что никакие внешние резисторы для создания лог. 1 не нужны.

В следующем примере кода показано, как инициализируются порты GPIO. Эта часть программы должна быть выполнена 1 раз, когда включается питание AVR.

Инициализация

;
; Инициализация I/O портов для подключения клавиатуры
;
. DEF rmp = R16 ; определение регистра общего назначения
; определение портов
.EQU pKeyOut = PORTB  ; регистр для установки состояния выхода (Col3..Col1)
                      ; и настройки Pull-Up (Row4..Row1)
.EQU pKeyInp = PINB   ; регистр для чтения входов (Row4..Row1)
.EQU pKeyDdr = DDRB   ; регистр, задающий направление работы порта
; Код инициализации
InitKey:
   ldi rmp,0b01110000 ; подготовка данных для регистра DDRB, столбцы
                      ; настраиваются как выходы, строки как входы
   out pKeyDdr,rmp    ; запись в регистр направления
   ldi rmp,0b00001111 ; разрешить резисторы Pull-Up на строках
   out pKeyOut,rmp    ; вывод информации в регистр PORTB

Определение, нажата ли кнопка

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

;
; Проверка, нажата или нет любая из кнопок
;
AnyKey:
   ldi rmp,0b00001111 ; PB4..PB6(Col3..Col1)=0, pull-Up резисторы подключены 
                      ; на входы (PB0..PB3, Row4..Row1).
   out pKeyOut,rmp    ; установка регистра PORTB
   in rmp,pKeyInp     ; чтение состояния строк (Row4..Row1).
   ori rmp,0b11110000 ; установить все неиспользуемые биты в лог. 1
   cpi rmp,0b11111111 ; все биты в лог. 1?
   breq NoKey         ; да, не была нажата ни одна из кнопок

Прим. переводчика: можно также настроить пробуждение микроконтроллера по изменению уровня на любом из входов Row4..Row1. Для этого нужно установить все три столбца Col3..Col1 в состояние лог. 0 и отправить микроконтроллер в режим сна (Sleep, режим пониженного энергопотребления). После того, как пользователь нажмет любую кнопку, микроконтроллер проснется по появлению лог. 0 на входах строк Row4..Row1. В этом месте можно запустить сканирование Col3. .Col1 и определить, какая именно кнопка нажата.

Идентификация нажатой кнопки

Теперь нужно прочитать клавиатуру, для этого на столбцы Col3..Col1 поочередно нужно выставить лог. 0. После того, как на одном из портов столбца PB4..PB6 (Col3..Col1) выставлен 0 и на остальных портах столбца лог. 1, проверяется состояние портов строк PB0..PB3 (Row4..Row1) на наличие 0. Регистр Z (регистровая пара R31:R30) указывает на таблицу (размещена в памяти программ FLASH), содержащую коды кнопок. После того, как код определения кнопки закончит работу, регистр Z будет указывать на код нажатой кнопки. С помощью инструкции LPM можно прочитать этот код и сохранить его в регистр R0.

;
; Идентификация нажатой кнопки
;
ReadKey:
   ldi ZH,HIGH(2*KeyTable) ; Z указывает на таблицу кодов кнопок
   ldi ZL,LOW(2*KeyTable)
   ; чтение столбца 1 (Col1)
   ldi rmp,0b00111111      ; PB6 = 0
   out pKeyOut,rmp
   in rmp,pKeyInp          ; чтение строк
   ori rmp,0b11110000      ; маскирование старших бит
   cpi rmp,0b11111111      ; нажата кнопка в этом столбце?
   brne KeyRowFound        ; найдена нажатая кнопка в этом столбце
   adiw ZL,4               ; в этом столбце не было нажатия, перемещение Z
                           ; на 4 кнопки дальше
   ; чтение столбца 2 (Col2)
   ldi rmp,0b01011111      ; PB5 = 0
   out pKeyOut,rmp
   in rmp,pKeyInp          ; снова чтение строк
   ori rmp,0b11110000      ; снова маскирование старших бит
   cpi rmp,0b11111111      ; нажата кнопка в этом столбце?
   brne KeyRowFound        ; найдена нажатая кнопка в этом столбце
   adiw ZL,4               ; в этом столбце не было нажатия, перемещение Z
                           ; на 4 кнопки дальше
   ; чтение столбца 3 (Col3)
   ldi rmp,0b01101111      ; PB4 = 0
   out pKeyOut,rmp
   in rmp,pKeyInp          ; последнее чтение строк
   ori rmp,0b11110000      ; снова маскирование старших бит
   cpi rmp,0b11111111      ; нажата кнопка в этом столбце?
   breq NoKey ; неожиданно обнаружилось, что не нажата кнопка ни в одном
              ; из столбцов
KeyRowFound:               ; найден столбец, где нажата кнопка, теперь
                           ; надо узнать, в какой строке
   lsr rmp                 ; сдвиг лог.  0 влево, бит 0 при этом вдвигается
                           ; в признак переноса
   brcc KeyFound           ; выдвинулся лог. 0, это значит что клавиша найдена
   adiw ZL,1               ; перейти к следующей кнопке в этом столбце
   rjmp KeyRowFound        ; повторить сдвиг
KeyFound:                  ; найдена нажатая кнопка
   lpm                     ; прочитать из таблицы код кнопки в регистр R0
   rjmp KeyProc            ; продолжить обработку кнопок
NoKey:
   rjmp NoKeyPressed       ; не была найдена нажатая кнопка
;
; Таблица кодов кнопок для преобразования
;
KeyTable:
.DB 0x0A,0x07,0x04,0x01 ; первый столбец, кнопки *, 7, 4 и 1
.DB 0x00,0x08,0x05,0x02 ; второй столбец, кнопки 0, 8, 5 и 2
.DB 0x0B,0x09,0x06,0x03 ; третий столбец, кнопки #, 9, 6 и 3

Как избавиться от дребезга контактов (дебоунсинг)

У подпрограммы KeyProc и NoKeyPressed можно добавить дебоусинг нажатой кнопки. Это можно сделать, к примеру, добавив счетчик, который будет считать вверх, пока будет идентифицирована одна и та же кнопка. Эти повторы идентификации должны продолжаться в течение примерно 50 миллисекунд. Подпрограмма NoKeyPressed очистит счетчик, и этим будут исключены ложные срабатывания определения нажатой кнопки. Поскольку время опроса зависит от других требований по интервалам времени обработки в общей программе AVR, то конкретная реализация подавления дребезга здесь не показана.

Недостатки, что еще можно улучшить

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

Внутренние нагрузочные резисторы микроконтроллера AVR (pull-up) имеют номинал около 50 кОм. Длинные провода или работа в условиях сильных помех могут привести к неустойчивому опросу клавиатуры. Чтобы снизить чувствительность к шумам и помехам, добавьте на сигналы строк Row4..Row1 внешние нагрузочные резисторы подходящего номинала (1..10 кОм).

Еще один недостаток схемы в том, что для работы клавиатуры требуется 7 портов GPIO микроконтроллера. Модификация с использованием цифроаналогового преобразователя (ЦАП, Analog-Digital Convertor, ADC) и цепочки резисторов более экономична и позволяет задействовать меньше ножек микроконтроллера.

[3. Подключение к ADC с использованием резисторной матрицы]

Большинство микроконтроллеров AVR серий Tiny и Mega в настоящее время имеют в своем составе ЦАП (ADC). Без дополнительной внешней аппаратуры ADC может измерить аналоговое напряжение с точностью 10 бит. Если хотите сохранить ножки GPIO и применить для чтения клавиатуры ADC, то Вы как-то должны заставить клавиатуру генерировать разное напряжение в зависимости от того, какая кнопка нажата. Это задача для резисторной матрицы.

Резисторная матрица

На рисунке показано, как устроена резисторная матрица. Строки матрицы подключены к земле (- источника питания), и между столбцами подключены соединенные в стек резисторы. Строки подключены к также к стеку резисторов, но подключенных к + питания (например, 5V). Вход АЦП (канал ADC0) заблокирован конденсатором 1 нФ (1000 пФ). Этот конденсатор и сопротивление резисторов матрицы образуют ФНЧ, который всегда необходим на входе ADC, так как ADC не может правильно оцифровать слишком высокие частоты, которые могут быть вызваны перепадами сигнала при нажатиях на кнопки.

Рассмотрим на примере, как работает чтение клавиатуры с использованием ADC. Если нажата кнопка «5», то активизируется следующий делитель напряжения:

1 кОм + 820 Ом = 1.82 кОм нижнее плечо (подключенное к земле),
3,3 кОм + 680 Ом + 180 Ом = 4.16 кОм верхнее плечо (подключенное к +5V).

При рабочем напряжении 5V на выходе делителя получится напряжение:
(5 * 1. 82) / (1.82 + 4.16) = 1.522V

Это напряжение попадет на вход АЦП. Если принять допуск на номинал резисторов 5%, то результирующее напряжение будет между 1.468 и 1.627 вольтами. 10-битный АЦП преобразует это напряжение (если у ADC опорное напряжение то же самое, что и у матрицы, 5V) в значение между 300 и 333. Если мы проигнорируем два младших бита результата (например, разделим результат ADC на 4 сдвигом или если применить левое выравнивание результата, когда ADC это позволяет), это даст 8-битное значение в диапазоне 74..78. Любое нажатие кнопки на клавиатуре даст соответствующий диапазон значений на выходе ADC, который по таблице можно преобразовать в код нажатой кнопки.

Напряжения и распознавание кнопок

Комбинации резисторов в делителе матрицы дадут напряжения, которые собраны в следующую таблицу. Приведены диапазоны напряжений, приведенные к 8-битному результату преобразования ADC. 8-битный результат можно более оптимально использовать для детектирования различий между кнопками.

Кнопка Напряжение, V 8-битный результат ADC Детектирование
(из значения ADC)
min nom max min nom max
1 0.225 0.248 0.272 11 13 14 7
2 0.396 0.434 0.474 20 22 25 18
3 0.588 0.641 0.698 29 33 36 28
4 0. 930 0.969 1.048 47 49 54 42
5 1.438 1.522 1.627 74 78 84 64
6 1.959 2.020 2.139 99 103 110 91
7 2.563 2.688 2.809 130 137 144 121
8 3.285 3.396 3.500 167 173 180 156
9 3.740 3.832 3.917 190 195 201 185
* 4.170 4.237 4.298 212 216 221 207
0 4. 507 4.550 4.588 229 232 235 225
# 4.671 4.700 4.726 238 240 242 237

Как можно видеть из таблицы, нет перекрытия уровней напряжения при детектировании нажатий различных кнопок, при учете допуска на номинал резисторов 5%. Если захотите поэкспериментировать с другими комбинациями резисторов, то можете скачать лист в формате Excel и Open Office [4], который может производить нужные вычисления для составления таблицы преобразования.

Советы по использованию аппаратного АЦП микроконтроллеров AVR

Чипы ATtiny часто позволяют использовать для опорного напряжения АЦП только внутреннее опорное напряжение или напряжение источника питания. Для опроса клавиатуры в качестве опорного напряжения для АЦП подходит только вариант с напряжением источника питания в качестве опорного. Эта опция должна быть настроена при инициализации ADC, как только программа стартует (после сброса или включения питания).

Многие чипы ATmega могут брать опорное напряжение для ADC с внешнего вывода, AREF. Этот вывод может работать либо как вход, либо как выход. Он будет выходом, если в качестве опорного для ADC выбрано внутренне опорное напряжение, или напряжение источника питания. В этом случае к ножке AREF и к земле должен быть подключен конденсатор, чтобы уменьшить шумы и помехи на опорном напряжении. AREF работает как вход, если настроен выбор внешнего источника опорного напряжения. В этом случае опорное напряжение для ADC поступает от внешнего источника. Если опорное напряжение предоставляет внешний источник, то и матрица резисторов клавиатуры также должна быть запитана от этого же источника. Имейте в виду, что приведенная схема матрицы может потреблять ток до 10 мА, это сделано для уменьшения чувствительности к помехам.

Чипы ATmega позволяют питать ADC от внешнего отдельного источника питания через дополнительный вывод корпуса (AVCC), чтобы дополнительно снизить шумы. Если ADC используется только для клавиатуры, то из-за низкой используемой точности преобразования (8 бит) нет необходимости применять отдельный источник питания для вывода AVCC, и этот вывод может быть напрямую подключен к обычному напряжению питания. Если все же другие каналы ADC используются для других точных измерений, то рекомендуется подключить вывод AVCC к напряжению питания через дроссель номиналом около 22 мкГн, и между выводом AVCC и землей должен быть подключен блокирующий конденсатор 100 нФ (0.1 мкФ).

Инициализация и чтение результата преобразования ADC

Для чтения напряжений, которые генерирует матрица клавиатуры, нужен только один канал ADC. ADC инициализируется один раз, когда запускается программа микроконтроллера (включение питания или сброс). Два примера кода показывают: в одном примере последовательность запуска одиночного преобразования, где используется ATmega8, и в другом примере управляемый прерываниями запуск ADC, этот пример для ATtiny13.

ATmega8: ручной запуск преобразования ADC

Первый пример показывает подпрограмму для ATmega8, без прерываний, с ручным запуском и остановом ADC. Сигнал от клавиатурной матрицы приходит на канал ADC0.

.DEF rKey =R15   ; Регистр для хранения результата ADC
.DEF rmp = R16    ; Регистр общего назначения
   ; установка канала 0 мультиплексора, с левым выравниванием 
   ; результата, AREF берется от AVCC
   ldi rmp,(1<<REFS0)|(1<<ADLAR) ; ADMUX канал 0, AREF от AVCC
   out ADMUX,rmp
   ; включение ADC, запуск конверсии, делитель скорости = 128
   ldi rmp,(1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
   out ADCSRA,rmp
   ; ожидание, пока не завершится преобразование
WaitAdc1:
   ; проверка бита ADSC, конверсия завершена если этот бит == 0
   sbic ADCSRA,ADSC  ; конверсия завершена?
   rjmp WaitAdc1     ; еще нет
   ; чтение старшего байта (MSB) результата преобразования ADC
   in rKey,ADCH
   ; выключение ADC
   ldi rmp,(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
   out ADCSRA,rmp

Пожалуйста имейте в виду, что это одиночное преобразование требует примерно 25 * 128 тактовых циклов, на тактовой частоте 1 МГц время преобразования составит 3. 2 миллисекунды. Это довольно значительная трата времени, поэтому такой способ получения результата ADC допустим только в том случае, если Вам ничего не надо делать во время задержки на ожидание преобразования (за исключением того, что будет происходить в обработчиках прерываний).

ATtiny13: автозапуск конверсии ADC, с использованием прерываний

Даже ATtiny13 с её 8 ножками может прочитать матрицу клавиатуры, если задействовать ADC (мы не сможем традиционным образом подключить матрицу клавиатуры 3×4, потому что у ATtiny13 не хватит ножек I/O).

В этом примере выбран следующий способ преобразования: напряжение постоянно считывается с канала ADC3 (вывод 2 ATtiny13), и после того как преобразование завершится, следующее преобразование запустится автоматически.

;
; Настройка ADC, первый запуск конверсии
;
   ; PB3=ADC3, этот вход используется для чтения клавиатуры
   ldi rmp,0b00001000   ; отключение цифрового драйвера PB3,
                        ; это экономит потребляемую энергию
   out DIDR0,rmp
   ; Опорное напряжение = напряжению питания, левое выравнивание
   ; результата преобразования, ADMUX переключен на ADC3
   ldi rmp,0b00100011   ; опорное напряжение = напряжению питания,
                        ; выбор ADC3
   out ADMUX,rmp
   ; выбрана опция автостарта преобразования
   ldi rmp,0b00000000   ; постоянно запускающиеся сами по себе
                        ; преобразования (free-running, автостарт). 
   out ADCSRB,rmp
   ; запуск ADC, разрешение прерывания, выбор делителя тактовой частоты
   ldi rmp,0b11101111 ; старт ADC, автостарт
   out ADCSRA,rmp       ; прерывание разрешено, делитель тактов 128
; инициализация завершена

Использование прерывания по завершению преобразования требует определения таблицы прерываний, где будет вектор соответствующего обработчика прерывания (rjmp intadc).

;
; Векторы сброса и прерываний ATtiny13
;
.CSEG          ; ассемблирование в сегмент кода,
.ORG $0000     ; с самого его начала
   rjmp main   ; Вектор сброса (Reset)
   reti ; Int0, вектор внешнего прерывания
   reti ; PCINT0, вектор прерывания по изменению уровня
   reti ; TC0, вектор прерывания по переполнению таймера 0
   reti ; вектор прерывания готовности EEPROM
   reti ; вектор прерывания аналогового компаратора
   reti ; вектор прерывания TC0 CompA (событие сравнения)
   reti ; вектор прерывания TC0 CompB (событие сравнения)
   reti ; вектор прерывания WDT
   rjmp intadc ; вектор прерывания по завершению конверсии ADC
;

Само собой, для использования прерываний должен быть инициализирован стек, и должен быть установлен флаг общего разрешения прерываний (SEI).

Обработчик прерывания ADC читает результат преобразования. Поскольку выбрано левое выравнивание результата, то достаточно прочитать только старший (MSB) байт результата:

;
; Обработчик прерывания (ISR) для завершения конверсии ADC
;
.DEF rKey = R15   ; Регистр для хранения результата ADC
intadc:
   in rKey,ADCH   ; чтение старшего (MSB) байта преобразования
   reti           ; возврат из прерывания
;

Регистр rKey постоянно дает текущее состояние резисторной матрицы клавиатуры.

Декодирование результата ARC, получения кода нажатой кнопки

Результат преобразования ADC сам по себе не очень-то полезен. Напряжения и соответствующие им результаты преобразования ADC не укладываются в простые математические правила (должно быть, номиналы резисторов 4.7 — 5.6 — 6.8 — 8.2 придумал пьяный профессор математики, и формула V = R1 / (R1 + R2) не очень проста для обработки). Поэтому лучше всего использовать табличный метод для получения кодов кнопок. Таблица не получится примитивной, потому что у нас есть 256 возможных различных результатов преобразования ADC, и нам хотелось бы получить таблицу поменьше.

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

KeyTable:
.DB 7, 255, 18, 1, 28, 2, 42, 3, 64, 4, 91, 5
.DB 121, 6, 156, 7, 185, 8, 207, 9, 225, 10, 237, 0, 255, 11

Здесь первый байт это значение сравнения для результата преобразования, а второй байт это код кнопки, если значение сравнения больше, чем наш результат. Если результат находится в диапазоне между 0 и < 7, то это означает, что не была нажата ни одна из кнопок (код клавиши 255), если между 7 и < 18, то код кнопки 1, и так далее.

Или можно использовать сразу ASCII-коды для кнопок:

KeyTable:
.DB 7, 0 , 18, '1', 28, '2', 42, '3', 64, '4', 91, '5'
.DB 121, '6', 156, '7', 185, '8', 207, '9', 225, '*', 237, '0', 255, '#'

Код декодирования будет наподобие такого:

;
; Конвертация результата преобразования ADC в код кнопки
;
GetKeyCode:
   ; сначала нужно сделать копию результата, потому что результат
   ; может измениться во время проверки
   mov R1,rKey ; копирование результата ADC в регистр R1
   ldi ZH,HIGH(2*KeyTable)    ; Z указывает на таблицу преобразования
   ldi ZL,LOW(2*KeyTable)
GetKeyCode1:
   lpm               ; чтение значения сравнения из таблицы
   cp R1,R0          ; сравнение значения из таблицы и результата ADC
   brcs GetKeyCode2  ; результат меньше, чем табличное значение,
                     ; кнопка идентифицирована
   inc R0            ; проверка, достигнут ли конец таблицы
   breq GetKeyCode2  ; таблица закончилась
   adiw ZL,2         ; переход к следующей записи в таблице
   rjmp GetKeyCode1  ; переход к сравнению следующей записи
GetKeyCode2:
   adiw ZL,1         ; Z указывает на код кнопки
   lpm               ; чтение кода кнопки в регистр R0
;

Здесь конечно же есть проверка, что не одна их кнопок не нажата (в этом случае R0 = 0xFF, а если используется кодировка кнопок ASCII, то R0 = 0) и мы можем устранить ложные срабатывания (если проверить, что один и тот же код клавиши прочитан 20 или большее количество раз).
Experiences

Первые эксперименты показали, что слишком большие значения резисторов (сначала резисторы были в 10 раз больше по номиналу) делают чтение клавиатуры с использованием АЦП слишком чувствительной к высокочастотным помехам. К примеру, клавиатура отказывалась нормально работать, когда рядом находился передатчик VHF (УКВ) с мощностью около 2 Вт.

[Ссылки]

1. Connecting a keypad to an AVR site:avr-asm-tutorial.net.
2. AVR245: кодовый замок с клавиатурой 4×4 и I2C LCD.
3. Доступ к портам I/O AVR на языке C (GCC, WinAVR).
4. 131121-adc-keyboard.zip.
5. AVR240: клавиатура 4×4, пробуждение AVR от нажатия.

Нажать и распознать ‒ микроконтроллер, Bascom-AVR и несколько кнопок | mp42b — Про транзисторы и прочее

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

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

Нефиксируемые, срабатывающие на замыкание.

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

1. Начнём с простой схемотехники

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

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

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

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

А именно:

  • Каждая из подключенных кнопок занимает одну линию порта микроконтроллера. Целый отдельный вывод. И если на роскошном ATmega328P это не выглядит слишком большой расточительностью, то на крохах вроде ATtiny10, ATtiny13 или ATtiny45 может оказаться просто критичным для существования самой схемы.
  • Для каждой из подключенных кнопок необходимо разводить на плате отдельные печатные проводники или подключать кнопки отдельными проводами. Сказывается отрицательно на стремлении к миниатюризации конструкции.
  • К каждой кнопке по умолчанию прилагается свой отдельный резистор подтяжки. Для снижения эффекта «дребезга контактов» может прилагаться и отдельный конденсатор. А если задействовать срабатывание от нажатий кнопки по прерываниям, как вот здесь или здесь, то может потребоваться и по дополнительному разделительному диоду.

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

А из главных преимуществ ‒ возможность подключения практически любого (разумного) количества кнопок на одну линию порта микроконтроллера.

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

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

А наша схема делителя напряжения может выглядеть примерно так:

2.

Добавим немного расчётов

Перед сборкой понадобится рассчитать или хотя бы примерно прикинуть параметры делителя.

Например:

  • Мне необходимо использовать и распознавать нажатия от 8-ми кнопок. Соответственно делитель должен выдавать восемь уровней напряжения. То есть содержать минимум восемь последовательно соединенных резисторов, по одному на каждую кнопку.
  • Ток, протекающий через делитель, с одной стороны не должен быть слишком велик, ради экономии энергии источника питания, с другой, должен быть достаточным для определения срабатывания отдельной кнопки микроконтроллером. Я остановился на значении в 3-5 мА (это меньше, чем у индикаторного светодиода), но вполне возможны и другие варианты.
  • Сам делитель будет запитываться от источника питания с напряжением в 5 вольт.

Дальше закон Ома.

5 V / 0.003 А = 1667 Ом ‒ Это сопротивление всего делителя.

По 208 Ом на каждый из входящих в него резисторов.

У меня под рукой были резисторы на 180 Ом. При их использовании ток, протекающий через делитель, должен быть около 3.5 мА. Тоже вполне подойдёт.

Соответственно при последовательном нажатии кнопок (от одной до восьми) на выходе делителя напряжения теоретически получим 0.63, 1.26, 1.89, 2.52, 3.15, 3.78, 4.41 и 5.04 вольт.

3. Поясним общий принцип действия

Для распознавания нажатых кнопок задействуем аналого-цифровой преобразователь ‒ АЦП. Такой, и даже не один, есть практически в любом микроконтроллере AVR. Например в ATmega328P АЦП восьмиканальный для микроконтроллера в TQFP-корпусе и шестиканальный для микроконтроллера в DIP-корпусе. Нам будет достаточно использовать всего один канал. Каждый канал 10-ти разрядный, то есть измеряемое напряжение на входе канала может быть представлено в 1024 отсчётах: минимум ‒ 0, максимум ‒ 1023.

Во многих источниках при работе с АЦП советуют не учитывать показания двух младших разрядов в результатах измерений, так как в них мало полезной информации и много информационного шума, в основном наводок и импульсных помех на входе АЦП, пойманных в процессе измерения. Учтём этот полезный совет на будущее, на тот случай, когда будем делать высокоточный цифровой вольтметр. В данном же практикуме он не потребуется. Нам даже не потребуется переводить отсчёты измерения в вольты, преобразуя числа с плавающей запятой, экономя тем самым вычислительный ресурс микроконтроллера. Почему? Читаем дальше.

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

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

Тестовый стенд с ними ‒ «цифровой кирпичик номер 3» ‒ подробно рассматривался в прошлой статье.

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

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

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

5. И реализуем её на практике

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

Нужно добавить к ним делитель напряжения, из резисторов и кнопок. Сделать это можно, например, используя дополнительную беспаечную макетную плату и обычные тактовые кнопки. Мне же показалось удобнее расположить кнопки PBS-10B, срабатывающие на замыкание, на отдельной планке, вырезанной из листового полистирола толщиной 2 мм.

Также понадобятся разноцветные многожильные и одножильные провода, термоусадка для изоляции и однорядный 5-ти контактный разъём для подключения.

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

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

После монтажа кнопок и их соединения делитель выглядит так.

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

Информационный выход делителя напряжения подключим к входу 23 микроконтроллера (канал ADC0 АЦП), а выводы плюса напряжения питания и корпуса подключаются к шине питания на тестовом стенде.

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

6. Приступим к программированию

Вот и дошло дело до программирования микроконтроллера.

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

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

Так же, как и для предыдущей статьи, при подготовке данного раздела использовались материалы с замечательного сайта AVR Project.ru ‒ Проекты на микроконтроллерах AVR.

В частности тщательно изучались следующие статьи:

  1. ЗАДЕЙСТВУЕМ АЦП. ВОЛЬТМЕТР НА AVR.
  2. Аналогово-Цифровой Преобразователь (АЦП)
  3. ПОНИЖАЕМ ЭНЕРГОПОТРЕБЛЕНИЕ УСТРОЙСТВ НА МИКРОКОНТРОЛЛЕРАХ AVR

Эта информация оказалась очень полезной для понимания работы АЦП микроконтроллера и особенностей его программирования.

А ещё полезным оказалось заглянуть в стандартную документацию Bascom-AVR, при необходимости помогая себе онлайн-переводчиком. Ну и техническое описание к микроконтроллеру тоже не будет лишним.

На основании прочитанного приступим к программированию аналого-цифрового преобразователя в среде Bascom-AVR.

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

Config Adc = Single, Prescaler = Auto, Reference = Avcc

Здесь указаны следующие параметры:

  • Adc = Single ‒ работа преобразователя в режиме однократного считывания. Если вместо параметра Single поставить Free АЦП будет работать в непрерывном режиме измерений
  • Prescaler = Auto ‒ делитель частоты тактового генератора микроконтроллера для АЦП. От него зависит с какой частотой будет работать АЦП. В данном случае компилятор выбирает значение автоматически. Также можно установить значение вручную (2, 4, 8, 16, 32, 64).
  • Reference = Avcc ‒ выбор источника опорного напряжения. Aref ‒ внешний источник, подключаемый к входу Aref, Avcc ‒ напряжение питания схемы, Internal ‒ внутренний источник опорного напряжения на 2.56 в.

Далее с помощью команды

Start Adc

запускаем функционал АЦП в работу.

Если вдруг нам понадобится сообщить микроконтроллеру об остановке процесса измерений АЦП даём команду

Stop ADC

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

W = Getadc(0)

,которая сохраняет измеренные значения в заданной нами числовой переменной. В качестве параметра указан опрашиваемый номер канала АЦП. Для ATmega328P-PU могут использоваться значения от 0 до 5, соответствующие выводам микроконтроллера ADC0-ADC5.

Напомню, что данные сохраняются не в вольтах, а в отсчётах разрядности АЦП, от 0 до 1023, где 0 соответствует минимальному значению напряжения ‒ уровню земли (на входе АЦП стоит резистор подтяжки к общему проводу), а 1023 соответствует максимальному опорному ‒ у нас это напряжение питания +5 вольт.

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

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

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

Прошивка в виде откомпилированного .hex-файла находится здесь.

Вот участок кода с основным циклом обработки.

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

При нажатии на кнопки на индикаторах отображаются измеренные АЦП значения.

Показания не стабильны, при одних и тех же нажатых кнопках и нескольких измерениях можно заметить, что значения «пляшут» или «плавают», меняются на несколько единиц (относительно некоторых базовых величин).

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

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

Это можно использовать для определения самого факта одновременного нажатия кнопок.

Далее преобразуем нашу программу таким образом, чтобы при нажатии на ту или иную кнопку вместо значения отсчётов АЦП отображался номер нажатой кнопки. Вместо использования нескольких условных операторов IF-ELSE нам поможет конструкция CASE.

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

Основной цикл программы теперь выглядит так.

В данном варианте программы также задействованы сегменты светодиодной шкалы. При ненажатых кнопках светятся сегменты 9-10, при нажатых кнопках ‒ сегменты от 1 до 8, по номеру нажатой кнопки.

Исходный текст варианта программы с определением нажатой кнопки находится здесь.

Прошивку в виде откомпилированного .hex-файла можно скачать отсюда.

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

В этом случае можно определять и отбрасывать часть (но, к сожалению, не все) ошибочных комбинаций при одновременно нажатых кнопках.

Также, чем больше сужаем диапазон, тем больше вероятность ошибочного определения уже и для правильного нажатия кнопки.

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

Да, сам факт одновременного нажатия нескольких кнопок он определяет.

При этом возросшее число ошибочных определений данное преимущество сводит на нет.

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

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

При изменении состояния на входе ADC0 микроконтроллера

  • Возникает программное прерывание
  • В подпрограмме его обработки IntADC устанавливается флаг ADCFlag
  • Микроконтроллер просыпается, начинает выполнение основной программы, проверяет состояние флага и при его установленном значении производит замер на входе АЦП.
  • После чего измеренное значение выводится на индикаторы, а микроконтроллер опять засыпает.

Здесь также сделана попытка использования режима ADСNOISE.

В этом режиме «создаются более благоприятные условия для аналого-цифрового преобразования с повышенной разрешающей способностью за счет снижения влияния шумов на результат измерения. При использовании режима ADСNOISE прекращается тактирование процессора, памяти программ, а также системы ввода/вывода, но продолжают работу АЦП и внешние прерывания».

В данный режим отдельные модели микроконтроллеров могут быть переведены командой

Config Powermode = ADCNOISE

Также в коде для снижения энергопотребления переводится в режим Shutdown и микросхема-контроллер сегментных индикаторов MAX7219.

Участок основного цикла программы здесь выглядит так.

А это код обработчика прерывания.

Исходный текст третьего варианта программы (с прерыванием и спящим режимом) с подробными комментариями находится здесь.

Прошивку в виде откомпилированного .hex-файла можно скачать отсюда.

По внешним результатам работы третий вариант программы (с использованием прерываний) практически не отличается от второго.

7. Про энергопотребление

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

Надежда, к сожалению, не оправдалась.

Для всех трёх вариантов программы ток потребления микроконтроллера составлял примерно 1.8 мА при ненажатых кнопках и около 2.0 мА при их нажатии.

Вся схема потребляет от 20 до 28 мА.

Вполне вероятно я чего-то (или многого и важного) ещё не учёл или где-то (быть может во многом) ошибся. Если у вас возникнут идеи или советы по данному поводу ‒ большая просьба поделиться ими в комментариях.

8. Про прошивку и FUSE-биты

Все три варианта прошивки занимают в памяти микроконтроллера меньше 4 kB, а это значит, что для компиляции вполне подойдет демонстрационная и бесплатная версия среды Bascom-AVR.

Какой бы вариант прошивки вы не использовали, откомпилировать программу в Bascom-AVR и залить её в микроконтроллер можно с помощью способа, подробно описанного вот в этой статье.

Возможно при этом вам пригодится картинка с настройками FUSE-бит из CodeVisionAVR.

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

9. Окончательный результат ‒ это всего лишь начало новой конструкции

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

Да, это совсем не готовая конструкция, а всего лишь отработка одной из её частей, «цифровой кирпичик номер 4».

При желании вы вполне можете применить её в каком-то из своих устройств, например в кодовом замке, цифровом пианино, проводном пульте управления, схеме освещения умного дома или в любом другом.

Пока ещё рано говорить о том, где собираюсь применить её я. Тем более, что остались не совсем ещё решённые вопросы и ещё есть куда стремиться.

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

06 сентября 2020 года.

С уважением, Ваш @mp42b.

<— Предыдущая статья | Содержание 2019-2020 | Следующая статья —>

#простые вещи #Bascom-avr #кнопки и ацп #mp42b #микроконтроллеры_mp42b

7.3 подключение кнопок к контактам микроконтроллера PIC

7.3 Кнопки

Кнопки представляют собой механические устройства, используемые для разрыва или соединения двух точек. Они бывают разных размеров и с разным назначением. Кнопки, которые здесь используются, также называются «дип-кнопками». Они припаиваются непосредственно к печатной плате и широко используются в электронике. Они имеют четыре контакта (по два на каждый контакт), что придает им механическую устойчивость.

Пример подключения кнопок к контактам микроконтроллера

Функция кнопок проста.Когда мы нажимаем кнопку, два контакта соединяются вместе и устанавливается соединение. Тем не менее, не все так просто. Проблема заключается в природе напряжения как электрической величины и в несовершенстве механических контактов. То есть, прежде чем контакт установится или прервется, есть небольшой промежуток времени, когда может возникнуть вибрация (колебание) из-за неравномерности механических контактов или из-за разной скорости нажатия на кнопку (это зависит на человека, который нажимает кнопку).Термин, данный этому явлению, называется ПЕРЕКЛЮЧЕНИЕМ (КОНТАКТОМ) DEBOUNCE. Если это упустить при написании программы, может произойти ошибка, или программа может выдать более одного выходного импульса для одного нажатия кнопки. Чтобы этого избежать, мы можем ввести небольшую задержку при обнаружении замыкания контакта. Это гарантирует, что нажатие кнопки интерпретируется как одиночный импульс. Задержка устранения дребезга создается программно, и продолжительность задержки зависит от кнопки и ее назначения.Проблема может быть частично решена путем добавления конденсатора к кнопке, но лучше всего подойдет хорошо продуманная программа. Программу можно корректировать до полного устранения ложных срабатываний. На изображении ниже показано, что на самом деле происходит при нажатии кнопки.

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

кнопка макрос port, pin, hilo, label
Порт — порт микроконтроллера, к которому подключена кнопка. В случае микроконтроллера PIC16F84 это может быть PORTA или PORTB.
Пин — это пин порта, к которому подключена кнопка.
HiLo может принимать значение «0» или «1», что соответствует состоянию, когда кнопка нажата.
Метка — адрес назначения для перехода к сервисной подпрограмме, которая будет обрабатывать событие (нажатие кнопки).

Пример 1:

кнопка PORTA, 3, 1, Button1

Кнопка T1 подключена к контакту RA3 и к массе через подтягивающий резистор, поэтому при нажатии она генерирует логическую единицу. Когда кнопка отпущена, программа переходит к метке Button1.

Пример 2:

кнопка PORTA, 2, 0, кнопка 2

Кнопка T1 подключена к контакту RA1 и к массе через нагрузочный резистор, поэтому при нажатии она генерирует логический ноль.Когда кнопка отпущена, программа переходит к метке Button2.

Следующий пример иллюстрирует использование макроса кнопки в программе. Кнопки подключаются к источнику питания через подтягивающие резисторы и при нажатии подключаются к массе. Переменная cnt отображается на светодиодах порта B; cnt увеличивается нажатием кнопки RA0 и уменьшается нажатием кнопки RA1.

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

Идея проста. Каждые 10 мс состояние кнопки будет проверяться и сравниваться с предыдущим состоянием ввода.Это сравнение может обнаружить нарастающий или спадающий фронт сигнала. В случае, если состояния одинаковы, изменений, по-видимому, не произошло. При изменении с 0 на 1 возникал нарастающий фронт. Если последующие 3 или 4 проверки дают один и тот же результат (логический), мы можем быть уверены, что кнопка нажата.

Микроконтроллер интерфейса

— обзор

2.1.3 Архитектура mbed LPC1768

Блок-схема архитектуры mbed показана на рис.2.2. Возможно и полезно связать показанные здесь блоки с реальным mbed. Сердцем mbed является микроконтроллер LPC1768, который хорошо виден на обоих рис. 2.1 и 2.2. Сигнальные контакты mbed, как показано на рис. 2.1C, подключаются непосредственно к микроконтроллеру. Таким образом, когда в следующих главах мы будем использовать цифровой вход или выход mbed, аналоговый вход или любое другое периферийное устройство, мы будем подключаться непосредственно к микроконтроллеру внутри mbed и полагаться на его функции.Интересным дополнением к этому является то, что LPC1768 имеет 100 контактов, а mbed — только 40. Поэтому, когда мы углубимся в понимание LPC1768, мы обнаружим, что есть некоторые функции, которые просто недоступны для нас, пользователей mbed. . Однако вряд ли это является ограничивающим фактором.

Рисунок 2.2. Блок-схема архитектуры mbed LPC1768.

На этом mbed есть второй микроконтроллер, который взаимодействует с USB. Это называется интерфейсным микроконтроллером на рис.2.2 и является самой крупной микросхемой на нижней стороне печатной платы mbed. Продуманность конструкции аппаратного обеспечения mbed заключается в том, как это устройство управляет USB-соединением и действует как USB-терминал для хост-компьютера. В большинстве случаев он получает файлы программного кода через USB и передает эти программы в 16-мегабитную память (8-контактная микросхема на нижней стороне mbed), которая действует как «USB-диск». Когда программа загружается в mbed, она помещается на USB-диск. При нажатии кнопки сброса программа с самой последней отметкой времени передается во флэш-память LPC1768, и начинается выполнение программы.Передача данных между интерфейсным микроконтроллером и LPC1768 осуществляется в виде последовательных данных через порт UART (что означает универсальный асинхронный приемник/передатчик — канал последовательной передачи данных, не будем сейчас вдаваться в подробности) порта LPC1768.

Блок «Управление питанием» состоит из двух регуляторов напряжения, расположенных по обе стороны от индикатора состояния. Также имеется микросхема ограничения тока, которая находится в левом верхнем углу mbed. mbed может питаться от USB; это распространенный способ его использования, особенно для простых приложений.Если вы хотите или должны быть независимыми от USB-соединения, или для более энергоемких приложений, или тех, которые требуют более высокого напряжения, mbed также может получать питание от внешнего входа от 4,5 В до 9,0 В, подаваемого на контакт 2 ( с маркировкой VIN). Питание также может поступать от контактов 39 и 40 mbed (обозначенных как VU и VOUT соответственно). Соединение VU подает 5 В, взятое почти непосредственно из соединения USB; следовательно, он доступен только в том случае, если USB подключен. На контакт VOUT подается регулируемое напряжение 3,3 В, которое поступает либо от входа USB, либо от входа VIN.

mbed имеет несколько источников синхронизации, обозначенных блоком справа от диаграммы. Два микроконтроллера используют общий источник синхронизации; это кварцевый генератор, серебристый прямоугольник чуть выше LED4 на рис. 2.1B. LPC1768 использует это для поддержания внутренней тактовой частоты 96 МГц. «Ethernet PHY», микросхема, направленная к разъему USB на нижней стороне платы, имеет собственный тактовый генератор, расположенный между микросхемой памяти и интерфейсным микроконтроллером.

Для тех, кто склонен — и мы будем время от времени обращаться к ним — принципиальные схемы mbed LPC1768 доступны на веб-сайте mbed, указанном в Ref.[3].

Флэш-код и подключение микроконтроллера к ПК

Для визуализации данных в реальном времени в Excel с надстройкой Data Streamer вам потребуется подключить к нему микроконтроллер и флэш-код.

Флэш-код

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

Ардуино

  1. Установите Arduino IDE из магазина Microsoft.

  2. Загрузите файлы кода Arduino из соответствующего плана урока Hacking STEM.

  3. Откройте загруженный файл, чтобы запустить приложение Arduino.

  4. В приложении Arduino выберите: Tools > Port > COM 3 (Arduino/Genuino Uno). Ваш порт может отличаться от COM3.

  5. Выберите Инструменты > Плата: Arduino/Genuino Uno .

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

микро: бит

  1. Загрузите файл .шестнадцатеричные файлы кода из соответствующего плана урока Взлом плана урока STEM.

  2. Подключите micro:bit к компьютеру с помощью USB-кабеля. Установите драйвер mbed.

  3. В проводнике перейдите к файлу micro:bit. Он будет отображаться как внешнее запоминающее устройство, такое как флэш-накопитель или жесткий диск.

  4. Откройте второе окно проводника и перейдите к папке Downloads .Убедитесь, что вы видите оба окна.

  5. Выберите файл .hex в папке «Загрузки», затем перетащите его в окно micro:bit.

  6. Как только светодиодный индикатор перестанет мигать, код будет загружен на плату микроконтроллера micro:bit.

Теперь пришло время начать потоковую передачу данных в Excel.

Подключить микроконтроллер

Выберите Подключить устройство , чтобы выбрать микроконтроллер (Arduino, micro:bit).Появится подменю, позволяющее выбрать устройство, которое в данный момент подключено к вашему компьютеру.

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

Нужна дополнительная помощь?

Вы всегда можете обратиться к эксперту в техническом сообществе Excel или получить поддержку в сообществе ответов.

См. также

Что такое стример данных?

Включить надстройку Data Streamer

Начните потоковую передачу данных в реальном времени с помощью надстройки Data Streamer.

Расширенные настройки надстройки Data Streamer

Параметры рабочей книги для надстройки Data Streamer

Фотон | Быстрый старт | Частица

Что в коробке

Ваш новый Фотон! Обратите внимание, что многие изображенные компоненты будут включены только в том случае, если вы приобрели комплект Photon Kit.

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

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

Давайте быстро пробежимся по тому, что вы видите.

Что на нем?

Модуль Wi-Fi

Вероятно, поэтому вы купили свое устройство — модуль Wi-Fi позволяет вашему Photon’у обмениваться данными с Интернетом.Он подключает ваше устройство к Интернету так же, как ваш смартфон может подключаться к сети Wi-Fi. Не нажимайте на модуль Фотона. Это вызывает сброс и, как правило, не очень хорошо для Фотона.

Микроконтроллер

Микроконтроллер — это мозг вашего устройства. Он запускает ваше программное обеспечение и сообщает вашему прототипу, что делать. В отличие от вашего компьютера, он может запускать только одно приложение (часто называемое прошивкой или встроенным приложением ).Это приложение может быть простым (всего несколько строк кода) или очень сложным, в зависимости от того, что вы хотите сделать. Микроконтроллер взаимодействует с внешним миром с помощью контактов.

Контакты

Контакты — это входные и выходные части микроконтроллера, которые выставлены на боковых сторонах вашего устройства. Штыри GPIO могут быть подключены к датчикам или кнопкам, чтобы слушать мир, или они могут быть подключены к огням и зуммерам, чтобы воздействовать на мир. Есть также контакты, которые позволяют вам питать ваше устройство или двигатели и выходы за пределами вашего устройства.Есть контакты для связи Serial/UART и контакт для перезагрузки вашего устройства.

Кнопки и светодиоды

На вашем Photon есть несколько замечательных кнопок и светодиодов, облегчающих использование.

Кнопка SETUP находится слева, а кнопка RESET — справа. Вы можете использовать эти кнопки, чтобы помочь вам установить режим вашего устройства. Светодиод RGB находится в центре вашего фотона, над модулем. Цвет светодиода RGB говорит вам, в каком режиме сейчас находится ваш Photon. Светодиод D7 находится рядом с контактом D7 на вашем Photon, в верхнем правом квадранте.Этот светодиод загорается, когда контакт D7 установлен в состояние HIGH.

  • Программное обеспечение
    • Мобильное приложение Particle для iPhone | Андроид
    • Примечание. Мы настоятельно рекомендуем использовать мобильное приложение для первой настройки.
  • Аппаратное обеспечение
    • Ваше устройство Particle, совершенно новое и только что из коробки!
    • Кабель USB-микро-USB
    • Источник питания для кабеля USB (например, компьютер, аккумулятор USB или блок питания)
    • Ваш iPhone или смартфон Android или Windows
  • Настройки Wi-Fi
    • 2.Маршрутизатор
    • с поддержкой 4 ГГц
    • Каналы 1-11
    • Шифрование WPA/WPA2
    • В широковещательной сети SSID
    • Не защищен жестким брандмауэром или корпоративной сетью
    • Примечание. Мы не рекомендуем использовать настройки WEP Wi-Fi по соображениям безопасности.
  • Опыт
    • Нет! Это ваш первый проект.

Подключите свой Photon

В этом примере мы впервые подключим ваше устройство к Интернету.Затем мы будем мигать светодиодом D7 на вашем устройстве с помощью вашего смартфона.

Шаг 1. Включите питание устройства

Подключите кабель USB к источнику питания. (Ваш компьютер отлично подходит для этой цели.) Вашему устройству Particle не нужен компьютер для подключения к Wi-Fi. С таким же успехом вы можете подключить устройство к блоку питания, защитному экрану или другому источнику питания, подключенному к контакту VIN.

Как только устройство будет подключено, светодиод RGB на вашем устройстве начнет мигать синим цветом.

Если ваше устройство не мигает синим цветом, удерживайте кнопку SETUP.

Шаг 2a. Подключите Photon к Интернету с помощью веб-приложения для настройки

  • Перейдите на страницу setup.particle.io
  • Нажмите Настройка фотона
  • После нажатия на NEXT вам должен быть представлен файл (photonsetup.html)
  • Открыть файл

После открытия файла:

  • Шаг 5 Подключите ПК к Photon, подключившись к сети с именем PHOTON-...
  • Шаг 6 Настройте учетные данные Wi-Fi

Примечание. Если вы ошиблись при вводе учетных данных, Photon будет мигать темно-синим или зеленым цветом. Вы должны пройти процесс снова (обновив страницу или щелкнув часть процесса повторной попытки) <

  • Шаг 7 Переименуйте свое устройство. Вы также увидите подтверждение, было ли заявлено устройство или нет

Примечание. Убедитесь, что ваш Photon не является частью продукта, прежде чем заявлять права на него.

Зачем отдельный файл?

Мы очень заботимся о безопасности и хотим, чтобы все, что вы делаете, было безопасным.Загрузка локального файла гарантирует, что учетные данные будут отправлены непосредственно в Photon без какой-либо возможности их перехвата.

Шаг 2б. Подключите Photon к Интернету с помощью смартфона

Откройте приложение на телефоне. Войдите или зарегистрируйте учетную запись в Particle, если у вас ее нет.

Нажмите значок плюса и выберите устройство, которое хотите добавить. Затем следуйте инструкциям на экране, чтобы подключить устройство к Wi-Fi. Ваше устройство запоминает до 5 сетей Wi-Fi и автоматически подключается к ним, если находит их.

Это может занять некоторое время, но не волнуйтесь.

После того, как вы подключили свое устройство, оно узнало эту сеть. Ваше устройство может хранить до пяти сетей. Чтобы добавить новую сеть после первоначальной настройки, вы должны снова перевести свое устройство в режим прослушивания и действовать, как указано выше (часть запроса можно пропустить). Если вам кажется, что на вашем устройстве слишком много сетей, вы можете стереть из памяти устройства все известные ему сети Wi-Fi. Вы можете сделать это, продолжая удерживать кнопку SETUP в течение 10 секунд, пока светодиод RGB не начнет быстро мигать синим цветом, сигнализируя об удалении всех профилей.

Шаг 3: Мигайте светодиодом!

Теперь на экране должно появиться приложение Particle, как показано ниже.

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

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

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

Коснитесь D7 , затем digitalНапишите во всплывающем окне. Теперь, когда вы нажимаете на кружок D7, крошечный синий светодиод должен выключаться или включаться!

Поздравляем, вы только что мигнули светодиодом через Интернет с помощью устройства Particle!

Дополнительные примеры аппаратного обеспечения см. в разделе Примеры аппаратного обеспечения.

Кнопочные входы

— Часть 9. Основы микроконтроллера…

Примечание. Компания Microchip недавно внесла некоторые изменения, и их новые версии IDE используют компилятор XC8 для ассемблера, в то время как весь приведенный здесь пример кода создан для компилятора MPASM. Тем не менее, пример кода был портирован на XC8 пользователем tinyelect на нашем канале Discord (которому мы очень благодарны!), а версия кода для XC8 приведена в конце этого руководства для справки. Чтобы увидеть изменения, необходимые для перехода с MPASM на XC8, ознакомьтесь с процессом, которым он поделился.

Еще раз привет! После содержательного последнего урока, я думаю, было бы неплохо немного отдохнуть и подумать о чем-нибудь относительно легком и коротком. Кроме того, на этот раз я не предоставил решение домашнего задания, потому что… как я могу узнать, какая у вас любимая песня? Так что я оставляю это на ваше усмотрение.

Некоторые внимательные читатели этих руководств могут спросить: «Почему мы установили две кнопки и два светодиода и никогда не использовали их вместе?» Готовимся к этому дню! Исправим это упущение.

Сегодняшняя задача будет состоять из двух частей:

  1. Переключать LED1 после каждого нажатия кнопки SW1.
  2. Переключение светодиода 2 все время, пока кнопка SW2 нажата, с задержкой 200 мс.

Код программы для выполнения этой задачи показан ниже:

  

#include "p10f200.inc"

__CONFIG _WDT_OFF & _CP_OFF ​​& _MCLRE_OFF

i    EQU 10   ;Регистр задержки №1

j    EQU 11   ;Регистр задержки № 2

    ОРГ 0x0000    

ИНИТ

    MOVLW ~((1<

    ОПЦИЯ   ;Включить GPIO2 и подтяжки

    MOVLW ~((1 << GP2)|(1 << GP1))    

    TRIS GPIO  ; установите GP1 и GP2 в качестве выходов

КОНТУР

    CALL CHECK_SW1   ;Проверьте переключатель SW1

    CALL CHECK_SW2   ;Проверьте переключатель SW2

    ПЕРЕХОД К ЦИКЛУ

CHECK_SW1   ;Начало подпрограммы CHECK_SW1

    BTFSC GPIO, GP3   ;Проверьте, равен ли GP3 0 (нажат SW1)

    RETLW 0   ; Если не 0, вернуть

    CALL DEBOUNCE_DELAY ;В противном случае выполнить задержку устранения дребезга

    BTFSC GPIO, GP3             ; И снова проверьте GP3

    RETLW 0   ; Если не 0, вернуть

    BTFSS GPIO, GP3             ; В противном случае подождите, пока GP3 равен 0

    GOTO $-1   ;Цикл ожидания

    CALL DEBOUNCE_DELAY ;После установки GP3 (отпуска SW1)

    MOVLW (1 << GP1)            ;Переключить контакт GP1

    XORWF GPIO, F               ;с использованием операции XOR

    RETLW 0   ;И возврат из подпрограммы

CHECK_SW2   ;Начало подпрограммы CHECK_SW1

    BTFSC GPIO, GP0              ;Проверьте, равен ли GP0 0 (нажат SW2)

    RETLW 0   ; Если не 0, вернуть

    CALL DEBOUNCE_DELAY ;В противном случае выполнить задержку устранения дребезга

SW2_LOOP   ;Цикл при нажатии SW2

    BTFSC GPIO, GP0             ;Проверьте, равен ли GP0 0

    RETLW 0   ; Если не 0, вернуть

    MOVLW (1 << GP2)            ;В противном случае переключить контакт

GP2

    XORWF GPIO, F               ;с использованием операции XOR,

    CALL TOGGLE_DELAY      ;выполнить длительную задержку перед следующим переключением

    GOTO SW2_LOOP            ;и возврат к началу цикла

DEBOUNCE_DELAY   ;Здесь запустите подпрограмму DEBOUNCE_DELAY

    MOVLW D'40'   ;Загрузить начальное значение задержки    

    MOVWF i   ;Скопируйте значение в регистр i

    MOVWF j   ;Скопируйте значение в регистр j

DELAY_LOOP   ;Начать цикл задержки

    DECFSZ i, F   ;Уменьшить i и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP   ;Если нет, то перейти к метке DELAY_LOOP

    DECFSZ j, F   ;Уменьшить j и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP   ;Если нет, то перейти к метке DELAY_LOOP

    RETLW 0   ;Иначе возврат из подпрограммы

TOGGLE_DELAY   ;Здесь запустите подпрограмму TOGGLE_DELAY

    MOVLW D'255'               ;Загрузить начальное значение задержки    

    MOVWF i   ;Скопируйте значение в регистр i

    MOVWF j   ;Скопируйте значение в регистр j

DELAY_LOOP1   ;Начать цикл задержки

    DECFSZ i, F   ;Уменьшить i и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP1       ;Если нет, то перейти к метке DELAY_LOOP1

    DECFSZ j, F   ;Уменьшить j и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP1       ;Если нет, то перейти к метке DELAY_LOOP1

    RETLW 0   ;Иначе возврат из подпрограммы

    КОНЕЦ

Выглядит не так устрашающе, да? Рассмотрим его подробнее.

В строках с 1 по 7 нет ничего интересного. Мы определяем два регистра «i» (строка 4) и «j» (строка 5), чтобы использовать их в подпрограмме задержки. В остальном это стандартная инициация.

В строке 8 есть что-то новое. Мы уже помним, что ~(1<

GPPU означает (подтягивание выводов общего назначения), НЕ означает, что когда этот бит равен 0, подтягивания включены, а когда он равен 1, подтягивания отключены.В отличие от большинства микроконтроллеров, где вы можете отдельно включать подтягивающие резисторы для каждого вывода, в PIC10F200 вы включаете или отключаете подтягивающие резисторы для выводов GP0, GP1 и GP3 одновременно. Обратите внимание, что контакт GP2 не имеет внутреннего подтягивающего элемента .

Что такое подтягивающие резисторы?

Потерпите, пока мы ненадолго отвлечемся от программы. Что такое подтягивающие резисторы или, точнее, подтягивающие резисторы? Внутри микроконтроллера есть специальные резисторы (или, когда они недоступны внутри, вручную подключаются к контакту снаружи), которые помогают его входам быть более стабильными.Если вы посмотрите на рисунок 1 урока 4, вы можете заметить, что кнопки SW1 и SW2 подключены непосредственно к контактам GP3 и GP0 микроконтроллера соответственно. Когда вы нажимаете любую кнопку, она замыкает соответствующий контакт на землю, и, таким образом, напряжение на этом контакте становится равным 0 В. Но что произойдет, если кнопка не будет нажата? В этом случае состояние входного контакта не определено. Поскольку входной драйвер имеет очень высокое сопротивление, даже малейшие токи (менее микроампера) могут заставить вход изменить свое состояние (например, если вы коснетесь контакта пальцем).И вы не знаете, приведет ли это состояние к росту или к снижению. И, что еще хуже, даже без постороннего вмешательства возможно, что значение пина может «плавать» где угодно от 0В до 5В.

Поскольку мы не хотим, чтобы это произошло, нам необходимо подключить так называемые подтягивающие резисторы. Они подключаются между входным контактом и положительным контактом источника питания (VDD). Обычно они составляют несколько десятков кОм. Ток, протекающий через этот резистор от VDD к входному контакту, достаточен, чтобы удерживать его в высоком состоянии, пока мы не нажмем кнопку.Собственно, поэтому он и называется «pull-up», он подтягивает напряжение пина до напряжения питания. Подтягивающие резисторы более распространены, но есть также конфигурации подтягивающих резисторов, которые подтягивают контакт к земле, привязывая вход к земле с помощью резистора в несколько десятков кОм.

Надеюсь, теперь понятно, что в этом приложении подтягивающие резисторы жизненно необходимы. Вы можете спросить: «Но если мы включим подтягивающие резисторы на выводах GP0, GP1 и GP3, то LED1, подключенный к GP1, должен загореться от них, не так ли?».- Нет, не будет. Подтягивающие резисторы включены только на входных контактах. Как только вы установите направление вывода в качестве выхода, подтягивания для этого вывода отключаются. Отличный вопрос, однако!

Вернемся к нашей программе.

  

    MOVLW ~((1<

    ОПЦИЯ   ;Включить GPIO2 и подтяжки

    MOVLW ~((1 << GP2)|(1 << GP1))    

    TRIS GPIO  ; установите GP1 и GP2 в качестве выходов

КОНТУР

    CALL CHECK_SW1   ;Проверьте переключатель SW1

    CALL CHECK_SW2   ;Проверьте переключатель SW2

    GOTO LOOP

С помощью строки 8, мы загружаем значение ~((1<

В строка 9, мы загружаем это значение в регистр OPTION, которому принадлежат упомянутые биты.

В строках 10-11, мы устанавливаем пины GP1 и GP2 как выходы. Мы уже делали это раньше, так что давайте просто продолжим.

В строках 13 и 14 мы вызываем подпрограммы CHECK_SW1 и CHECK_SW2 соответственно. В этой подпрограмме мы проверяем, нажаты ли соответствующие кнопки (SW1 или SW2), и выполняем действие в соответствии с заданной задачей.Поскольку PIC10F200 не поддерживает прерывания, мы должны опрашивать кнопки, поэтому мы не можем обрабатывать обе кнопки одновременно.

«Опрос» кнопки — это когда вы часто проверяете состояние кнопки. Это активный шаг, который обычно считается неэффективным, особенно в больших и сложных программах, но он подходит для этих простых процедур. В более мощных микроконтроллерах есть возможность использовать «прерывания», которые могут прервать программу, если она обнаружит изменение на интересующем вас контакте, и выполнить определенное действие в этот момент.Это огромная тема, и мы не можем отдать ей должное, не отвлекаясь от этого урока.

  

CHECK_SW1   ;Начало подпрограммы CHECK_SW1

    BTFSC GPIO, GP3   ;Проверьте, равен ли GP3 0 (нажат SW1)

    RETLW 0   ;Если не 0, то вернуть

Теперь рассмотрим, что происходит в этих подпрограммах.

В подпрограмме CHECK_SW1, которая начинается с строки 17, , нам нужно проверить, нажата ли кнопка SW1, дождаться ее нажатия и отпускания, чтобы переключить LED1 (в соответствии с задачей).

В строке 18 появилась новая инструкция BTFSC (Битовая проверка в файловом регистре, Пропустить, если очистить). Эта инструкция противоположна уже известной нам инструкции BTFSS. Он имеет тот же синтаксис, но пропускает следующую строку, если упомянутый бит регистра сброшен (= 0), в отличие от BTFSS, при котором следующая строка пропускается, когда бит установлен (= 1). Итак, в строке 18 проверяем, равен ли бит GP3 регистра GPIO 0. Если да, значит, кнопка нажата.Надеюсь, вы помните, что когда кнопка отпущена, соответствующий бит равен 1 из-за подтягивающего резистора, а когда кнопка нажата, контакт замыкается на землю, и соответствующий бит становится 0). Если кнопка нажата, строка 19 пропускается и мы переходим к строке 20.

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

Помните, что RETLW — это RETurn Literal to W, где адрес в верхней части стека загружается обратно в счетчик программ.

  

CALL DEBOUNCE_DELAY  ;В противном случае выполните задержку устранения дребезга

    BTFSC GPIO, GP3     ;И снова проверьте GP3

    RETLW 0   ;Если не 0, то вернуть

В строке 20 находится вызов подпрограммы DEBOUNCE_DELAY. Зачем нам это надо? Мы живем в реальном мире, где не все идеально. Кнопки не исключение (особенно если вы купили самые дешевые на Алиэкспресс). Итак, когда вы нажимаете кнопку, это не значит, что входной сигнал сразу меняется с 1 на 0 и остается неизменным до тех пор, пока вы не отпустите кнопку.Нет, оно несколько раз прыгает между 0 В и 5 В, пока не станет стабильным. Это происходит из-за того, что контакты кнопок неидеальны, и пока вы нажимаете кнопку, они очень быстро соприкасаются и отпускают друг друга много раз, пока контакт не станет стабильным.

Поскольку микроконтроллер считывает свой ввод с частотой около 1 МГц, он может рассматривать одно нажатие кнопки как многократное нажатие и многократно выполнять требуемое действие. Поскольку мы не хотим, чтобы это произошло, лучше дождаться, пока сигнал станет стабильным, а затем прочитать состояние кнопки.Это называется «задержкой устранения дребезга». После того, как мы замечаем первый раз, когда сигнал становится слабым (первое касание кнопки касается), мы ждем 20-30 миллисекунд, в зависимости от качества кнопки, а затем снова проверяем состояние. Если состояние все еще низкое, это означает, что кнопка действительно была нажата, и мы можем двигаться вперед. Давайте рассмотрим, как это реализовано в строках 20-22.

В строке 20, как было сказано ранее, мы вызываем задержку для устранения дребезга, после чего в строке 21, мы снова проверяем состояние кнопки той же инструкцией BTFSC.Если состояние не 0 (что означает, что по какой-то причине кнопка была отпущена в течение этих 30 мс), то реализуется строка 22 , где инструкция RETLW возвращает нас из подпрограммы. Если состояние по-прежнему равно 0, то строка 22 пропускается и мы переходим к строке 23.

  

BTFSS GPIO, GP3     ;В противном случае подождите, пока GP3 будет 0

    GOTO $-1    ;Цикл ожидания

    CALL DEBOUNCE_DELAY  ;После установки GP3 (отпущен SW1)

Строки 23 и 24 выполняют цикл ожидания, пока мы удерживаем кнопку нажатой.В строке 23 мы используем инструкцию BTFSS.

BTFSS — это «Проверка битов в файловом регистре, пропустить, если установлен», поэтому он проверяет бит регистра и пропускает следующую строку, если бит равен 1.

В строке 24 есть инструкция GOTO $-1. В предыдущих уроках я упоминал, что «$» означает текущее значение ПК. Таким образом, «$-1» означает предыдущую строку кода. Итак, если бит GP3 не установлен, то вызывается строка 24, и мы снова возвращаемся к строке 23. Это происходит до тех пор, пока значение бита GP3 не станет равным 1, что означает, что кнопка была отпущена.

Но мы называем задержку устранения дребезга в строке 25 , потому что при отпускании кнопки все равно происходит дребезг контактов.

  

MOVLW (1 << GP1)    ;Переключатель контакта GP1

    XORWF GPIO, F   ;с использованием операции XOR

    RETLW 0   ;И возврат из подпрограммы

В строки 26 и 27 , только после всего этого мы можем выполнить требуемое действие — переключить LED1. Это делается так же, как в предыдущем руководстве, путем операции XOR регистра GPIO с регистром W, предварительно загруженным с 1 только в бите GP1.

В строке 28 мы можем считать действие выполненным и выйти из подпрограммы с инструкцией RETLW (строка 28).

Теперь о подпрограмме CHECK_SW2. Он похож на CHECK_SW1, но имеет некоторые отличия, потому что на этот раз нам нужно не только ждать, пока нажата кнопка, но и делать в это время какие-то действия.

  

CHECK_SW2   ;Начало подпрограммы CHECK_SW1

BTFSC GPIO, GP0      ;Проверьте, равен ли GP0 0 (нажат SW2)

    RETLW 0   ; Если не 0, вернуть

    CALL DEBOUNCE_DELAY  ;В противном случае выполните задержку устранения дребезга

SW2_LOOP       ;Цикл при нажатии SW2

    BTFSC GPIO, GP0     ;Проверьте, равен ли GP0 0

    RETLW 0   ; Если не 0, вернуть

    MOVLW (1 << GP2)     ;В противном случае переключить контакт GP2

    XORWF GPIO, F   ;используя операцию XOR,

Итак, строки 31-33 такие же, как строки 18-20, за исключением того, что теперь мы проверяем вывод GP0 вместо GP3.

В строке 34 мы добавляем метку SW2_LOOP, здесь мы запускаем цикл, в котором мы ждем, пока кнопка SW2 будет отпущена.

Строки 35-36 по своему назначению в основном идентичны строкам 21-22. Мы проверяем состояние кнопки после задержки устранения дребезга и, если кнопка все еще нажата, идем дальше.

В строках 37-38, мы переключаем LED2 так же, как мы переключали LED1 в строках 26-27.

  

CALL TOGGLE_DELAY      ;выполнить длительную задержку перед следующим переключением

    GOTO SW2_LOOP          ;и возврат в начало цикла

После этого вызываем TOGGLE_DELAY в строке 39 .Задержка переключения — это та же задержка, но больше, чем DEBOUNCE_DELAY. На самом деле я мог бы использовать тот же код, что и в предыдущем уроке — просто загрузить значения «i» и «j» вне подпрограммы DELAY, а затем уменьшить их внутри подпрограммы DELAY. Но если подсчитать общее количество вызовов DEBOUNCE_DELAY и TOGGLE_DELAY в программе, получится 4 раза. Загрузка значений «i» и «j» занимает 3 строки (в основном 3 слова флэш-памяти). Итак, нам нужно 6 дополнительных строк (потому что мы загружаем их дважды в подпрограммах DEBOUNCE_DELAY и TOGGLE_DELAY).В то время как цикл задержки занимает всего 5 строк (47-51 и 58-62), мы экономим одно слово памяти, ура! Это отличный пример небольших вещей, которые вы можете сделать для оптимизации кода на ассемблере, по сравнению с написанием на C, C++ или Java и автоматическим созданием машинного кода компилятором. Компиляторы профессионального уровня, по общему признанию, могут делать довольно потрясающую работу, и если вы не очень хорошо разбираетесь в ассемблере, вы можете быть даже менее эффективными. Но если у вас есть хорошее понимание того, как работает сборка, и немного творчества, вы можете делать удивительные вещи.

Возвращаясь к программе, после вызова TOGGLE_DELAY мы возвращаемся к строке 34 по инструкции GOTO в строке 40 . Затем мы проверяем, нажата ли кнопка, и снова переключаем светодиод 2, если это так. Таким образом, мы продолжаем переключать светодиод с указанной задержкой, пока не отпустим кнопку.

  

DEBOUNCE_DELAY       ;Здесь запустите подпрограмму DEBOUNCE_DELAY

MOVLW D'40'   ;Загрузить начальное значение задержки    

    MOVWF i   ;Скопируйте значение в регистр i

    MOVWF j   ;Скопируйте значение в регистр j

DELAY_LOOP       ;Начать цикл задержки

    DECFSZ i, F   ;Уменьшить i и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP   ;Если нет, то перейти к метке DELAY_LOOP

    DECFSZ j, F   ;Уменьшить j и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP   ;Если нет, то перейти к метке DELAY_LOOP

    RETLW 0   ;иначе возврат из подпрограммы

Как я упоминал ранее, в строках 42-51 находится подпрограмма DEBOUNCE_DELAY, а в строках 53-62 находится подпрограмма TOGGLE_DELAY.Мы знаем о задержках все, поэтому я не буду рассматривать их более подробно.

  

TOGGLE_DELAY       ;Здесь запустите подпрограмму TOGGLE_DELAY

MOVLW D'255'       ;Загрузить начальное значение задержки    

    MOVWF i   ;Скопируйте значение в регистр i

    MOVWF j   ;Скопируйте значение в регистр j

DELAY_LOOP1       ;Начать цикл задержки

    DECFSZ i, F   ;Уменьшить i и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP1     ;Если нет, то перейти к метке DELAY_LOOP1

    DECFSZ j, F   ;Уменьшить j и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP1     ;Если нет, то перейти к метке DELAY_LOOP1

    RETLW 0   ;Иначе возврат из подпрограммы

    END

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

Теперь можно скопировать программу в редактор MPLAB, собрать ее и загрузить в микроконтроллер. Затем нажмите кнопку SW1 и отпустите ее. Вы должны увидеть, что LED1 меняет свое состояние. Когда вы нажмете ее в следующий раз, LED1 вернется в исходное состояние.Обратите внимание, что время, в течение которого вы удерживаете кнопку SW1, не имеет значения — светодиод LED1 будет переключаться только один раз за одно нажатие.

Теперь попробуйте кратковременно нажать кнопку SW2, вы увидите то же поведение, что и при нажатии кнопки SW1 — будет переключаться светодиод 2. Но когда вы нажимаете SW2 и держите его, светодиод 2 будет менять свое состояние несколько раз в секунду (5 раз, если быть точным, так как по задаче задержка составляет 200 миллисекунд).

Внимание! Вы можете столкнуться с проблемой, что после загрузки программы ничего не работает или просто мигает светодиод 2.Не волнуйтесь, это не ошибка. Это может произойти из-за программатора. После завершения программирования он по какой-то причине держит низкий уровень GP0 и высокий уровень GP3 (по крайней мере, с моим PICKit 3). Вот почему программа зависает. Чтобы устранить эту проблему, просто отключите провода, которые идут от программатора к GP0 и GP3 микроконтроллера, и все будет работать нормально. Но не забудьте вернуть их обратно, когда захотите снова запрограммировать свой микроконтроллер. ( И уж точно не перепутайте! Ваш микроконтроллер может быть поврежден. )


И все. Сегодняшняя сухая статистика даже меньше, чем в предыдущем уроке. Мы выучили только одну новую инструкцию — BTFSC, и теперь мы знаем 20 из 33. Размер программы составляет всего 43 слова флэш-памяти, или почти 17% нашего программного пространства.

В качестве домашнего задания рекомендую следующее задание. Подсчитайте количество нажатий кнопки SW1 и укажите его в двоичном коде с помощью светодиодов LED1 и LED2 в соответствии с таблицей ниже:



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

  

#include "p10f200.inc"

__CONFIG _WDT_OFF & _CP_OFF ​​& _MCLRE_OFF

i EQU 10 ;Регистр задержки 1

j EQU 11 ;Регистр задержки 2

count    EQU 12   ;Количество нажатий кнопок

    ОРГ 0x0000    

ИНИТ

    MOVLW ~((1<

    ОПЦИЯ   ;Включить GPIO2 и подтяжки

    MOVLW ~((1 << GP2)|(1 << GP1))    

    TRIS GPIO  ; установите GP1 и GP2 в качестве выходов

КОНТУР

    BTFSC GPIO, GP3   ;Проверьте, равен ли GP3 0 (нажат SW1)

    GOTO LOOP   ;Если это не 0, то вернуться к LOOP

    CALL DEBOUNCE_DELAY ;В противном случае выполнить задержку устранения дребезга

    BTFSC GPIO, GP3   ;И снова проверьте GP3

    GOTO LOOP   ;Если это не 0, то вернуться к LOOP

    BTFSS GPIO, GP3   ; В противном случае подождите, пока GP3 будет равен 0

    GOTO $-1   ;Цикл ожидания

    CALL DEBOUNCE_DELAY ;После установки GP3 (отпуска SW1)

    INCF count, F               ;увеличить регистр счетчика

    MOVLW 0x03   ;Загрузить значение 0x03 в регистр W

    Число ANDWF, F               ;Выполнить операцию И с регистром счетчика

    RLF count, W               ;Повернуть регистр счетчика влево

    MOVWF GPIO  ; и сохраните значение в регистре GPIO

.

    ПЕРЕХОД К ЦИКЛУ

DEBOUNCE_DELAY   ;Здесь запустите подпрограмму DEBOUNCE_DELAY

    MOVLW D'40'   ;Загрузить начальное значение задержки    

    MOVWF i   ;Скопируйте значение в регистр i

    MOVWF j   ;Скопируйте значение в регистр j

DELAY_LOOP   ;Начать цикл задержки

    DECFSZ i, F   ;Уменьшить i и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP   ;Если нет, то перейти к метке DELAY_LOOP

    DECFSZ j, F   ;Уменьшить j и проверить, не равно ли оно нулю

    GOTO DELAY_LOOP   ;Если нет, то перейти к метке DELAY_LOOP

    RETLW 0   ;Иначе возврат из подпрограммы

    END

Я просто хотел показать вам, что с помощью некоторых трюков можно сделать решение очень компактным.Перечисленная программа использует всего 26 слов Flash-памяти, но полностью выполняет поставленную задачу.

Давайте теперь рассмотрим, как мне это удалось.

Судя по всему, нам нужен регистр, в котором мы можем считать количество нажатий кнопки SW1. Итак, давайте определим его как «количество» в строке 6 .

Часть инициализации абсолютно такая же, поэтому давайте пропустим ее и перейдем к строке 14 . Я исключил подпрограмму CHECK_SW1 и поместил ее код в основной цикл. Это позволяет нам сэкономить два слова — инструкции CALL и RETLW.

Строки с 14 по 21 скопированы из подпрограммы CHECK_SW1 и идентичны, за исключением строк 15 и 18, , где я заменил инструкцию RETLW 0 на GOTO LOOP, которая делает то же самое в текущем случае.

В строка 22, вместо переключения светодиода после отпускания кнопки мы увеличиваем переменную count с помощью уже знакомой вам инструкции INCF.

Строки 23-26 делают настоящее волшебство, которое я попытаюсь объяснить.

В строке 23, мы загружаем значение 0x03 в регистр W. Зачем нам это надо? 0x03 — это 00000011b в двоичном формате. Поскольку мы хотим указать только два последних бита значения «счетчика» с помощью светодиодов LED1 и LED2, мы можем захотеть установить другие биты этого регистра равными нулю. Итак, подготавливаем это значение в регистре W.

В строке 24, мы находим новую инструкцию ANDWF (И регистры W и F). Согласно его описанию, он выполняет логическую операцию И над регистром W и заданным файловым регистром и сохраняет результат либо в регистре W, либо в регистре F в соответствии с операндом 2.В нашем случае мы загружаем значение обратно в регистр «count». Реализуя эту строку, мы устанавливаем все биты регистра «count» в 0, кроме двух последних битов — они остаются неизменными. Давайте посмотрим, как это работает:

Итак, вы видите, что значение «счетчика» после операции И изменяется в цикле как 1, 2, 3, 0, 1, 2… что нам хорошо, так как нам нужны только последние два бита ( выделено).

Таким образом, мы могли бы использовать это значение для загрузки в регистр GPIO и прямого управления LED1 и LED2, но они подключены к контактам GP1 и GP2 соответственно, которые соответствуют битам 1 и 2 регистра GPIO, а не битам 0 и 1, которые у нас здесь.

Итак, нам нужно сдвинуть значение «count» на один бит влево, чтобы иметь значение, готовое к загрузке в регистр GPIO.

PIC10F200 имеет для этого специальную инструкцию: RLF (Rotate Left File register), которую мы видим в строке 25. Эта инструкция сдвигает данный файловый регистр на одну позицию влево через бит C (Carry) регистра STATUS. Звучит немного сложно, но позвольте мне объяснить, используя изображение из таблицы данных PIC10F200 (рис. 1). перешел на бит № 2 и так далее.Но бит #7 является последним, поэтому его некуда переместить, поэтому он копируется в бит C регистра STATUS, а после этого бит C копируется в бит #0. Итак, в основном значение бита № 7 перемещается в бит № 0. Таким образом, значение регистра вращается по большому кругу, и ничего не теряется.

Результат сдвига можно сохранить обратно в регистр File или переместить в регистр W в соответствии с операндом 2. В нашем случае мы хотим сохранить результат в регистре W, чтобы сохранить значение «count» без сдвига.После выполнения этой инструкции мы будем иметь следующее:

Теперь у нас есть изменяющиеся биты в нужных местах (см. выделенное). Таким образом, мы можем просто скопировать регистр W в регистр GPIO. И мы уже знаем, как это сделать, используя инструкцию MOVWF, которую мы видим в строке 26.

Вот и все! Как видите, используя аппаратное подключение и понимая, как все устроено, мы можем уменьшить размер кода в несколько раз. Также хочу отметить, что если бы LED1 и LED2 были подключены к GP0 и GP1 соответственно, нам бы даже не понадобились операции И и сдвига, так как без них он работал бы корректно.Это подводит нас к идее, что понимание того, как эти вещи работают, может помочь нам разработать лучшую схематическую диаграмму, реализующую текущую задачу с минимальным использованием памяти. Грань между разработкой схемы и разработкой прошивки действительно тонкая!

шт. Теперь мы знаем еще 2 инструкции — ANDWF и RLF, так что 22 из 33.

Файлы проекта

Кнопки проверки | LEARN.PARALLAX.COM

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

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

Модуль micro:bit имеет две встроенные кнопки. Вы также можете добавить дополнительные кнопки к своему кибер:боту на макетной плате.При этом вы узнаете, как работает кнопочная схема.

О кнопках

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

…и вот рисунок, напоминающий макетную кнопку:

Обратите внимание, что при нажатии кнопки все 4 контакта соединяются.Однако, когда кнопка не нажата, ножки 1 и 4 по-прежнему соединены, а ножки 2 и 3 по-прежнему соединены.

Если кнопка нажата, схема подает 3,3 В на контакт ввода-вывода через кнопку, и небольшой ток также проходит через резистор 10 кОм на землю. Когда кнопка не нажата, соединение с источником питания 3,3 В разорвано, поэтому схема подключает GND (0 В) к контакту ввода/вывода.

Кнопочные и светодиодные схемы

В этой схеме используются встроенные в плату светодиоды P20 и P21, а также две схемы кнопок, которые вы встроите на макетную плату.Используйте резисторы на 220 Ом для подключения цепей кнопок к контактам ввода-вывода Cyber:bot и используйте резисторы на 10 кОм для соединения цепей с землей.

Детали
(2) кнопки
(2) резисторы 220 Ом (красный-красный-коричневый)
(2) резисторы 10 кОм (коричневый-черный-оранжевый)

  • Соберите две цепи кнопок, показанные на принципиальной и электрической схеме. Мы также используем встроенные светодиоды на P20 и P21.

 

Код теста: test_pin_3_button.ру

Этот тестовый код отобразит состояние кнопки, подключенной к P3, на дисплее модуля micro:bit. На дисплее будет отображаться 1, если кнопка нажата, или 0, если она не нажата.

  • Введите, сохраните и запустите скрипт test_pin_3_button.py.
 # test_pin_3_button.py

из импорта киберботов *

пока верно:
    если бот(3).read_digital() == 0:
        дисплей.показать("0")
    Элиф бот(3).read_digital() == 1:
        display.show("1") 

Как test_pin_3_button.ру работает

Этот скрипт Python находится внутри непрерывного цикла while True:. Внутри цикла есть один оператор if, который проверяет два условия.

Первое условие, которое он проверяет, это то, что функция bot(3).read_digital равна 0. Если это так, модуль micro:bit отобразит 0. В данном случае функция read_digital проверяет состояние ввода вывода. Р3. Таким образом, если кнопка не нажата, состояние ввода на контакте 3 равно 0. 

Вторая часть оператора if проверяет, равно ли состояние ввода 1 (кнопка нажата), если это так, модуль micro:bit отобразит 1.


Знаете ли вы?

Активный-высокий: Используемая вами схема кнопки называется активный-высокий , потому что кнопка отправляет на контакт ввода-вывода Cyber:bot сигнал высокого уровня 3,3 В при нажатии (активный) или сигнал низкого уровня 0 В. когда выпустили.

Pull-down: Резистор 10 кОм на схеме называется резистором pull-down . Это делается для того, чтобы контакт ввода-вывода обнаруживал 3,3 В через резистор при нажатии кнопки.Если вы его не укажете, контакт ввода-вывода будет вести себя как антенна, а близлежащие электрические поля в конечном итоге будут контролировать, будет ли обнаружена 1 или 0.

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


Попробуйте это: pin_3_button_LED.ру

Теперь пришло время управлять светодиодом с помощью кнопки.

  • Измените функции display.show на функцию write_digital, чтобы при нажатии кнопки включались желтые светодиоды, подключенные к контакту 20.
  • Изменить test_pin_3_button.py на pin_3_button_LED.py
  • Замените display.show(«0») на bot(20).write_digital(0) и замените display.show(«1») на bot(20).write_digital(1).
  • Введите, сохраните и запустите приведенный ниже скрипт:
 # pin_3_button_LED.пи

из импорта киберботов *

пока верно:
    если бот(3).read_digital() == 0:
        бот(20).write_digital(0)
    Элиф бот(3).read_digital() == 1:
        бот(20).write_digital(1) 
  • Убедитесь, что светодиод P20 мигает при нажатии кнопки, подключенной к P3, и гаснет, когда вы ее отпускаете.

Ваша очередь — светодиод P21 и кнопка P4

Можно ли заставить светодиод, подключенный к P21, мигать при нажатии кнопки, подключенной к P4?

  • Измените свой пробный проект, чтобы протестировать управление светодиодом P21 с помощью кнопки P4.
  • Сохраните проект и расширьте код так, чтобы кнопка P3 управляла светодиодом P20, а кнопка P4 одновременно управляла светодиодом P21.

 

Схема для USB игрового контроллера с 12 входами (8 кнопок + 4 направления)


Схема для игрового контроллера USB с 12 входами (8 кнопок + 4 направления)

Содержимое

Обзор проекта

Для некоторых проектов предусмотрена схема, позволяющая подключить 12 кнопок (в том числе 4 кнопки направлений) к ПК с USB-портом очень полезен.Вот несколько примеров:
  • Самодельный аркадный контроллер и небольшие игровые автоматы
  • Простой контроллер (1 провод на кнопку) к USB. Например: Neo-Geo, Atari…
  • С помощью соответствующего программного обеспечения на стороне ПК можно использовать входы для других целей. Например: переключатели, концевые выключатели, сигнализация… Чистое решение чем модификация существующего игрового контроллера

На этой странице вы узнаете, как собрать такую ​​схему с помощью микроконтроллера.Прошивка реализует стандартный USB-джойстик с 4 кнопками направления и 8 кнопками общего назначения.

В зависимости от ваших навыков, вы можете построить схему на макетной плате, используя сквозные компоненты или соберите версию для поверхностного монтажа, используя мою маленькую многоцелевую плату PCB2 печатная плата. Я также продаю готовые схемы и предварительно запрограммированные микросхемы Atmega8 (только в DIP-корпусе). Посещение мой интернет-магазин для более подробной информации.

Драйвера не требуются!
Правильно, так как стандарт USB определяет классы устройств.я использую устройство человеческого ввода (HID), которое позволяет мне сообщить компьютеру, что Подключаемое USB-устройство представляет собой джойстик и имеет 2 оси и 4 или 8 кнопок. Другая хорошо, что адаптер должен работать со всеми операционными системами поддержка HID-устройств. (проверил, работает как минимум на Win98, Win2K, WinXP и Linux)

В этом проекте используется микроконтроллер ATmega8 от Atmel. Этот микроконтроллер аппаратно не поддерживает USB, поэтому я использовал только программный драйвер USB из объективного развития.Этот Драйвер позволяет микроконтроллеру AVR, такому как ATmega8, общаться через USB с минимальным количеством внешних компонентов. В результате интерфейс можно построить легко и дешево


Схема

Вот основная схема:
А вот пример проводки:

Кроме того, ниже на этой странице показана таблица подключения контроллеров NeoGeo.
Список компонентов:
Артикул Описание
U2 Микроконтроллер Atmega8.ATMEGA8-16PC, ATMEGA8-16PI, ATMEGA8-16PJ или ATMEGA8-16PU. Не используйте ATMEGA8L-*, часы 12 МГц были бы слишком высокими.
R1 Резистор 1,5 кОм. Подойдут обычные карбоновые пленочные резисторы на 1/4 ватта.
R2, R3 Резисторы 68 Ом. Подойдут обычные карбоновые пленочные резисторы на 1/4 ватта.
D2, D3 Стабилитроны 3,6 В.
R4 Не устанавливать, больше не используется.
D1 Не устанавливать, больше не используется.
Y1 Кристалл 12 МГц.
C2, C3 Конденсаторы 27 пФ. Если в описании кристалла рекомендовано другое значение, используйте его.
C1 Конденсатор 10 мкФ. Установите его рядом с ATmega8.
JP1, JP2 Перемычки. Вы также можете использовать DIP-переключатели, обычные переключатели или перемычки для пайки.
J2 6-контактный разъем, расстояние 2,54 мм. Нужен для программирования ATmega8.

Для USB-подключения просто зачистите USB-кабель и припаяйте провода напрямую. к доске. USB использует стандартные цвета проводов: 9111 9111 9111 D +
Цвет Описание
31112 +5 вольт 9111
9111 9111 D-


Программирование

Микроконтроллер — это компонент, который необходимо запрограммировать, чтобы что-то полезное.Итак, вот шестнадцатеричный файл, который необходимо прошить в микроконтроллер:
usb_game12-1.0.hex

Многие микроконтроллеры имеют то, что называется «Fuse bytes». В случае с ATmega8a два байта: старший байт и младший байт. Эти байты используются для настройки некоторых аспектов микроконтроллера. Какой тип часов использовать? Кристалл? Резонатор? Внутренние часы RC? Разрешать программирование через провайдера? Очень важно установить предохранители на правильные значения. Использование неправильного значения могут сделать ваш MCU непригодным для использования.

Для этого проекта приведены соответствующие значения предохранителей:
старший байт = 0xc9 , младший байт = 0x9f

Подробнее о программировании AVR см. посетите мою страницу программирования AVR.


Исходный код

Исходный код выпущен под лицензией GPL и компилируется с помощью avr-gcc. Чтобы предотвратить конфликты, пожалуйста, не распространяйте модифицированную версию, в которой дескриптор отчета USB имеет значение . был изменен без замены идентификатора поставщика USB и идентификатора продукта вашими.

usb_game12-1.0.tar.gz


Печатная плата для поверхностного монтажа

Версия для поверхностного монтажа использует мою схему Multiuse PCB2. Вот как это выглядит:
Многофункциональная печатная плата2:
Схема подключения для этого проекта на «Multiuse PCB2»:


Проводка адаптера NeoGeo

Контроллеры Neo Geo используют стандартные разъемы DB15. Этот разъем также используется старым ПК Джойстики но это несовместимо.Вот таблица, описывающая, как подключить Neo Geo. Разъем контроллера к этой цепи: 9111 9111
DB15 PIN Neo Geo12 Имя USB Game12 Имя Комментарии Common Common
3 Выбор Кнопка 5
4 D Кнопка
5 B Кнопка 9111 9111 3
6 9112
7 Down
8 + 5V + 5V + 5V 9111
D PIN 4 Дублирует PIN 4
11 Начало Кнопка 4
12 Кнопка C Кнопка 2
13 кнопка 9111 9111
14 11114 9111 9111 9111 9111 9111
15 UP UP
(контакты 2 и 10 DB15 не подключены)

Отказ от ответственности

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

alexxlab

Добавить комментарий

Ваш адрес email не будет опубликован.