Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос о прерываниях и задержках
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
M_Stamlo
Здравствуйте. Сразу отмечу, что я новичок в программировании для МК, поэтому просьба объяснять попроще sm.gif
Пишу программу в IAR Embedded Workbench for Atmel AVR 5.51.
Суть вопроса:
Есть основная часть программы, в которой происходит циклический опрос нескольких датчиков с проверкой условий.
Также описаны несколько обработчиков внешних прерываний.
В одном из обработчиков есть необходимость введения определенной временной задержки:
1) Отправляем сигнал, запускающий электродвигатель(ЭД).
2) Ждем 1с.
3) Проверяем, пришел ли сигнал о том, что ЭД вышел на номинальный режим работы. В зависимости от результата - соответствующая реакция.
Могу ли я реализовать(или использовать уже готовую функцию) данную задержку таким образом, чтобы при появлении более приоритетного прерывания, его обработчик запускался сразу, а не ждал пока завершится задержка?
Палыч
Цитата(M_Stamlo @ Dec 16 2010, 19:13) *
Могу ли я реализовать(или использовать уже готовую функцию) данную задержку таким образом, чтобы при появлении более приоритетного прерывания, его обработчик запускался сразу, а не ждал пока завершится задержка?

Можно в обработчике прерывания выставить разрешение прерываний. В этом случае любое прерывание не будет ждать завершения текущего прерывания, но тогда будет довольно затруднительно выдержать точное время задержки (она увеличится на время работы других обработчиков прерываний). Если это - не столь важно, то можно так и сделать, но перед разрешением прерываний желательно проделать некие действия, недопускающие повторного прерывания по событию в котором это все реализовано... Т.е. имеете шанс получить от такого построения вычислительного процесса маленькую кучку сюрпризов. Наверное, было бы лучше вместо задержки в прерывании завести на секунду таймер и выйти из прерывания, а уж по прерыванию от таймера доделать всё то, что собирались сделать по п.3 - проверить выход на номинальный режим и соответствующая реакция. Но, и такой подход - не очень то и хорош: обычно, желательно в обработчике прерываний выполнять минимум действий (например, выставить флаг события и - всё), а в основной программе (обычно она - бесконечный цикл) проверять условия наступления тех или иных условий и выполнять соответствующие действия...
rezident
Лучше сделать в прерывании единый таймер времени, значение которого сравнивать в каждом из КА (конечный автомат), управляющим своим процессом. У вас как минимум два КА: один опрашивает датчики, второй управляет ЭД. Зачем КА с опросом датчиков ждать окончания задержки в КА управления ЭД? Обе функции КА вызываются по-очереди. Если время для изменения состояния КА не вышло, то управление просто передается следующему КА. Время измеряется путем сравнения (вычитания) беззнаковых чисел внутри самой функции КА. Из текущего значения переменной таймера времени вычитается значение временной "засечки" данного КА и сравнивается с уставкой, заданной для текущего состояния КА. Если разность больше или равна уставки, то КА переходит в другое свое состояние.
Два важных момента.
1) переменная таймера времени должна иметь такую разрядность, чтобы обеспечить отсчет самого длительного интервала, который требуется в работе КА, без переполнения переменной.
2) при разрядности переменной таймера времени больше, чем нативная разрядность архитектуры МК, нужно обеспечивать атомарность доступа к этой переменной, учитывая тот факт, что переменная изменяется в прерывании.
Типично таймер времени считает в единицах миллисекунд, если не требуется более высокая точность. Соответственно в прерывании переменная увеличивается на количество мс кратное периоду вызова этого прерывания.
M_Stamlo
Палыч, спасибо за ответ.
Цитата(Палыч @ Dec 16 2010, 20:39) *
обычно, желательно в обработчике прерываний выполнять минимум действий (например, выставить флаг события и - всё), а в основной программе (обычно она - бесконечный цикл) проверять условия наступления тех или иных условий и выполнять соответствующие действия...

Тут такой ньюанс есть... Данная программа - промежуточная. После ее написания, мне нужно будет "перенести" ее под ОС реального времени(scmRTOS). Может моя логика и ошибочная, но я уже сейчас пытаюсь сделать так, чтобы реакция на событие, вызывающее внешнее прерывание, была определенной по времени(для наиболее приоритетного события). Если обработчик прерывания только выставит флаг, то реакция на событие последует тогда, когда в основной программе дойдет очередь до проверки этого флага. А это может занять слишком много времени и реакция будет несвоевременной.

Цитата
Наверное, было бы лучше вместо задержки в прерывании завести на секунду таймер и выйти из прерывания, а уж по прерыванию от таймера доделать всё то, что собирались сделать по п.3 - проверить выход на номинальный режим и соответствующая реакция.

Вот эта идея мне нравится, но в условиях моей задачи, в худшем случае, может возникнуть такая ситуация:
В течении секунды, но асинхронно, всем 4-рем однотипным обработчикам прерываний(но разного приоритета) понадобится таймер. Как-нибудь можно разрешить эту ситуацию? Мой МК - AVR ATmega 128.




rezident, интересный метод, правда у меня нет ощущения, что я его правильно понял. Попробую разобраться, когда будет время. Спасибо.
Палыч
Цитата(M_Stamlo @ Dec 16 2010, 20:40) *
Как-нибудь можно разрешить эту ситуацию?
См. выше ответ rezidentа. Использование одного аппаратного таймера для отсчета разных интервалов времени или одинаковых по длительности, но с разным временем начала не раз обсуждалось на этом форуме. Поищите.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.