Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывания в Atmel 8535
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
DMD
У меня возникла парочка вопросов по прерываниям, смотрел в документации - не нашел. Если сможете - подскажите, пожалуйста.
Как я понял из документации, при входе в обработчик прерывания все остальные прерывания запрещаются, ведь так? То есть неявно выполняется инструкция cli. А что происхоит в случае, если за время обработки происходит внешнее прерывание, INT0, к примеру? Информация о нем отбрасывается или остается где-то? Дело в том, что я пишу обработчик и мне надо знать было ли за время работы обработчика прерывание. Если было, то после выхода вызвать другой обработчик...
И ещё вопрос: как я понял, приоритет у всех внешних прерываний одинаковый, ведь так? А назначить приоритет можно только программно, правда?
Спасибо.
Qwertty
Цитата(DMD @ Jun 4 2008, 00:48) *
Если было, то после выхода вызвать другой обработчик...

Это произойдет само по себе. Сразу после выхода из текущего прерывания.

Цитата(DMD @ Jun 4 2008, 00:48) *
И ещё вопрос: как я понял, приоритет у всех внешних прерываний одинаковый, ведь так? А назначить приоритет можно только программно, правда?
Спасибо.

Приоритетов в АВР нет. Есть псевдоприоритеты - если два прерывания произойдут одновременно, то первым будет обработано то, адрес вектора у которого меньше. Возможно правда сделать вложенные прерывания - вставить sei в обработчик.
DMD
А есть возможность как-нибудь очистить вот эту очередь прерываний? Я имею ввиду сделать так, чтобы после обработки текущего отложенные прерывания не выполнялись?.. Куда хоть посмотреть можно?
dENIM
Цитата(DMD @ Jun 4 2008, 01:24) *
А есть возможность как-нибудь очистить вот эту очередь прерываний? Я имею ввиду сделать так, чтобы после обработки текущего отложенные прерывания не выполнялись?.. Куда хоть посмотреть можно?

флаги прерываний устанавливаются независимо от того, разрешены глобально прерывания, или нет.
можно контролировать конкретные флаги и обнулять их по необходимости.
zhevak
Цитата(DMD @ Jun 4 2008, 04:24) *
А есть возможность как-нибудь очистить вот эту очередь прерываний? Я имею ввиду сделать так, чтобы после обработки текущего отложенные прерывания не выполнялись?.. Куда хоть посмотреть можно?


Возвращайтесь из обработчика прерывания не по команде RETI, а по команде RET. Разница в том, что RETI насильственно устанавливает флаг I в регистре SREG, а команда RET -- флаги в регистре не трогает вообще. И не забудьте про регистры, которые вы в начале обработчика сохранили в стеке.

А флаги конкретных прерываний (которые имели наглость установиться за это время) снимайте сами, как это посоветовал dENIM.
smac
Цитата(Qwertty @ Jun 4 2008, 01:17) *
Это произойдет само по себе. Сразу после выхода из текущего прерывания.

Небольшое уточнение, насколько я знаю в контроллерах АВР есть два типа прерываний:
1 флаги которых защелкиваются, после возникновения причин прерываний и сбрасываются либо после перехода по вектору соответствующего прерывания либо программно
2. прерывания, флаги которых действуют только когда присуствтует причина прерываний (по-моему как раз ИНТ0 можно настроить в режим когда флаг прерывания действуе пока на входе соответствующий лог уровень)
fmdost
Цитата(smac @ Jun 6 2008, 16:23) *
... в контроллерах АВР есть два типа прерываний:
1 флаги которых защелкиваются, после возникновения причин прерываний и сбрасываются либо после перехода по вектору соответствующего прерывания либо программно
2. прерывания, флаги которых действуют только когда присуствтует причина прерываний (по-моему как раз ИНТ0 можно настроить в режим когда флаг прерывания действуе пока на входе соответствующий лог уровень)

Есть ещё флаги которые снимаются только по условию выполнения каких либо действий.
Например флаг UART RTX снимается только если произвести выборку из регистра принятых данных UDR
777777
Цитата(Qwertty @ Jun 4 2008, 01:17) *
Возможно правда сделать вложенные прерывания - вставить sei в обработчик.


Это и делает GNUтый С-компилятор. Кстати, вопрос к знатокам, а можно ли запретить прерывания в обработчике? Т.е. не с помощью вызова cli() в начале, а уговорить компилятор не вставлять там sei.
777777
Цитата(zhevak @ Jun 6 2008, 10:11) *
Возвращайтесь из обработчика прерывания не по команде RETI, а по команде RET.

Возвращаться из обработчика по команде RET нельзя!
Цитата(zhevak @ Jun 6 2008, 10:11) *
Разница в том, что RETI насильственно устанавливает флаг I в регистре SREG, а команда RET -- флаги в регистре не трогает вообще.

Вот именно! А их надо восстанавливать. Что тебе насчитает основная программа, если прерывания будут периодически портить регистр состояния?
zhevak
Цитата(777777 @ Jun 7 2008, 13:52) *
Возвращаться из обработчика по команде RET нельзя!


Да, почему нельзя? Если ты пишешь код и четко понимаешь как он исполняется, то какие проблемы?

У человека стоит задача __необрабатывать__ второе прерывание, если одновременно пришли "оба-два", или флаг второго прерывания поднялся до окончания обработки первого. Другое дело, что может быть человек не до конца еще понимает ситуацию, что нужно делать, т.е. еще нет четкого понятия как девайс должен работать. Отсюда такие несколько странные условия задачи. Но этот вопрос находится уже в другой плоскости.

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


А вообще, беспредметно спорить, только время терять.
777777
Цитата(zhevak @ Jun 7 2008, 14:38) *
Я не вижу здесь ни каких проблем. Не традиционный подход? -- Да. Опасные игры с кодом? -- Да. Но если ты четко знаешь, что происходит, то какие проблемы? По моему, здесь как раз и проходит грань между программированием, как "технология", и программированием, как "искусство".

Проблема в том, что это только сегодня ты четко знаешь, что происходит, через неделю будешь смутно вспоминать, а через месяц вообще забудешь. А код понадобится модернизировать. А если это будет делать другой программист? Думаешь он разделит твой восторг от отношения к программированию как к искусству? smile.gif А твой работодатель, боюсь, вообще будет категорически против. Потому что ему не видно твоего искусства, он видит только как работает устройство, есть там глюки или нет, и если они есть, то хвалится красотой исходного кода бессмысленно - никто не оценит. Да и пользы от всяких хитроумных трюков обычно никакой нет - даже если экономится 10-20% памяти, все равно оставшуюся неиспользуемую память ты никуда не денешь. И даже когда программа не помещается в памяти, выгоднее вместо ATmega8535 поставить ATmega16, чем мудрить с разного рода программистскими трюками - в конце концов они тебе выйдут боком.
Так что, с точки зрения бизнеса, к программированию надо относиться как к серийному производству, смотреть на устройство глазами пользователя, а не искусствоведа, приходящего в восторг от красиво написанного исходного кода.
Цитата(zhevak @ Jun 7 2008, 14:38) *
А вообще, беспредметно спорить, только время терять.

Ну почему же, спроить всегда полезно, в спорах, как известно, рождается истина.
artemm
Цитата(Qwertty @ Jun 4 2008, 00:17) *
Возможно правда сделать вложенные прерывания - вставить sei в обработчик.

Если разрешить прерывания в обработчике какого-нить прерывания то будет шопопало.
Если в обработчике прерывания I2C разрешить прерывания, то МК зависает. (по крайней мере у меня)
Также в прерывани ком порта будет происходить шопопало. Проверено
zhevak
Цитата(777777 @ Jun 9 2008, 10:29) *
Проблема в том, что это только сегодня ты четко знаешь, что происходит, через неделю будешь смутно вспоминать, а через месяц вообще забудешь...


Да, да, да. Это все так. Только, разумеется, сложные для понимания места обильно комментируем.


Цитата
Так что, с точки зрения бизнеса, к программированию

Точки зрения бывают разные.

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

Мне нужно сделать МК-девайс с потреблением не более 150 мкА. Дело не простое, так как мне нужно получить на УФ-датчике напряжение 300 В. Габарит -- не более размера батарейки "Крона". Питание устройства -- та же "Крона" В. Эти данные привожу, что бы Вы прочувствовали "пресс" требований, которые выдвигает заказчик.) Поэтому мне глубоко наплевать, что код будет не читабельный. Комментарии никто не отменял. Мне нужно обязательно получить результат, а уж как я его добиваюсь, заказчика это не волнует. Деньги он платит не за читабельность кода, а за конечный продукт. Это только один пример. Могу привести другой пример, из своей же практики. Пример, с точностью до наоборот.

Так что, конкретно можно говорить только по конкретной ситуации. Все остальное -- философия.


Цитата
Ну почему же, спроить всегда полезно, в спорах, как известно, рождается истина.

Еще раз: беспредметный спор == потеря времени. Предмета спора у нас нет. (По сути, разговор идет о гипотетическом устройстве и придуманной проге.)
Maik-vs
Цитата(artemm @ Jun 9 2008, 09:56) *
Если разрешить прерывания в обработчике какого-нить прерывания то будет шопопало.
Если в обработчике прерывания I2C разрешить прерывания, то МК зависает. (по крайней мере у меня)
Также в прерывани ком порта будет происходить шопопало. Проверено

А у меня не зависает. Проверено.
Вы пишите на ассемблере, отлаживайте. И тогда всё будет нормально, хоть с вложенными прерываниями, хоть с выложенными smile.gif
defunct
Цитата(zhevak @ Jun 7 2008, 13:38) *
Да, почему нельзя? Если ты пишешь код и четко понимаешь как он исполняется, то какие проблемы?

И превед глюкодром!
Лучше не давать бестолковых советов.

Из обработчика прерывания следует возвращаться командой RETI.


Цитата(DMD @ Jun 4 2008, 01:24) *
А есть возможность как-нибудь очистить вот эту очередь прерываний? Я имею ввиду сделать так, чтобы после обработки текущего отложенные прерывания не выполнялись?.. Куда хоть посмотреть можно?

А вы уверены, что это действительно то, что Вам нужно?
Обработчики прерываний можно сделать максимально короткими, тогда не придется сбрасывать "очереди отложенных прерываний". Все будет успевать отрабатываться как положено.

Например:
прерывание от UART - принять байт, взвести флаг "есть" данные и выйти.
прерывание таймера - увеличить внутренний счетчик (дергуть ногой если надо) и выйти.
прерывание от АЦП - сохранить результат АЦП (переключить на другой канал если требуется) и выйти.
и т.п.

Основную же обработку - вести в основном цикле программы (тобиш в main).

Цитата(Maik-vs @ Jun 9 2008, 12:31) *
Вы пишите на ассемблере, отлаживайте. И тогда всё будет нормально, хоть с вложенными прерываниями, хоть с выложенными smile.gif

И будут преведы, да еще и на ассемблере. smile.gif
Потом попробуйте к такой программе прилепить новую функциональность. (например еще один протокол обмена).

AVR со своим одноуровневым контроллером прерываний избавляет пользователя от множества проблем, бери да спокойно работай. Глубина стека прогнозируемая, overload прогнозируемый и легко расчитываемый. Карандаш в руки - просчитать нагрузку обработчиков прерываний и все - можно спасть спокойно. Неспешно расширять функционал программы не боясь что система загнется (не трогая обработчиков прерываний).

почему многие так и рвутся получить проблему (через одно место работая с прерываниями)? А потом эту проблему исправлять опять же через то же самое место?!
alx2
Цитата(artemm @ Jun 9 2008, 10:56) *
Если разрешить прерывания в обработчике какого-нить прерывания то будет шопопало.
Если в обработчике прерывания I2C разрешить прерывания, то МК зависает. (по крайней мере у меня)
Будет происходить не "шопопало", а "шонаписано". Если МК зависает, это значит, что обработчик написан неправильно, и не более того. Наверное стоило не делать поспешный вывод, что вложенные прерывания невозможны, а проанализировать ситуацию и найти ошибку. У меня во многих устройствах выполняется sei в обработчике - и никаких "шопопало", работает как часы. Подозреваю, что "шопопало" возникало из-за превышения дозволенного уровня вложенности обработчиков...
Maik-vs
Цитата(defunct @ Jun 9 2008, 15:42) *
И будут преведы, да еще и на ассемблере. smile.gif
Потом попробуйте к такой программе прилепить новую функциональность. (например еще один протокол обмена).

Преведы бывают хоть на ассемблере, хоть на с хоть на чём! Если руки не оттуда.
Функциональность программы для МК - гм, изначально несколько более строго задаётся, чем функциональность программы для большого компьютера. Брать куски из одного проекта для другого - да. Расширять функциональность - это если плохое ТЗ.

Цитата(defunct @ Jun 9 2008, 15:42) *
почему многие так и рвутся получить проблему (через одно место работая с прерываниями)? А потом эту проблему исправлять опять же через то же самое место?!

Потому что многих жмёт пространство и время. Про коробочку размером с "крону" написано. Про время: попробуйте сделать хоть генератор текста для врезания в видеосигнал - будете считать циклы процессора. С карандашом в руках, совсем несложно.
defunct
Цитата(Maik-vs @ Jun 10 2008, 15:39) *
Преведы бывают хоть на ассемблере, хоть на с хоть на чём! Если руки не оттуда.

На ассемблере преведов на порядок больше, и руки тут не при чем.
Зерно примитивов меньше - текста больше, сложность программы выше.
Программа получается ДУБОВАЯ - практически не подлежащая вразумительному расширению.

Цитата
Функциональность программы для МК - гм, изначально несколько более строго задаётся, чем функциональность программы для большого компьютера. Брать куски из одного проекта для другого - да.

У кого как, мне важнее time-to-market и возможность заливать в одно и тоже железо разное ПО. Постепенно наращивать функциональность приходится - допустим выпустят новый Сепам или МРЗС и еще какую-то байду, добавить их к уже имеющейся прошивке нет проблем, и все управляющие устройства сразу умеют с ними работать. Надо только обновить прошивку.
За примерами далеко ходить не надо -
DVD/CD-RW - поддержка дисков разных производителей часто добавляется уже после выхода привода в продажу;
Wireless AP / Router'ы - добавление различных режимов и служб тоже происходит после.
и т.п.
Цитата
Расширять функциональность - это если плохое ТЗ.

Невозможность расширения функциональности - это мертвое устройство. Т.к. через полгода придут конкуретны, с более дешевым девайсом и чуть более широкой функциональностью, и ваше устройство никто брать не будет.

Цитата
Потому что многих жмёт пространство и время.

Пространство меня не жмет. Хоть в медном тазу можно клепать, лишь бы крепилось на дин-рейку.
А про время, я вас умаляю. Ассемблеру с C не тягяться в этом.
Улыбнуло. ;>

Цитата
Про коробочку размером с "крону" написано. Про время: попробуйте сделать хоть генератор текста для врезания в видеосигнал - будете считать циклы процессора. С карандашом в руках, совсем несложно.

Мне не нужен генератор врезки текста, но например в IP router я смогу при необходимости легко добавить telnet консольку или http сервер или фильтр какой-нить хитроумный.
galjoen
Цитата(defunct @ Jun 10 2008, 18:22) *
На ассемблере преведов на порядок больше, и руки тут не при чем.
Зерно примитивов меньше - текста больше, сложность программы выше.
Программа получается ДУБОВАЯ - практически не подлежащая вразумительному расширению.
У кого как, мне важнее time-to-market и возможность заливать в одно и тоже железо разное ПО. Постепенно наращивать функциональность приходится - допустим выпустят новый Сепам или МРЗС и еще какую-то байду, добавить их к уже имеющейся прошивке нет проблем, и все управляющие устройства сразу умеют с ними работать. Надо только обновить прошивку.

А я наоборот как наполучал преведы на С (для АВР), так на асм перешёл. И С для АВР забыл как страшный сон (для компьютера конечно на С++ пишу). У АВР 80% работы - это работа с USART, CAN, SPI, таймерами, портами др. устройсвами. А в этом С только мешает. Напишешь на С и понимаешь, что написал программу на ассемблере с помощью С. Всё равно приходится весь получившийся ассемблерный текст контролировать.
А насчёт расширяемости:
1. Я сначала USB-HID написал и обращение через него к специфическим задачам.
2. Самопрограммирование через USB.
3. Всякие модбасы и др. USARTовские дела.
4. Mass Storage.
5. FAT (при работе без подключения к компьютеру).
6. SLEEP (работа от ионистора).
7. CAN.
Всё это работает в разных проектах в разных вариантах. В т.ч. и всё это в одном устройстве (на AT90CAN128). И прошивки без проблем через интернет обновляются самими пользователями. Причём они даже об этом иногда не знают.
Я всё это к тому, что и на асме и на С можно как плохо, так и хорошо писать.
777777
Цитата(galjoen @ Jun 10 2008, 19:17) *
А я наоборот как наполучал преведы на С (для АВР), так на асм перешёл.


Вместо того, чтобы найти их причину? smile.gif
galjoen
Цитата(777777 @ Jun 11 2008, 09:51) *
Вместо того, чтобы найти их причину? smile.gif

Нашёл несколько причин. Одна из них - несохранение С некоторых регистров в прерываниях. Искал долго т.к. вылезало редко, не во всех режимах, вылезало совсем в другом месте (в том месте которое было прервано после возврата с испорченными регистрами) и приводило к тому, что процессор выдавал на шину 1, а устройство 0. При этом происходило замыкание, срабатывала защита по питанию, срабатывал BOD, процессор перезапускался. Столько времени я бесполезно потерял... Понимаю, что в новых версиях это исправлено, но у меня уже какая-то аллергия на С для АВР выработалась. Мне всё кажется, что это глюк не мой, а С. А когда на асме пишу, то между мной и процессором никого нет... Макрокоманд для стандартных случаев понаписал. Если надо быстро сделать (и можно неоптимально), то макрокомандами пользуюсь. В принципе что-то типа своего языка на макрокомандах получилось.
ЗЫ Прошу прощения за офтоп.
Maik-vs
Вот оно, ключевое слово:
Цитата(defunct @ Jun 10 2008, 18:22) *
У кого как, мне важнее time-to-market ...


Цитата(defunct @ Jun 10 2008, 18:22) *
За примерами далеко ходить не надо -
DVD/CD-RW,Wireless AP / Router'ы и т.п.

ИМХО для этого всего avr-ки мягко говоря, слабоваты. Или есть примеры DVD-RW на любимой народом восьмой меге? Нет, не контроллер евонного двигателя, а весь DVD привод?

Цитата(defunct @ Jun 10 2008, 18:22) *
Пространство меня не жмет. Хоть в медном тазу можно клепать, лишь бы крепилось на дин-рейку.
А про время, я вас умаляю. Ассемблеру с C не тягяться в этом.
Улыбнуло. ;>

Прям представил медный таз, повешенный на DIN-рейку smile.gif УмАлять меня не надо, и улыбаться про себя типа как Джоконда. Лучше расскажите, как на С написать обработчик прерывания, длиной, например, 10 тактов процессора.
defunct
Цитата(Maik-vs @ Jun 12 2008, 14:11) *
Лучше расскажите, как на С написать обработчик прерывания, длиной, например, 10 тактов процессора.

Что есть такты и зачем именно 10? Что это даст?
Прерывания использую не ради тактов, а ради своевременной реакции на события системы. И мне производительности хватает.

Цитата
ИМХО для этого всего avr-ки мягко говоря, слабоваты.

Если пользовать все обработчики длиной в 10 тактов, то конечно AVRки будут слабоваты для всего.
sKWO
Цитата(defunct @ Jun 12 2008, 22:49) *
Если пользовать все обработчики длиной в 10 тактов, то конечно AVRки будут слабоваты для всего.

+1 biggrin.gif
733259
Цитата
Дело в том, что я пишу обработчик и мне надо знать было ли за время работы обработчика прерывание.
Можно узнать для таймерных прерываний - смотрите регистр TIFR.
Цитата
А есть возможность как-нибудь очистить вот эту очередь прерываний? Я имею ввиду сделать так, чтобы после обработки текущего отложенные прерывания не выполнялись?.. Куда хоть посмотреть можно?
Также через TIFR можно очистить соответствующие флаги установкой того же бита в TIFR. Смотреть в даташит, написано.

Цитата
А у меня не зависает. Проверено.
Вы пишите на ассемблере, отлаживайте. И тогда всё будет нормально, хоть с вложенными прерываниями, хоть с выложенными
У меня тоже не зависает, проверено.
Пишу на С (gcc), как-то и особой отладки не разу не требовалось.
Maik-vs
Цитата(defunct @ Jun 12 2008, 22:49) *
Если пользовать все обработчики длиной в 10 тактов, то конечно AVRки будут слабоваты для всего.

Вы просто не умеете их готовить biggrin.gif
sKWO
Цитата(Maik-vs @ Jun 12 2008, 15:11) *
Прям представил медный таз, повешенный на DIN-рейку smile.gif УмАлять меня не надо, и улыбаться про себя типа как Джоконда. Лучше расскажите, как на С написать обработчик прерывания, длиной, например, 10 тактов процессора.

Прочитайте AVR035, многие сишные команды дают одинаковый код если бы Вы писали на ассемблере, ну а зная ключевые слова конкретного компилятора можете вмешаться в сохранение рабочих регистров или исключить их сохранение , ну и обработчик прерываний будет коротеньким.
С другой стороны если вы имеете ввиду построение обработчика прерывания таким образом чтобы немедленно отреагировать на определённое событие ну а в основном цыкле делать его обработку - тогда зачем заморачиваться с асм?
733259
Не по теме, но не удержался biggrin.gif
Код
register uint8_t count asm("r2"),
                 tsreg asm("r3");

SIGNAL (SIG_INTERRUPT0) __attribute__((naked));
SIGNAL (SIG_INTERRUPT0){
  tsreg = SREG;          // 1 такт
  count++;               // 1 такт
  SREG = tsreg;          // 1 такт
  asm volatile("reti");  // 4 такта
}
Обработчик на gcc, для подсчета импульсов, например. count потом обрабатываем в основном цикле. И правда - зачем заморачиваться с ассемблером?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.