Нужна помощь в отладке скетча

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

storm134 пишет:

Просветите нас по приоритетам прерываний на АВР.    У них у всех одинаковый приоритет. 

Просвещаю. Хоть у AVR-ок и нету такого, как на ББ, контроллера прерываний, с разными уровнями и приоритетом, но при условии одновременного наступления двух и более прерываний, первым обработается прерывание с меньшим номером, остальные будут ожидать.  

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

storm134 пишет:

У них у всех одинаковый приоритет. 

Исполняем на Uno/Nano.

//
// Проверка последовательности обработки прерываний.
// Если в строке №9 написать false, то прерывания будут обрабатываться
// немедленно по мере поступления (строки №№ 42-44)
// если же в строке №9 написать true, то прерывания будут накапливаться
// а обработаются все сразу после того, как будет разрешена их
// обработка в строке №47
// 
#define COLLECT_INTERRUPTS  true

static char intLog[64];

// Прерывание INT0
void int0Int(void) { strcat(intLog, "Спартак "); }

// Прерывание INT1
void int1Int(void) { strcat(intLog, "разгромил "); }

// Прерывание переполнения таймера счётчика 0. Срабатывает один раз
ISR (TIMER2_OVF_vect) { TCCR2B = 0; strcat(intLog, "Реал "); }


void setup(void) {
	intLog[0] = '\0';
	Serial.begin(115200);
	pinMode(2, OUTPUT);
	pinMode(3, OUTPUT);
	attachInterrupt(0, int0Int, RISING);
	attachInterrupt(1, int1Int, RISING);

#if COLLECT_INTERRUPTS
	noInterrupts();
#endif	// COLLECT_INTERRUPTS

	TCCR2A = 0;
	TCCR2B = 1;
	TIMSK2 = 1;

	//
	//	Вызываем срабатывание трёх прерываний
	//
	_delay_us(100);
	digitalWrite(3, HIGH);
	digitalWrite(2, HIGH);

#if COLLECT_INTERRUPTS
	interrupts();
#endif	// COLLECT_INTERRUPTS

	Serial.println(intLog);
}

void loop(void) {}

///////////////////////////////////////
//
// РЕЗУЛЬТАТ
//
// (при false в строке №9)
// Реал разгромил Спартак 
// 
// (при true в строке №9)
// Спартак разгромил Реал
//

И кто кого? Реал или Спартак?

-NMi-
Offline
Зарегистрирован: 20.08.2018

Инты выше таймеров, посему при накоплении флажков в регистре прерываний первыми будут инты а уже потом таймер.

Дядьки, коль пошла такая пьянка, вопрос: а если несколько событий наступит по одному вектору, флаг сработает единожды ??? Прална ???

sadman41
Offline
Зарегистрирован: 19.10.2016

А как один бит поднять несколько раз одновременно? Прерывание сработавшее определяется битом регистра, как я помню.

Komandir
Offline
Зарегистрирован: 18.08.2018

sadman41 в теории железо может увидеть что прерывание еще не обработано и сохранить второй вызов ...

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

-NMi- пишет:
если несколько событий наступит по одному вектору, флаг сработает единожды ???

Да

sadman41
Offline
Зарегистрирован: 19.10.2016

Komandir пишет:

sadman41 в теории железо может увидеть что прерывание еще не обработано и сохранить второй вызов ...


Например - как оно увидит? И где сохранит? Не на бумажке же запишет, что "два на ум пошло". Думаю, что это частный случай, вполне объяснимый стандартным механизмом установки бита прерываний. Ну, там, INT0 по LOW каждый раз переустанавливается, пока нога на земле.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

И кто кого? Реал или Спартак?

это понятно! за 100 микросекунд это сколько 62-х наносекундных тиков нащёлкает )))

storm134
Offline
Зарегистрирован: 14.04.2017

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

storm134
Offline
Зарегистрирован: 14.04.2017

Флаг сбрасывается при переходе по вектору прерывания. Но не блокируется для установки его вновь пока выполняется обработчик.  И даже отключение прерываний при входе в обработчик не припятствует выставлению флага и при включении прерываний этот флаг обработается. 

Green
Offline
Зарегистрирован: 01.10.2015

storm134 пишет:

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


Хорошо изучил? Или стек это у тебя что то своё, личное?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

storm134 пишет:

Перед выходом из обработчика надо сбрасывать флаг прерывания.

А перед тем, как что-то постить - читать документацию. И не забывать принимать таблетки по расписанию.

storm134
Offline
Зарегистрирован: 14.04.2017

В стек помещается адрес перехода по инструкции RETI.  

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

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

rst
Offline
Зарегистрирован: 25.06.2018

wdrakula пишет:
Кстати задумался - откуда у всяких "стормов" такие легенды в голове? Про стек отложенных прерываний? Я этот бред не первый раз слышу.

Это называется "ложная память". Им кажется, что они читали документацию.

Медицине известны такие случаи:  https://ru.wikipedia.org/wiki/Парамнезия

storm134
Offline
Зарегистрирован: 14.04.2017

Оговорился, теперь елозить будете до скончания времен.  Адреса перехода сохраняются в стек.  А флаги прерываний выставляются независимо от того включены они или нет.  А снятие глобального флага прерываний 'I' их не сбрасывает. И при поднятии этого флага остальные прочитаются. А в каком порядке это уже вопрос. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

storm134 пишет:

Адреса перехода сохраняются в стек

А в каком порядке это уже вопрос. 

Поизучайте ещё, а то больно много у Вас вопросов осталось. Код мой заодно запустите, посмотрите. Заодно узнаете когда и куда адреса сохраняются.