CUSTOMELECTRONICS.RU
Информационно-учебный блог о разработке электроники
Эл. почта: info@customelectronics.ru

Arduino. Внешние прерывания. Подключение энкодера

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

Подготовка к работе

На нашей плате TutorShield установлены две кнопки, которые подключены к цифровым выводам D2 и D3. Подробно подключение кнопок описано в предыдущей статье цикла. Помимо них, для дальнейших экспериментов подключим еще две секции трехцветного светодиода (к выводам D9 и D10). Установите перемычки так, как показано на рисунке:

Установка перемычек

Установка перемычек

Первый пример

В предыдущем примере для обработки кнопок мы настраивали вывод микроконтроллера на вход и постоянно контролировали его состояние. Это не самый эффективный способ, так как при этом трудно заставить микроконтроллер делать что-то помимо опроса кнопок. Специально для этих целей можно использовать прерывания.
Прерывание — это функция микроконтроллера, которая при наступлении какого-либо события позволяет остановить выполнение основной программы и обработать произошедшие события. Например, прерывание можно использовать для обработки приема сигналов COM-порта: микроконтроллер выполняет основную программу, а когда модуль UART сообщает о завершении передачи, то МК прерывает работу и обрабатывает принятый байт. Прерывании в микроконтроллере Atmega8 ровно девятнадцать штук и два из них — это внешние прерывания, вызывающие при изменении напряжении на выводе D2 иди D3 Arduino-совместимой платы.
Рассмотрим работу с прерываниями на конкретном примере:

#define LED 11

void setup() {
    attachInterrupt(0, button1, RISING);
    attachInterrupt(1, button2, RISING);
    pinMode(LED, OUTPUT);
}

void loop() {
}

void button1() {
    digitalWrite(LED,HIGH);
}

void button2() {
    digitalWrite(LED,LOW);
}

Для работы с внешним прерыванием в первую очередь его надо инициализировать. Этим занимается функция attachInterrupt(pin,ISR,mode). У этой функции три параметра:

  • pin — номер вывода, на который настроено прерывание. Для платы EduBoard с МК Atmega8 прерывание может быть настроено только на 2ом и 3ем выводе
  • ISR — имя функции-обработчика прерывания
  • mode — режим работы прерывания, может принимать четыре значения. LOW — вызывает обработчик прерывания, когда на выводе низкое напряжение, CHANGE — при изменении, RISING — при переходе от низкого к высокому уровню, FALLING — от высокому к низкому

В приведенном примере настроено два прерывания. Прерывание "0" вызывает обработчик button1() при изменении напряжения с низкого на высокий уровень на выводе D2. Прерывание "1" вызывает обработчик button2() при изменении напряжения с низкого на высокий уровень на выводе D3.
В обработчике прерывания button1() зажигается светодиод, а при обработке прерывания button2() он гасится. То есть при нажатии на кнопку, подключенную к выводу D2 светодиод включится, а при нажатии D3 — выключится.

Второй пример

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

#define LED 11

int val = 0;

void setup() {
    attachInterrupt(0, button1, RISING);
    attachInterrupt(1, button2, RISING);
    pinMode(LED, OUTPUT);
    Serial.begin(9600);
}

void loop() {
    Serial.println(val);
    delay(500);
}

void button1() {
    digitalWrite(LED,HIGH);
    val++;
}

void button2() {
    digitalWrite(LED,LOW);
    val--;
}

После загрузки кода на плату, откройте монитор COM-порта (Ctrl+Shift+M) и посмотрите на то, как изменяются данные при нажатии на кнопки. Чаще всего все будет работать правильно, но иногда переменная будет меняться не на единицу, а сразу на два за одно нажатие. Это значит, что из-за дребезга контактов прерывание было вызвано несколько раз.
В каких-то ситуациях это не имеет большого значения. Чем лучше мы будем предотвращать дребезг контактов, там выше будет риск пропуска нажатия. Есть много способов борьбы с дребезгом контактов, как программных, так и аппаратных. Пока мы не будем останавливаться на них.

Обработка энкодера

На нашем шилде установлен инкрементальный энкодер. По своему виду он похож на переменный резистор, но работает он совершенно по-другому. Вы могли встречать инкрементальные энкодеры в регуляторах громкости с бесконечным вращением.
Мы не будем подробно описывать принцип работы энкодера. Самое главное для нас то, что при вращении на его двух выводах формируется импульсные последовательности сдвинутые по фазе. Фазовый сдвиг может быть положительным и отрицательным в зависимости от направления вращения. Для обработки энкодера необходимо один его вывод настроить на прерывания и в прерывании проверять состояние второго вывода. Если он в высоком состоянии, то значит энкодер вращали по-часовой стрелке. Если на входе низкое напряжение — то против. Рассмотрим на примере:

#define LED 11

int val = 0;

void setup() {
    attachInterrupt(0, button1, RISING);
    pinMode(LED, OUTPUT);
    pinMode(3, INPUT);
}

void loop() {
    if(val<0) val = 0;
    if(val>255) val = 250;
    analogWrite(LED,val);
}

void button1() {
    if( digitalRead(3) == HIGH) val=val+10;
    else val=val-10;
}

В результате работы этой программы при вращении энкодера по-часовой яркость светодиода будет увеличиваться, а при вращении против часовой — уменьшаться. Изменение яркости происходит с шагом в 10 единиц. Чтобы переменная не вышла за пределы нормальных значений в основном цикле она нормируется.

Индивидуальные задания

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

Остальные статьи цикла можно найти здесь.

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

Метки: , , , , , Просмотров: 33063