INT 21h

Hi, I am Vladimir Smagin, SysAdmin. Telegram Email GPG / Микроблог

Прерывания в AVR INT0 и INT1

№ 3132 В разделах: Программирование Электроника от July 26th, 2011,

Если откроете даташит к вашей atmega, то увидите ножки INT0, INT1 и т.д. Так вот это ножки, по изменению состояния которых может вызываться прерывание. Например, на спад напряжения или возрастание. Идеально, если вы используете кнопки или устройства, изменение состояния которых должно прямым образом отражаться на работе микроконтроллера. А самое лучшее применение, это прием данных, где очень важно вовремя их получить. Например, флажок “данные приняты в буфер” на радиомодуле.

Давайте рассмотрим пример работы с использованием обычной кнопки. Она будет замыкать или размыкать контакт, устанавливая на ножке INT1 логический 0 или 1. Это поможет разобраться в том, как это всё работает.



На рисунке самая обычная Mega32 в DIP корпусе. Резистор R1 “подтягивает” линию к плюсу. Обычно он ставится не менее 4.7 кОм. Некоторые и 10 кОм втыкают. По нажатию кнопки линия “просядет” до земли и на ножке получится логический ноль.

В даташите черным по белому нарисована такая вот таблица:

ISC11 ISC10 Description Перевод
0 0 The low level of INT1 generates an interrupt request. Логический 0 генерирует прерывание
0 1 Any logical change on INT1 generates an interrupt request. Любое изменение генерирует прерывание
1 0 The falling edge of INT1 generates an interrupt request. Вызов прерывания при смене логической 1 на 0
1 1 The rising edge of INT1 generates an interrupt request. Вызов прерывания при смене логического 0 на 1

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

Подключите эти файлы к вашей программе:
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>

Давайте настроимся на вызов прерывания при падении уровня напряжения на INT1 до 0:
GIMSK |= (1<<INT1); //разрешили прерывание
MCUCR = (1<<ISC11) | (0<<ISC10); //настроились

Приколитесь, это все что нужно было сделать 🙂 Осталось написать обработчик прерывания, где изменим переменную FLAG на 1 и перепрограммируем вызов прерывания на смену состояния ножки с логического 0 на 1.

uint8_t FLAG=0;
...
...
ISR(INT1_vect) {
_delay_ms(50);
if (FLAG==1) {
//вызов прерывания при смене логической 1 на 0
MCUCR = (1<<ISC11) | (0<<ISC10);
FLAG=0;
} else {
FLAG=1;
//вызов прерывания при смене логического 0 на 1
MCUCR = (1<<ISC11) | (1<<ISC10);
}
}

Таким образом, нажимая на кнопку (просто зажать и не отпускать) вы вызываете прерывание, где FLAG присваивается 1 (и может быть что-то еще делается) и меняете условия срабатывания так, что это прерывание вызовется еще раз при отпускании кнопки (когда логический 0 меняется на 1).

Если вы делаете это на настоящем железе, то следует учитывать “дребезжание” кнопки. Каждый ставит его по своему вкусу от 10 мс. Я поставил 50 мс. Но кнопки на прерываниях лучше не делать. Приспособьте для этого таймер.

4 комментариев »

4 responses to “Прерывания в AVR INT0 и INT1”

  1. Kostya says:

    Привет.
    “Но кнопки на прерываниях лучше не делать?” а почему лучше не делать.

    Как приспособить таймер?)

  2. 21h says:

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

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

  3. Pavel says:

    Выдаёт такую ошибку, что это может быть?
    Error 1 static declaration of ‘__vector_2’ follows non-static declaration C:\Users\Pavel\Documents\Atmel Studio\Interupt\Interupt\Interupt.c 25 6 Interupt

  4. фдыр0907 says:

    Огромное спасибо за идею, как можно перепрограммировать прерывание на другой фронт сигнала. Нужно было портировать программу с Ардуино Atmega328 на Atmega128. Там функция attachInterrupt из коробки не захотела просто так работать. Проще оказалось воспользоваться Вашей идеей.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Микроблог перейти

# 2018-11-26 09:15:41

Обнаружил в kubedb код google analytics UA-62096468-20, слежка включена по умолчанию.

# 2018-11-24 23:30:12

Несложно смог контейнеризовать nginx unit с предзагрузкой конфигурации перед стартом контейнера blindage.org/?p=9575


© Vladimir Smagin, 2005-2018. Копирование материалов без разрешения запрещено. GPG 0x29AE91B1A37721C3
Яндекс.Метрика

Fortune cookie: Today's spam: Thorough, complete, utter penetration now possible