INT 21h

Домашняя страница самого страшного прерывания

Прерывания в 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 комментариев »

Comment by Kostya | March 29, 2012 @ 22:32:04

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

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

Comment by 21h | March 31, 2012 @ 03:19:47

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

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

Comment by Pavel | August 31, 2012 @ 20:14:21

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

Форма отправки комментария

*

Разрешенные HTML-теги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

RSS RSS Feed только для этого поста |


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