mcu logic input - el-pths/w GitHub Wiki
Логические входы Микроконтроллеров
В самом начале мы познакомились с возможностью микроконтроллеров формировать логические сигналы на своих выводах. Низкому уровню (0) соответствует напряжение минуса питания (общего провода, Gnd), а высокому (1) - напряжение плюса (Vcc, Vdd).
Помимо этого контроллеры также умеют использовать свои выводы "на вход", т.е. для считывания логических сигналов. В этом случае обычно напряжение выше некоторого уровня считается "единицей", а ниже - "нулем". Кроме того граница между этими уровнями имеет небольшой гистерезис (различается при переключении из 0 в 1 и наоборот), чтобы избежать дребезга если сигнал колеблется вблизи границы.
По умолчанию ноги контроллеров чаще всего включены именно на вход. На всякий случай это можно сделать явно:
// для Ардуино
pinMode(10, INPUT);
10 rem для Мискатино
20 PIN 10;-1
После чего считать значение можно специальной функцией:
// для Ардуино
Serial.println(digitalRead(10));
10 rem для Мискатино
20 print pin(10)
Обратите внимание - для Miskatino название функции PIN
совпадает с названием команды PIN
, хотя по смыслу это разные вещи, не путайте их.
Подтяжки (pull-ups, pull-down)
При подключении к выводам кнопок обычно кнопка подключается к плюсу или к минусу и когда она нажата, то на вывод подается соответственно высокий или низкий уровень. Однако встает вопрос - какой уровень формируется когда кнопка отпущена?
По умолчанию - никакой. Вход находится в "высокоимпедансном" состоянии и любые пролетающие мимо помехи на нем создают постоянно переключающиеся нули и единицы.
Для борьбы с этим явлением, обычно кроме кнопки к входу подключается еще и резистор, "подтягивающий" этот вход к противоположной линии питания. Т.е. если кнопка подключена к плюсу - то резистор идет к минусу и наоборот. Благодаря этому, при отпущенной кнопке через резистор приходит слабый но уверенный уровень сигнала. При нажатой же резистор просто оказывается подключен (через кнопку) между плюсом и минусом и никакого воздействия на вход не оказывает. Сопротивление резисторов-подтяжек обычно 10-100 килоом. Подтяжки к плюсу называются "pull-up", а к минусу "pull-down".
Кроме того большинство контроллеров имеют внутренние резисторы-подтяжки на входах. У контроллеров Atmega (на которых сделаны Ардуино) есть только подтяжки вверх. У STM32 (на которых могут быть сделаны Miskatino) есть и вверх и вниз. Их можно подключать ко входам специальными командами:
//для Ардуино
pinMode(10, INPUT_PULLUP);
10 rem для Мискатино - вверх
20 pin 10;-2
30 rem для Мискатино - вниз
40 pin 10;-3
Конечно, для Miskatino на базе Arduino "-3" не имеет смысла. Обратите внимание, что если кнопка соединена с минусом, а подтяжка идет вверх (обычно для Ардуино), то при нажатии вход считывается как "0", а при отпускании как "1".
Выделение фронта и подавление дребезга
Отдельный вопрос - обеспечение однократного срабатывания кнопки - или выделение фронта сигнала. Например, мы хотим завести счетчик, который будет увеличиваться при нажатии кнопки. Если написать в духе
int n = 0;
void loop() {
if (digitalRead(10) == LOW) {
n++;
Serial.println(n);
}
}
10 n = 0
20 if pin(10); goto 20
30 n = n+1
40 print n
50 goto 20
То обнаружится, что за время нажатия на кнопку цикл успевает отработать много раз - счетчик увеличивается на сотни и тысячи.
Вместо этого, следовательно, нужно использовать более интеллектуальный подход. Завести переменную, которая хранит предыдущее состояние входа. И на каждой итерации сравнивать текущее состояни и предыдущее. Нажатие фиксировать только если текущее равно 0, а предыдущее 1 (кнопку только что нажали). Такой переход называется "фронтом". Кроме того, как только нажатие уловлено, следует сделать небольшую паузу (50-200 миллисекунд), т.к. обычно кнопка в момент нажатия может сделать несколько микросекундных скачков и таким образом будет зарегистрировано несколько "фронтов". Предлагается самостоятельно исправить код вышел с учетом этих инструкций.