Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывания AVR
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Пришелец
Интересно какая максимальная задержка может быть между появлением запроса на прерывание и его выполнением
т.е. переходом на вектор прерывания.


например прерывания по таймеру маскируются записью в TIMSK
и далее выполняется работа которая должна происходить при запрещённых прерываниях таймера

по идее после TIMSK=0
нужно поставить несколько NOP т.к. во время этой команды уже может быть начата подготовка к переходу на прерывание

так вот вопрос сколько нопов здесь нужно?


по-моему трёх должно хватить - но может я ошибаюсь...
Duhas
время выполнения команды... по идее.. т.е. если выполняется двухтактовая команда.. на первом такте пришло прерывание.. команда довыполнится и начнется обработчик..
chief_olimp
вы хоть сами то поняли что написали? TIMSK=0 запретит прерывания по таймерам. Если его поставить в программе - прерывания не будет. Если его поставить внутри прерывания - будут запрещены дальнейшие прерывания. Что не понятно? И при чем тут NOPы?
Xenia
Цитата(Пришелец @ Nov 3 2009, 12:15) *
по идее после TIMSK=0 нужно поставить несколько NOP т.к. во время этой команды уже может быть начата подготовка к переходу на прерывание
так вот вопрос сколько нопов здесь нужно?
по-моему трёх должно хватить - но может я ошибаюсь...

Не поняла вопрос. Если вы успели установить TIMSK=0 (т.е. когда обнуление этого регистра состоялось), то никакого прерывания от таймера больше не будет, как не будет и никакой "подготовки к прерыванию". Зачем вообще нопы ставить?
В архитектуре AVR, по моему мнению, не бывает никаких "подготовок", а вопрос быть прерыванию или не быть, решается в промежутках между инструкциями. Вот тогда-то и будет решен вопрос о том, переходить ли к следующей по порядку инструкции или вылететь на прерывание. Проверка на совпадение флага прерывания и его маски производится, несомненно, аппаратно. Так что если некая инструкция обнуляет маску прерывания, то следом за ней прерывание уже не последует, даже в том случае, если бит прерывания оказался к этому моменту уже взведен. Точно так же прерывание не может случиться во время выполнения какой-либо инструкции. Отсюда следует, что ставить нопы не нужно.
Пришелец
после возврата из прерывания следующее прерывание начинает обрабатываться не сразу
это говорит о том что подготовка к переходу на прерывание существует (видимо одна команда)

если в момент обнуления TIMSK (в момент исполнения этой команды или за одну команду до неё)
начнёт обрабатываться запрос на прерывание по таймеру то он будет обработан



проще конечно не гадать а на время обнуления TIMSK запретить все прерывания cli
а потом разрешить

_CLI();
TIMSK=0;
_SEI();

наверное ... ???

Цитата(Duhas @ Nov 3 2009, 12:29) *
время выполнения команды... по идее.. т.е. если выполняется двухтактовая команда.. на первом такте пришло прерывание.. команда довыполнится и начнется обработчик..




т.е. одного nop достаточно видимо.
Xenia
Цитата(Пришелец @ Nov 3 2009, 12:56) *
проще конечно не гадать а на время обнуления TIMSK запретить все прерывания cli
а потом разрешить
_CLI();
TIMSK=0;
_SEI();

Тогда, следуя вашей логике, надо и после CLI ставить нопы smile.gif, поскольку CLI точно так же стирает маску, как и TIMSK=0 (только в другом регистре масок - в SREG). И по своей аппаратной реализации ничем не отличается.
Пришелец
Цитата(Xenia @ Nov 3 2009, 12:59) *
Тогда, следуя вашей логике, надо и после CLI ставить нопы smile.gif, поскольку CLI точно так же стирает маску, как и TIMSK=0 (только в другом регистре масок - в SREG). И по своей аппаратной реализации ничем не отличается.




После CLI не надо rolleyes.gif

я думаю эти два механизма по разному работают.
Палыч
Цитата(Пришелец @ Nov 3 2009, 12:56) *
после возврата из прерывания следующее прерывание начинает обрабатываться не сразу
это говорит о том что подготовка к переходу на прерывание существует (видимо одна команда)
Имхо, то, что после возврата из прерывания выполнится одна команда до следующего прерывания, не факт того, что подготовка к прерыванию занимает один такт! Сделано это для того, чтобы успеть выполнить некие действия между прерываниями. Как пример: после выхода из "спячки" запретить прерывания, и, даже если "висит" другое прерывание - команда cli его отложит до sei. Ваше обнуление регистра TIMSK снимет прерывание от таймера в любом случае: т.е. в процедуру прерывания с обнулённым регистром TIMSK МК не перейдет.
Xenia
Цитата(Пришелец @ Nov 3 2009, 13:05) *
я думаю эти два механизма по разному работают.

С чего бы это вдруг, если оба выставляют или снимают маски с прерываний? CLI это вроде рубильника, отключающего электричество во всем доме, а TIMSK - для отдельной квартиры. И с точки зрения отдельной квартиры, все равно как в ней свет отключили - главным домовым рубильном (CLI) или тем, что стоит на лестничной клетке рядом со счетчиком (TIMSK). Никаких дополнительных задержек не возникнет ни в том, ни в другом случае.
А вы собрались пред тем, как отключить от сети свой телевизор, предварительно обесточить всех жильцов в доме smile.gif. И расчитывете, что так ваш телевизор отключится быстрее.
chief_olimp
по моему это обсуждение не имеет смысла. Я на пример так и не понял чего добивается автор
Пришелец
про cli явно написано что после него не выполнится ни одно прерывание

про флаги индивидуальных запретов прерываний такого не написано.




после появления запроса прерывания выполняется текущая команда
так вот если этой командой окажется TIMSK=0
то запрос будет принят на обработку или нет ???

Цитата(chief_olimp @ Nov 3 2009, 13:23) *
по моему это обсуждение не имеет смысла. Я на пример так и не понял чего добивается автор




добиваюсь ясности в своей голове - может и не только мне а и другим это будет полезно.
Vetal-Soft
))) Даже если допустить, что произойдет так, что сигнал прерывания от таймера поступит во время выполнения TIMSK=0 и после ее выполнения, все таки, выполниться переход на подпрограмму его обработки, то после возврата из нее при выполнении следующей за "TIMSK=0;" команды, прерывания от таймера уже будут запрещены. Зачем нужны NOP ?
Пришелец
сдаюсь rolleyes.gif


согласен

убедили

Спасибо.
defunct
Цитата(Пришелец @ Nov 3 2009, 12:05) *
я думаю эти два механизма по разному работают.

Проц __заканчивает выполнение текущей комады__, после чего если есть хотя бы одно активное прерывание, осуществляет неявную команду JMP на соответвующий активному прерыванию вектор.
Спите спокойно, после команды TIMSK = 0 активных прерываний от таймера не будет, но следует отметить, что
сишное выражение
TIMSK = 0;
скорее всего разобъется на две команды, например

ldi Rd, 0
out TIMSK, Rd

После ldi - прерывание от таймера еще может случиться, а после out - однозначно нет.
501-q
Цитата(defunct @ Nov 4 2009, 04:02) *
ldi Rd, 0
out TIMSK, Rd

После ldi - прерывание от таймера еще может случиться, а после out - однозначно нет.


После out в течении ещё одной команды прерывания от таймера могут быть. Практика. И документация.

После команды sei ещё одна команда защищина от прерываний. Тоже практика и докумнтация.

Т.е. вот так работать не будет:

ldi Rd, 0
sei
out TIMSK, Rd
-- вот здесь ещё может быть прерывание от таймера


А вот так -- работает:

ldi Rd, 0
out TIMSK, Rd
sei
-- здесь прерываний от таймера не будет
777777
Цитата(Пришелец @ Nov 3 2009, 12:56) *
если в момент обнуления TIMSK (в момент исполнения этой команды или за одну команду до неё)
начнёт обрабатываться запрос на прерывание по таймеру то он будет обработан

Вы для начала расскажите, чего вы хотите добиться в самом общем виде, а то непонятно зачем обнулять TIMSK да еще при этом делать общий запрет прерываний. Почему вы боитесь, что прерывание может выполниться сразу после обнуления TIMSK, но не боитесь, что оно выполнится за несколько команд до него.
bekas
Товарищи специалисты, у меня тоже есть вопрос относительно прерываний. Хочу предупредить я в этом деле ещё чайник.

Есть ATiny2313 и нужно организовать прерывание по совпадению таймера Т1, загружаю в регистры следующее:

TIMSK - 01000000 (Разрешить прерывания по совпадению канала А таймера Т1)
TCCR1B - 00001010 (Сброс таймера при совпадении, частота таймера 1/8 тактовой)
OCR1AL и OCR1AН некоторые числа

Провожу отладку симулятором AVR Studio, при совпадении значения таймера TCNT1 и OCR1A появляется флаг TIFR, сбрасывается значение TCNT1, но прерывание не происходит, можете мне сказать что я забыл сделать???
SysRq
Цитата(bekas @ Nov 25 2009, 17:02) *
...можете мне сказать что я забыл сделать???
Разрешить прерывания глобально. Флаг I в SREG. Команды SEI, CLI.
Duhas
мб разрешить прерывания глобально? SEI...
bekas
не помогает, следующеедействие после команды SEI это переход по адресу $001 при этом даже флаг TIFR не успевает установиться
ILYAUL
Цитата(bekas @ Nov 26 2009, 00:06) *
не помогает, следующеедействие после команды SEI это переход по адресу $001 при этом даже флаг TIFR не успевает установиться


Вам эта таблица знакома? Там команда типа RJMP существует ?


Table 21. Reset and Interrupt Vectors
Vector
No.
Program
Address Source Interrupt Definition
1 0x0000 RESET External Pin, Power-on Reset, Brown-out Reset,
and Watchdog Reset
2 0x0001 INT0 External Interrupt Request 0
3 0x0002 INT1 External Interrupt Request 1
4 0x0003 TIMER1 CAPT Timer/Counter1 Capture Event
5 0x0004 TIMER1 COMPA Timer/Counter1 Compare Match A
6 0x0005 TIMER1 OVF Timer/Counter1 Overflow
7 0x0006 TIMER0 OVF Timer/Counter0 Overflow
8 0x0007 USART0, RX USART0, Rx Complete
9 0x0008 USART0, UDRE USART0 Data Register Empty
10 0x0009 USART0, TX USART0, Tx Complete
11 0x000A ANALOG COMP Analog Comparator
12 0x000B PCINT Pin Change Interrupt
13 0x000C TIMER1 COMPB Timer/Counter1 Compare Match B
14 0x000D TIMER0 COMPA Timer/Counter0 Compare Match A
15 0x000E TIMER0 COMPB Timer/Counter0 Compare Match B
16 0x000F USI START USI Start Condition
17 0x0010 USI OVERFLOW USI Overflow
18 0x0011 EE READY EEPROM Ready
19 0x0012 WDT OVERFLOW Watchdog Timer Overflow
smac
Цитата(bekas @ Nov 26 2009, 00:06) *
не помогает, следующеедействие после команды SEI это переход по адресу $001 при этом даже флаг TIFR не успевает установиться

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

Вот пока писал Вам уже предыдущий оратор правильную дорогу (к таблице векторов прерываний) показал.
ILYAUL
Цитата(smac @ Nov 26 2009, 00:24) *
Вот пока писал Вам уже предыдущий оратор правильную дорогу (к таблице векторов прерываний) показал.

Это не главное , главное научиться ей пользоваться
bekas
Да, были разрешены внешние прерывания, по умолчанию на низкий уровень входа INT0 и при наладке я этот вход не использовал-отсюда скачёк по адресу $001.
Теперь вроде работает. Спасибо всем.
bekas
Появился ещё один вопрос: после обработки прерывания насколько мне кажется прогграмма должна продолжить выполняться с места вызова прерывания, а у меня она почемуто снова вызывает прерывание и выполняет его циклически. Как с этим бороться??

Для наглядности ниже текст программы:


Код
; Начало программы
rjmp Init          ;$000 Первая выполняемая комманда
reti
reti
reti
rjmp Time

;======================================

Time:

  inc Book
  nop
  nop
  nop
  cli

reti;

;======================================
Init:

ldi temp, 0b01000000
out TIMSK, temp

ldi temp, 0b00001010     ;
out TCCR1B,temp        

out OCR1AL, temp

ldi Book,0                 ; задаём начальное
;====================================================================

Begine:

SEI

nop
nop
nop

CLI

rjmp Begine
defunct
Цитата(bekas @ Dec 11 2009, 16:52) *
Для наглядности ниже текст программы:

По тексту программы - для наглядности надо бы:

1. указать МК, для которого пишется программа .include "tn2313def.inc"
2. вместо веселых нечитаемых констант 0b0100000, пользовать осмысленные имена битов (1 << OCIE1A) чтобы было видно какие биты включаются.
3. поудалять бездумно натыканные команды CLI.
4. описать всю таблицу прерываний как в даташите.
5. вынести SEI за переделы основного цикла.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.