Портал для радиолюбителей и разработчиков электроники · с 2003 годаРеклама на сайте
Найти компонент, схему или даташит

Даташиты, справочник отечественных приборов, схемы с разбором и живой форум

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы

Обработка прерываний.

Непрочитано 08.07.2007, 18:21  
Tibo
Прохожий
 
Регистрация: 08.07.2007
Сообщений: 2
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Tibo на пути к лучшему
По умолчанию Обработка прерываний.

Я думаю на вопросы по прерываниям отвечали уже не раз, но я не смог найти на свой.
Пусть имеется следующая программа:
1)Функция Авария. При переходе к ней запускается бесконечный цикл в котором происходит сигнализация, а также сброс флагов прерывания, и остановка таймер-счетчика.
2)Функция обработки прерывания по переполнению таймер-счетчика, в которой вызывается функция Авария.
Вопрос первый.
Если я сбрасываю флаг прерывания при его выполнении. Прерывание будет считаться оконченым и не будет мешать обработке других прерываний? Корректно ли это?
Вопрос второй.
Как грамотно при выполнении прерывания после его окончания, вернуться не к месту, где была прервана оснавная программа, а перейти в желаемую точку. К примеру прерывание возникло в цикле, а после его выполнения необходимо из цикла выйти.
Как это ораганизовать на СИ для WINAVR?
Я понимаю что можно ввести в цикл дополнительное условие... Но если циклов много?
Возможно ли использовать метки или что-то подобное им?

Буду признателен за ответы.
Реклама:
Tibo вне форума  
Непрочитано 09.07.2007, 11:45  
nokazus
Вид на жительство
 
Регистрация: 05.09.2006
Сообщений: 359
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
nokazus на пути к лучшему
По умолчанию

Команда возврата из прерывания RETI восстанавливает указатель адреса из стека плюс сбрасывает служебные флаги контроллера прерываний. Для того чтобы вернуться из прерывания в другую точку программы (на определенную метку) нужно заменить адрес возврата в стеке на нужный. Для этого восстанавливаем из стека два байта, например выполняем два раза команду

POP R16
POP R16

Данные (адрес с которого вызвано прерывание) игнорируем. Теперь записываем в стек адрес возврата на метку и даем команду выхода из прерывания. Для этого выполняем команды

LDI R16,Low(Label)
PUSH R16
LDI R16,High(Label)
PUSH R16
RETI

Не помню какая очередность записи байтов в стек, сначала младший, потом старший (как написано здесь) или наоборот. Проверьте сами. Переложить на С думаю сможете.

Удачи.
nokazus вне форума  
Непрочитано 09.07.2007, 18:32  
double_dash
Прописка
 
Аватар для double_dash
 
Регистрация: 15.10.2006
Сообщений: 129
Сказал спасибо: 0
Сказали Спасибо 2 раз(а) в 1 сообщении
double_dash на пути к лучшему
По умолчанию Re: Обработка прерываний.

Сообщение от Tibo
Если я сбрасываю флаг прерывания при его выполнении. Прерывание будет считаться оконченым и не будет мешать обработке других прерываний? Корректно ли это?
Вполне. Только правильнее будет наверно сказать
что прерывание будет обработано до конца,
а при следующем обращении уже не вызовется
(думаю речь идет о бите разрешения прерывания?)

Сообщение от Tibo
Как грамотно при выполнении прерывания после его окончания, вернуться не к месту, где была прервана оснавная программа, а перейти в желаемую точку. К примеру прерывание возникло в цикле, а после его выполнения необходимо из цикла выйти.
Я понимаю что можно ввести в цикл дополнительное условие... Но если циклов много?
Возможно ли использовать метки или что-то подобное им?
Ну использовать какую либо глобальную переменную-флаг все равно придется.
А выходить из глубоких циклов
если все дело происходит в какой либо функции
можно при помощи return
Код:
int flag = 0;

func()
 {
  for(i=0; i‹n; i++)
   {
     ....
     for(j=0; j‹m; j++)
      {
       ....
       if(flag) return;
       }
     }   
  }
double_dash вне форума  
Непрочитано 09.07.2007, 19:13  
EVGENIY1962
Гражданин KAZUS.RUN
 
Регистрация: 27.07.2006
Сообщений: 658
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
EVGENIY1962 на пути к лучшему
По умолчанию

Если вам доступен стек,то можно выйти куда угодно,но лучше этого не делать.Любой просчет приведет к сбою программы.Вы не слишком усердствуете?Кроме того вам придется отслеживать глубину стека и решать куда нужно выйти.Кстати стек придется править.
EVGENIY1962 вне форума  
Непрочитано 09.07.2007, 21:57  
sanitar249
Почётный гражданин KAZUS.RUN
 
Аватар для sanitar249
 
Регистрация: 19.01.2007
Сообщений: 1,745
Сказал спасибо: 2
Сказали Спасибо 46 раз(а) в 35 сообщении(ях)
sanitar249 на пути к лучшему
По умолчанию

Вы затронули очень серьезный вопрос, с точки зрения программирования: "В фон-неймановской архитектуре единая область памяти используется, в том числе, и для реализации стека. При этом снижается производительность устройства, так как одновременный доступ к различным видам памяти невозможен. В частности, при выполнении команды вызова подпрограммы следующая команда выбирается после того, как в стек будет помещено содержимое программного счетчика.
В гарвардской архитектуре стековые операции производятся в специально выделенной для этой цели памяти. Это означает, что при выполнении программы вызова подпрограмм процессор с гарвардской архитектурой производит несколько действий одновременно.
Необходимо помнить, что МК обеих архитектур имеют ограниченную емкость памяти для хранения данных. Если в процессоре имеется отдельный стек и объем записанных в него данных превышает его емкость, то происходит циклическое изменение содержимого указателя стека, и он начинает ссылаться на ранее заполненную ячейку стека. Это означает, что после слишком большого количества вызовов подпрограмм в стеке окажется неправильный адрес возврата. Если МК использует общую область памяти для размещения данных и стека, то существует опасность, что при переполнении стека произойдет запись в область данных либо будет сделана попытка записи загружаемых в стек данных в область ОЗУ." Я полностью согласен с EVGENIY1962, что стек лучше "руками" не трогать. А для нормальной работы стека правильно расставить приоритеты прерываний, осуществить контроль заполнения стека и при угрозе переполнения отказывать в обработке малозначительным процессам(ставить в очередь, если возможно).
sanitar249 вне форума  
Непрочитано 10.07.2007, 07:31  
nokazus
Вид на жительство
 
Регистрация: 05.09.2006
Сообщений: 359
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
nokazus на пути к лучшему
По умолчанию

В программах на ассемблере состояние стека легко контролируется. И потом можно запоминать и состояние стека в переменной, а перед выходом восстанавливать указатель на адрес возврата. Я согласен, что это не совсем "правильно", но вполне возможно. "Правильней" создать переменную, в которую при обработке прерывания будет записываться признак или флаг, обзовите как угодно, а втеле программы эта переменная анализируется и происходит ветвление программы.
Но во-первых, обработчик прерываний вызывается из неопределенного места программы и возврат из прерывания произойдет в ту же неизвестную точку. Во-вторых обработка ветвлений занимает достаточно много времени и оно меняется от значения анализируемой переменной. А если человеку необходима немедленная реакцияна на событие?
Конечно все зависит от правильного (уже без кавычек) построения алгоритма программы. Выходить из прерывания описанным мной методом не рекомендуется при сложной программе. И не из-за стека, а из-за неопределенного состояния портов, переменных. Т.е. нужно уходить в процедуру реинициализации контроллера. Я думаю что в случае ухода на обработку критической ошибки, после которой следует процедура инициализации всего или рестарт программы это оправдано.
Я применял такой метод ветвления в теле прграммы (не при выходе из прерывания) с целью сократить время на обработку ветвлений при их большом количестве. К тому же, как я писал выше, это время не зависит от проверяемого значения. Строится таблица переходов в виде массива слов, где значение с индексом 0 является адресом на который нужно уходить если значение переменной равно 0 и т.д. Если кому интересно могу подробней описать.
Мой знакомый коллега использовал такой же метод и при выходе из прерывания. Все у него работает.
Не надо бояться, следует опасаться.
Конечно за стеком нужно следить, особенно при работе в Си.
Удачи.
nokazus вне форума  
Непрочитано 10.07.2007, 10:46  
bamu
Прохожий
 
Регистрация: 17.11.2006
Сообщений: 1
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
bamu на пути к лучшему
По умолчанию

Для обработки ошибок в WINAVR лучше использовать
функции setjmp и longjmp модуля ‹setjmp.h›,
пример использования приведен в
WinAVRdocavr-libcavr-libc-user-manual.
bamu вне форума  
Непрочитано 10.07.2007, 12:27  
EVGENIY1962
Гражданин KAZUS.RUN
 
Регистрация: 27.07.2006
Сообщений: 658
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
EVGENIY1962 на пути к лучшему
По умолчанию

Сообщение от bamu
Для обработки ошибок в WINAVR лучше использовать
функции setjmp и longjmp модуля ‹setjmp.h›,
пример использования приведен в
WinAVRdocavr-libcavr-libc-user-manual.
Согласен.GOTO проще и безопаснее CALL.Про авр не знаю но в мелких пиках до стека прото так не добраться.
EVGENIY1962 вне форума  
Непрочитано 10.07.2007, 12:33  
SasaVitebsk
Гражданин KAZUS.RUN
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию

В основном Вам ответили.
Про прерывания я соглашусь с double_dash. Это найболее коректный ответ на мой взгляд.

По выходу.
Действительно бывают такие ситуации (обычно аварийные) когда из любого места программы (в том числе из прерывания) лучше выйти в конкретное место. Обработчика аварии. Во всяком случае я такое делал. Как и другие я выполнял это на ассемблере. В добавление тех способов что вам перечислии (1. подсовывание адреса в стэк и возврат, 2. сброс стека и прямой переход) я добавлю ещё один. Инициализация стека и прямой переход. В принципе 1 и 3 способ можно реализовать на IAR C. С GCC к сожелению не знаком. Но я рекомендовал бы сделать следующее (если другим способом - ну никак)

По аварии выходить на JMP 0. А при инициализации проверять как мы попали в место старта. В этом случае у вас гарантированно будет всё нормально со всеми вашими переменными и стеками. (в смысле они инициализируются) Теже которые нельзя трогать необходимо разместить в сегменте неинициализированных.
Короче совтовый вариант WDT.
SasaVitebsk вне форума  
Непрочитано 10.07.2007, 13:18  
nokazus
Вид на жительство
 
Регистрация: 05.09.2006
Сообщений: 359
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
nokazus на пути к лучшему
По умолчанию

Сообщение от SasaVitebsk
По аварии выходить на JMP 0. А при инициализации проверять как мы попали в место старта. В этом случае у вас гарантированно будет всё нормально со всеми вашими переменными и стеками. (в смысле они инициализируются) Теже которые нельзя трогать необходимо разместить в сегменте неинициализированных.
Короче совтовый вариант WDT.
Вариант с аппаратным WDT или вызовом его срабатывания из программы - "5". При этом инициализируются все регистры микроконтроллера. Вариант же GOTO из прерывания на точку старта, даже если Вы всю периферию и переменные проинициализировали, в т.ч. указатель стека, может привести к неприятным последствиям. Пример, в MSC-51 имеется служебный недоступный регистр обработчика прерываний, который устанавливается вначале обработки прерывания и сбрасывается только командой RETI (этим она и отличается от команды RET) или системой сброса. Пока триггер не сбросится, обработки прерываний не будет. К сожалению про этот триггер мало написано в даташите. Не уверен, есть-ли такое в AVR, скорее нет. Но я бы не рискнул выходить из прерывания без RETI, или проверил бы.
Удачи.
nokazus вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Симуляция прерываний в EWAVR woroba Микроконтроллеры, АЦП, память и т.д 5 13.02.2009 08:39
Обработка нескольких прерываний AVR (вопрос) festoon Микроконтроллеры, АЦП, память и т.д 27 17.11.2008 18:02
обработка клавиатуры? maxNTF Микроконтроллеры, АЦП, память и т.д 18 26.10.2007 23:44
нид хелп. Обработка сигнала с датчика freele Автоматика и аппаратура связи 5 14.07.2007 16:56
Использование прерываний в ATMega8535 igor727 Микроконтроллеры, АЦП, память и т.д 2 28.04.2007 15:50


Часовой пояс GMT +4, время: 10:26.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.