Объясните новичку по прерыванию INT0 в Atmega8, пожалуйста

Обсуждаем контроллеры компании Atmel.
Ответить
AonMaster
Опытный кот
Сообщения: 811
Зарегистрирован: Пн дек 29, 2014 11:48:22

Объясните новичку по прерыванию INT0 в Atmega8, пожалуйста

Сообщение AonMaster »

Добрый день!

Разрешил одно прерывание INT0 по фронту импульса. В прерывании взвожу флаг int0=1 и выхожу.
В цикле main сравниваю int0 с 1, если int0 == 1 то {int0=0; делаю вызов подпрограммы}

Беда в том, что пока после фронта импульса на ноге int0 держится 1, у меня эта подпрограмма всё время выполняется несколько раз. А ведь, по идее, прерывание уже не должно срабатывать, т.к. фронт уже прошёл, до следующего фронта. Или я неверно понимаю?
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Z_h_e »

AonMaster писал(а):В прерывании взвожу флаг int0=1
Если я правильно понял Вашу мысль. То получается следующее.
-произошло событие внешнего прерывания, у вас установился флаг.
-т.к. у Вас прерывания разрешены, оно у Вас возникает (при этом контроллер автоматически сбрасывает флаг и запрещает все прерывания)
-Вы флаг принудительно зачем то устанавливаете
-контроллер выходит из прерывания и разрешает их. Глядь, а флаг опять установлен (Вы ж его установили сами), ну и обратно в обработчик и т.д.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение uk8amk »

Проблема в том что у атмеги невозможно вручную выставить флаг в регистре и тем самым сгенерировать IRQ. Так что ждём подробностей.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Z_h_e »

Точно ж, там же сброс единицей. Ждемс...
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Novice user
Мудрый кот
Сообщения: 1704
Зарегистрирован: Вт янв 05, 2016 10:14:25
Откуда: поселок Мелеуз

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Novice user »

а если стандартно?(сам новичок)
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
подпрограмма
}
AonMaster
Опытный кот
Сообщения: 811
Зарегистрирован: Пн дек 29, 2014 11:48:22

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение AonMaster »

Z_h_e писал(а):-произошло событие внешнего прерывания, у вас установился флаг..


Int0 - это не флаг внутренних регистров МК, это так я назвал переменную, которая вначале равна 0.

Вошло в прерывание - установилась переменная в 1, вышло из прерывания.
В цикле анализирую эту переменную, как только она стала равна 1 - выполняю подпрограмму.
Сбрасыванием в 0 пытался добиться того, чтоб больше до следующего начала импульса подпрограмма не выполнялась. А она всё равно выполняется.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Z_h_e »

У Вас реальное устройство или в симуляции?
Если реальное, то может оказаться что дребезг какой на входе.
Код то покажите?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
AonMaster
Опытный кот
Сообщения: 811
Зарегистрирован: Пн дек 29, 2014 11:48:22

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение AonMaster »

Реальное.

int drob,drob1, int0=0, done = 0;

interrupt [EXT_INT0] void ext_int0_isr(void)
{
int0 = 1;
}

void front() {
PORTC.5=0;
delay_ms(200);
PORTC.5=1;
delay_ms(200);
}

void main(void)
{

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
GICR|=0x40;
MCUCR=0x03;
//MCUCR=0x00;
GIFR=0x40;
ACSR=0x80;

#asm("sei")

while(1) {

if ((int0 == 1) && (done < 1000) ) {
int0 = 0;
front();
}

}
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Барсик »

Возможно, виноват дребезг, а возможно что-то ещё.
Я бы сделал так:

Код: Выделить всё

// объявил бы int0 как volatile
volatile unsigned char int0 = 0;

// внутри обработчика прерывания, запретил бы то самое прерывание

// в main объявил бы локальную переменную
unsigned char tmp_int0 = 0;

// поскольку боюсь неатомарных операций до дрожи в коленках, считывал флаг так:
#asm("cli")
tmp_int0 = int0;
#asm("sei")
// потом бы уже неспеша работал с переменной tmp_int0

// после того, как импульс сгенерирован, очистил бы флаг прерывания. И не int0, а именно бит в регистре,
// который за это прерывание отвечает
// после чего разрешил бы прерывание опять
// и установил переменную - флаг

#asm("cli")
int0 = 0;
#asm("sei")

// таким образом, прерывания не произойдёт, пока формируется импульс.
// при формировании импульса такие задержки, что дребезг влиять не будет
AonMaster
Опытный кот
Сообщения: 811
Зарегистрирован: Пн дек 29, 2014 11:48:22

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение AonMaster »

Дребезг, думаю, тут ни при чём, т.к. у меня импульсы на PORTC.5 возникают только при "1" на входе int0. Из чего я делаю вывод, что вопреки ожидаемому, МК после первого фронта и пока там держится 1, всё-таки отрабатывает это прерывание снова и снова. Вот и спрашивал, должно ли так быть :-(
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение __Alexander »

та кончено дребезг. сначала вызови функцию, а потом обнули флаг.
AonMaster
Опытный кот
Сообщения: 811
Зарегистрирован: Пн дек 29, 2014 11:48:22

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение AonMaster »

в чём разница? пробовал и так, кажись.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Z_h_e »

А что у Вас за источник импульсов для INT0? Попробуйте его отключить (источник), а вместо него подавать сигнал с другого порта. Даже скорее всего и подавать не надо, просто порт INT0 переключить на выход и его дергать, тоже наверное должны возникать прерывания.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение __Alexander »

AonMaster писал(а):в чём разница? пробовал и так, кажись.


разница в том, что пока будет выполнятся функция, где 400мс задержа, то дребезг уже пройдет в любом случае, вот тогда и обнуляйте.
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Барсик »

И где Ваш исходник?

__Alexander писал(а):пока будет выполнятся функция, где 400мс задержа, то дребезг уже пройдет в любом случае
Вот и я об этом же писал...
Novice user
Мудрый кот
Сообщения: 1704
Зарегистрирован: Вт янв 05, 2016 10:14:25
Откуда: поселок Мелеуз

Re: Объясните новичку по прерыванию INT0 в Atmega8, пожалуйс

Сообщение Novice user »

int0 = 0;
front();-поменяйте местами,что будет?
Ответить

Вернуться в «AVR»