CodeVision AVR в вопросах и ответах
потеряно
- Реклама
- Сообщения: 392
- Зарегистрирован: Сб дек 12, 2009 02:15:45
спасибо, понятно.
тогда такой вопрос, если запрещать и разрешать прерывание прямо в обработчике прерывания, можно ли??
тогда такой вопрос, если запрещать и разрешать прерывание прямо в обработчике прерывания, можно ли??
Код: Выделить всё
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
какой то мой код
#asm("cli")
какой то мой код
#asm("sei")
}- Сообщения: 326
- Зарегистрирован: Сб сен 06, 2008 12:56:13
Если флаг общего разрешения прерываний "I" в регистре SREG сброшен - команда #asm("cli"), то, если после этого возникают условия отдельных прерываний, устанавливаются их флаги. После общего разрешения прерываний, они обрабатываются в порядке приоритета.neon-f писал(а):подскажите, если запрещаешь прерыванияв это время произходит прерывание, потом разрешаешь прерываниеКод: Выделить всё
#asm("cli")- это прерывание потеряно? или после разрешения прерываний оно обработается?Код: Выделить всё
#asm("sei")
- Сообщения: 392
- Зарегистрирован: Сб дек 12, 2009 02:15:45
- Сообщения: 326
- Зарегистрирован: Сб сен 06, 2008 12:56:13
Если оно было разрешено и имеет флаг, то не потеряется.neon-f писал(а):ValBag
так все таки не потеряю прерывание???
- Реклама
- Сообщения: 402
- Зарегистрирован: Пт май 29, 2009 10:14:29
Ничего не догнал. У кого нибудь примерчик будет , что бы можно было пощупать?ValBag писал(а):Если флаг общего разрешения прерываний "I" в регистре SREG сброшен - команда #asm("cli"), то, если после этого возникают условия отдельных прерываний, устанавливаются их флаги. После общего разрешения прерываний, они обрабатываются в порядке приоритета.neon-f писал(а):подскажите, если запрещаешь прерыванияв это время произходит прерывание, потом разрешаешь прерываниеКод: Выделить всё
#asm("cli")- это прерывание потеряно? или после разрешения прерываний оно обработается?Код: Выделить всё
#asm("sei")
- Сообщения: 326
- Зарегистрирован: Сб сен 06, 2008 12:56:13
Можно словесно. Допустим, у вас есть разрешение на прерывание по переполнению таймера0. Теперь вы запрещаете глобально все прерывания (cli). Таймер продолжает работать, разрешение на прерывание по его переполнению есть, выставляются флаги запроса прерывания. Но глобальное условие запрещает все прерывания. Флаг запроса таймера не "пропадает" и при общем разрешении прерываний (sei), он обработается. Но есть один момент. Если в период "перерыва" в прерываниях возникло несколько запросов от таймера, то выполнится только последнее.nsl2004 писал(а):Ничего не догнал. У кого нибудь примерчик будет , что бы можно было пощупать?
правильнее сказать - обработается только один-единственный запрос, т.е. возникнет только одно прерывание.ValBag писал(а):Но есть один момент. Если в период "перерыва" в прерываниях возникло несколько запросов от таймера, то выполнится только последнее.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 326
- Зарегистрирован: Сб сен 06, 2008 12:56:13
Можно и так сказать. Но часть прерываний, если они были, потеряются.ARV писал(а):правильнее сказать - обработается только один-единственный запрос, т.е. возникнет только одно прерывание.
- Сообщения: 392
- Зарегистрирован: Сб дек 12, 2009 02:15:45
а если такой варианнт. во время #asm("cli") - #asm("sei") происходит два разных события, например переполнение Т0 и Т2, значит подымется 2 разных флага и после #asm("sei") обработаются оба события ???
- Сообщения: 326
- Зарегистрирован: Сб сен 06, 2008 12:56:13
Да, с учетом сказанного выше и в порядке приоритета.neon-f писал(а):а если такой варианнт. во время #asm("cli") - #asm("sei") происходит два разных события, например переполнение Т0 и Т2, значит подымется 2 разных флага и после #asm("sei") обработаются оба события ???
- Сообщения: 402
- Зарегистрирован: Пт май 29, 2009 10:14:29
2ValBag
Спасибо. Несколько понятнее стало. Надо что то скропать поигратся и посмотреть.
Спасибо. Несколько понятнее стало. Надо что то скропать поигратся и посмотреть.
- Сообщения: 459
- Зарегистрирован: Вс июн 01, 2008 12:16:38
Небольшое дополнение - есть все-таки флаги которые могут потеряться, их немного но все-же. Например внешнее прерывание по низкому уровню на выводе - флаг устанавливается только на время действия низкого уровня, естественно если низкий уровень произошел между командами cli и sei. Естественно если команды идут подряд, то это очень короткий промежуток и вероятность пропуска прерываний мала, но если между командами есть еще и другие - т.е время между командами не очень мало, то есть вероятность пропустить короткий импульс.
- Сообщения: 326
- Зарегистрирован: Сб сен 06, 2008 12:56:13
Да, такая вероятность есть. Только флаг там не устанавливается. Прерывание действует все время, пока присутствует условие, в данном случае - низкий уровень, а флаг сброшен постоянно.
- Сообщения: 392
- Зарегистрирован: Сб дек 12, 2009 02:15:45
ну с этим вопросом все понятно
теперь такой вопрос
я в прерывании подымаю "флаг" , потом в теле проверяю поднят ли, и если да, то делаю какое-то действие, а флаг сбрасываю. в качестве флага у меня обычная переменная. а как можно обойтись без переменной? где то читал что можно использовать регистры, которые сами сбрасываются после использования, но где не найду.
вот как это сейчас делаю я:
теперь такой вопрос
я в прерывании подымаю "флаг" , потом в теле проверяю поднят ли, и если да, то делаю какое-то действие, а флаг сбрасываю. в качестве флага у меня обычная переменная. а как можно обойтись без переменной? где то читал что можно использовать регистры, которые сами сбрасываются после использования, но где не найду.
вот как это сейчас делаю я:
Код: Выделить всё
bit flag=0;
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
flag=1;
}
..
if (flag==1) {flag=0; какой то мой код ;}- Сообщения: 326
- Зарегистрирован: Сб сен 06, 2008 12:56:13
Я тоже пользуюсь таким приемом, чтобы совершить какие-то действия после возврата из прерывания. Другие пока не знаю. Переменная то, битовая, в чем проблема.
прерывание для того и существует, чтобы немедленно отреагировать на какое-то событие. только в очень редких случаях можно согласиться с тем, что событие фиксируется мгновенно, а обрабатывается затем когда-нибудь, например, при фиксации игольчатых импульсов. в других случаях надо трижды подумать, оправдан ли такой подход. можео сделать обработку события в самом обработчике прерываний, или наоборот, обойтись вообще без прерываний - методом опроса.
вот смотрите: вы ставите флаг в обработчике - зачем? если запретить обработку прерывания по переполнению таймера, то не потребуется и переменная-флаг: в регистре TIFR и так при переполнении таймера установится соответствующий бит-флаг! вам остается только иной раз проверять - стоит флаг или нет. а сбросить его можно записью единички. вот и выходит, что в вашем случае нет нужды тратить память на обработчик прерывания и битовую переменную...
вот смотрите: вы ставите флаг в обработчике - зачем? если запретить обработку прерывания по переполнению таймера, то не потребуется и переменная-флаг: в регистре TIFR и так при переполнении таймера установится соответствующий бит-флаг! вам остается только иной раз проверять - стоит флаг или нет. а сбросить его можно записью единички. вот и выходит, что в вашем случае нет нужды тратить память на обработчик прерывания и битовую переменную...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 392
- Зарегистрирован: Сб дек 12, 2009 02:15:45
на самом деле вот как это выглядит
для чтения ds18b20 использую модифицированную библиотеку, которая запрещает прерывания на время общения по 1 Wire. так вот если чтение ds18b20 делать внутри прерывания, то останавливается динамическая индикация. а если читать ds18b20 вообще без прерываний, то получается постоянное чтениедатчика, что во первых вредно точности измерения, и самое главное контроллеру некогда опрашивать кнопки. если добавить задержку delay, то до кнопок вообще дело не доходит. Вот такое кино.
Код: Выделить всё
bit flag=0;
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{ какой то код связанный с динамической индикацией }
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
какой то код2
flag=1;
}
..
if (flag==1) {flag=0; чтение ds18b20 ;}в том случае, если флаг сигнализирует о том, что надо что-то сделать действительно "редкое", ваш подход оправдан. более того, долгие процедуры (а работу с датчиком быстрой не назовешь) недопустимо делать в прерывании. однако, помимо всего прочего, вам бы надо модифицировать свою функцию работы с датчиком так, чтобы прерывания запрещались только на время тайм-слота, т.е. примерно 15-20 микросекунд, а не на весь процесс обмена (порядка нескольких миллисекунд) - тогда никакого влияния на динамическую индикацию и что-либо еще работа с датчиком не окажет (20 микросекунд слишком мало, чтобы быть заметным человеку)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 392
- Зарегистрирован: Сб дек 12, 2009 02:15:45
так у меня и запрещается только на время тайм-слота, поэтому динамическая индикация и не прерывается. а вот если чтение датчика делать внутри одного из прерываний, то уже не важно как и на сколько запрещать, и запрещать ли вообще, т.к. пока не обработается одно, второе все равно не наступит.


