INT 21h

Hi, I am Vladimir Smagin, sysadmin. Telegram Email

Прерывания в 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 мс. Но кнопки на прерываниях лучше не делать. Приспособьте для этого таймер.

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

3 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

Leave a Reply

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

*

Комментарии

  • 21h: нене ) без меня )
  • Серегй: Не совсем грабить)) если грабить можно и без рации, есть...
  • 21h: магазин грабить собрались? ) не, тут я не помощник ;)
  • Серегй: А что бы мне поймать чужую волну, что мне для этого нужно...
  • 21h: слушать никто не запрещает. нет закона, который запрещает...
  • Серегй: Я хотел узнать могу ли я просто прийти с данной рацией baofeng...
  • 21h: У меня есть только эти 2. По другим ничего не знаю. В интернете...

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