9zip.ru Инструкции Точное таймерное прерывание
Когда таймер переполняется, процессор не сразу уходит в обработку прерывания. Сначала он должен завершить текущую команду. В AVR на это уходит до трех тактов в зависимости от текущей команды и момента возникновения прерывания. Мне видится три пути обхода этой проблемы:
Тривиальный способ, который подходит только для очень простых задач - расчитать всю программу по тактам. Тогда прерывание вообще не нужно.
Более "правильный" - загнать процессор в SLEEP. Если после этого возникнет прерывание от таймера, процессор сразу же начнет его выполнять. Проблема в том, чтобы гарантированно уходить в SLEEP _перед_ приходом прерывания. Этот способ удобно использовать, когда "фоновую" задачу можно порезать на заведомо быстрые кусочки, или "фоновая" задача сама привязана к таймеру.
Ну и наконец есть способ прочитать значение таймера внутри процедуры обработки, определить сколько времени прошло с момента переполнения и скомпенсировать ошибку. Это наиболее удобный способ, так как он позволяет не курочить ВСЮ программу, чтобы привязать ее к таймеру.
В результате экспериментов родилась последовательность команд, приведенная чуть ниже.
Обратите внимание на использование команд "SBRC" и "SBRS". Какую из них когда использовать зависит от места расположения этих команд в обработчике прерывания. Так что в вашем проекте возможно понадобится другая комбинация команд "SBRC" и "SBRS".
Еще одно замечание. Этот кусок изменяет регистры "R16" и "R0" (командой "LPM"). Так что, если они используются в программе, их придется сохранить.
; Корректируем время: ; такты
in r16,TCNT0 ; 1 Читаем Таймер0
sbrc r16,1 ; 1/2 Смотрим бит 1 - 2 или 4 такта
lpm ; 3
sbrs r16,0 ; 1/2 Смотрим бит 0 - 2 или 3 такта
rjmp _next ; 2
_next: ; Здесь в фиксированное время
; относительно момента переполния
Целиком пример можно скачать в виде архива: timer_int.zip Он написан для AT90S2313 и компилировался в AVR-Studio. Эта тестовая программка выдает на ноге D.0 импульс длиной в 10 тактов с периодом 100 тактов. Ради интереса можно посмотреть на лог порта, который выдал симулятор AVR-Studio:
; Такты:Порт
000000000:00
000000090:01
000000100:00
000000190:01
000000200:00
000000290:01
000000300:00
000000390:01
000000400:00
И еще одно замечание: Фоновая задача может быть какой угодно сложной и написанной на чем угодно. Однако любое другое прерывание (или команда "STI") могут заблокировать ваш обработчик.
9 нравится?
8 01.02.2015 ©
9zip.ru Авторские права охраняет Роскомнадзор
| Понравилась статья? Винни Пух говорит: поделись с друзьями! |
|
, Электродвигатель питается от сети переменного тока напряжением 220 В частотой 50 Гц. Под крышкой центрифуги установлен выключатель, блокирующий включение двигателя при открытой крышке. Установкой требуемой выдержки времени подготавливают цепи включения реле и нагревателя.