Форум программистов, компьютерный форум, киберфорум
Цифровая обработка сигналов
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/47: Рейтинг темы: голосов - 47, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 05.02.2010
Сообщений: 167
1

Timer 1. Прерывание по таймеру = +- 1шаг. Как избавиться?

21.02.2010, 02:39. Показов 8829. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть такая проблемка. При возникновении прерывания запись в порт возникает с разницей в +- 1-н машинный такт. Как сделать, чтоб небыло такого разброса? Или хотябы в одну сторону постоянно было.
частота проца - 4 MHz
время мигания светодиода - 1 секунда
999936.00 us
999936.25
999936.00
999935.75
999936.00
999936.25
Получается как раз не одна секунда.
Проект в AVR Studyo прилагается)))
Формула для расчета времени срабатывания (тактов) TCNT1=0x10000L-(xtal/1024L/fmove);
fmove может быть разной.

[60.17 Кб]

0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.02.2010, 02:39
Ответы с готовыми решениями:

Прерывание по таймеру
Хочу я организовать регулярное действие в моей программе (каждые n секунд делать что-либо)....

Прерывание по таймеру
Добрый день! Написал код по которому мигает светодиод от таймера, так вот от таймера 1 он работает,...

Прерывание по таймеру
Здравствуйте! Возможно ли сделать в консольном приложении на Visual Studio так, чтобы во время...

Прерывание программы по таймеру
Как мне создать собственное исключение для прерывания функции, если она выполняется дольше 1...

STM32L прерывание по таймеру
Добрый день. Начал изучение STM32 на базе STM32T-Dyscovery. Как ИДЕ использую Ecplipse,...

8
0 / 0 / 0
Регистрация: 05.02.2010
Сообщений: 167
21.02.2010, 02:49 2
И еще как поменять частоту на которой симулируется в AVR Studyo? Там стоит 4 мегагерца, и надо свой проект на ету частоту стачить...???????
0
Shodow
21.02.2010, 03:14 3
Поменять частоту в AVR Studyo можно с помощью меню Debug->AVR Simulator Options.
Время различно так как в случае возникновения прерывания во время выполнения длинной команды (2-3 такта) контролер сначала закончит выполнение команды, а затем перейдёт к вектору прерывания.
0 / 0 / 0
Регистрация: 26.01.2010
Сообщений: 273
21.02.2010, 10:59 4
Короче нужно использовать прерывание по совпадиению. Так будет проще и нагляднее. Тогда в счетчик каждый цикл ничего писать не нужно будет.
Сайчас в счетчик каждый раз записывается заначение, и ошибка, с которой пришло прерывание, суммируется.
Кстати +/- тут невозможно. Возможно только в "плюс" 0-1-2 лишних такта.

Если критичны эти 1-2 такта (НЕ НАКАПЛИВАЕМОЙ ОШИБКИ) то можно подравнятьвот такой конструкцией:

Код
TIM0_OVF:
nop      ; сохраняем контекст программы
nop      ;
nop      ;

in   temp,tcnt0
subi temp,(7+n)   ; сдесь под n понимается число тактов,
; необходимое для сохранения контекста
brmi otygn1
otygn1:   dec  temp3
brmi otygn2
otygn2:   nop      ; эта операция будет выполняться через
nop      ; точное колличество циклов
nop      ;

reti
Она "съест" 7 тактов, но если это важно, то почему бы и нет.
0
0 / 0 / 0
Регистрация: 05.02.2010
Сообщений: 167
21.02.2010, 20:23 5
Спасибо Shodow. Наконец-то теперь вкурил как менять частоту кварца. )))
Спасибо и SOWushko. С попами можно конечно загасить лишние такты, но невсегда. При одном кварце и одном числе по которому идет прерывание по совпадинию - будет точно выдержанно время. А если мы поменяем число - до которого надо считать, то опять будут ходить последние цифры))) +0, 1, 2 такта.
Я вот дума точно не будет никогда, если будем менять до скольки считать . (Посимулировал в AVRStudyo схемку часов по совпаденю http://habrahabr.ru/btogs/gadgets/38443/). Спасибки))

Мне надо ето для управлением драйвером шагового двигателя. Точнее нужно дергать ножкой МК. Наверное последние знаки не будут влиять на работу))
0
0 / 0 / 0
Регистрация: 26.01.2010
Сообщений: 273
21.02.2010, 23:04 6
Цитата Сообщение от rot20
Спасибо и SOWushko. С попами можно конечно загасить лишние такты, но невсегда.
Под столом от этого комента. =))

Вы видимо имели в виду команду "nop"? и видимо глянув на код решили что я предлагаю гасить "лишнее время" простоем процессора? =)))

Так вот, обьясняю еще раз. Очень подробно.
Вход в прерывание происходит при трех обязательных условиях:
1) Прерывание разрешено
2) Произошло событие (в нашем случае это события таймера-счетчика "переполнение", а если интервылы не меняются - лучше "совпадение")
3) процессор не выполняет длинную операцию.

И если с первыми двумя особых проблем нет, то третье - это проблема. (Тут нужно сказать, что в случае зажигания светодиодов - это не проблема, а в случае когда важно соблюдать точность в десятые доли микросекунды - это важно.)

Почему происходит эта задержка. Да потому что у АВР есть длинные команды, которые выполняются не за 1, а за 2-3 такта. Так вот если событие ("преполнение" или др.) произошло после первого такта длинной комманды, то задержка будет 1-2 такта, для 2-3 тактовых операций соответственно.

В вашем варианте программы, вы входите в обработчик прерывания и меняете значение счетчика. Если вход в прерывание всегда будет во время выполнения коротких операций - то все хорошо. Интервалы ровные.

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

Если мы используем прерывание по совпадению, то выполнение обработчика может запаздать на 1-2 такта. Но дрейфа этого не будет!

Тот листинг который привел я выравнивает задержки, и делает абсолютно точными (с точностью до такта) интервалы межде началом выполнения кода с меткой "otygn2" после него можно изменять значение счетчика на требуемое и использовать событие "переполнение". Но делать так при одинаковых интервалах - глупо.
Команды nop ножно заменить кодом, предварительно прочитав комментарий написаный после этих самых нопов =))

Желаю удачи, и никогда не делать черезчур поспешных выводов.
0
0 / 0 / 0
Регистрация: 05.02.2010
Сообщений: 167
23.02.2010, 00:43 7
Спасибки))) За разъяснения))!! НЕ буду делать поспешных выводов)
Я так понял от TIM0_OVF: до reti. ето наше прерывание
А in temp,tcnt0 -ето запись числа из счетчика в temp.
потом вычитаем етой коммандой subi temp,(7+n) - из темт число 7+n, Если результат отрицательный, то переходим по метке brmi otygn1.
Метка otygn1: dec temp3 - вычитаем из temp3 единичку. ЧТО за темп3? Чему он равен? НАверное нулю?!
И опять если результат отрицательный, то переходим на brmi otygn2.
А где заносить новое число, до которого надо считать таймеру? Наверное после метки otygn2?
Счетчик считать будет постоянно до одной величины тактов, но в целой программе - можно менять, и придется менять етот счетчик.

Люблю людей с чувством юмора!!!!
Если так, то вот еще посмейся немножко до кучи)))))) Играли в бильярд трое или четверо парней, и девчонка. Ну вот когда били из лузы шар. ДЕвушка сказала, что ето выстрел из дырки)))) Смеялись тоже долго))))))))))))))
0
0 / 0 / 0
Регистрация: 26.01.2010
Сообщений: 273
23.02.2010, 21:45 8
Temp3 - это опечатка. Конструкция эта "выравнивает" время которое потребовалось на то чтобы зайти в счетчик. После того как спроисходит событие которое вызвало прерывание счетчик сбрасывается. То есть вариант когда у нас прерывание по совпадению, но счетчик не сбрасывается, нужно это учесть при сравнении temp с числом. Если вход в обработчик не "запаздывает", то конструкция выполняется за 7 тактов, если запаздывает на 1 - то за 6 тактов, и соответственно на 2 - за 7 тактов.
0
0 / 0 / 1
Регистрация: 22.01.2010
Сообщений: 4,000
26.02.2010, 22:07 9
Есть один извратский метод. Подходит для поимки очень коротких выдержек.

точка ожидания условия:
NOP ; дальше полигон из NOP
NOP
NOP
NOP
NOP
NOP
...

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

Выход из прерывания делается тоже хитро - мы меняем адрес возврата на конец полигона (чтобы по нему не скакать) и делаем RETI

Еще можно помозговать и завернуть два условия. Одно срабатывает если есть событие, другое если нет. Т.е. как ни крути у нас в цикле ожидания будет один переход, что выровняет длину цикла ожидания и тоже даст четкое время срабатывания.
0
26.02.2010, 22:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.02.2010, 22:07
Помогаю со студенческими работами здесь

stm32f429 прерывание по таймеру
Всем привет. Не получается включить прерывание по таймеру, или диод не моргает - не знаю в чем...

Прерывание по таймеру на C++ в консоли
Подскажите пожалуйста,как в консольном приложении можно написать прерывание срабатывающее при...

Не отключается прерывание по таймеру
Приветствую всех! Обращаюсь к знатокам за помощью. Проблема такая. Не отключается прерывание по...

Не работает прерывание по таймеру в STM32f411RE
Пробую сделать прерывание по таймеру. Разрешил прерывания глобально, разрешил прерывание конкретно...

Прерывание по таймеру раз в пол-секунды
Использую CVAVR. Необходимо получить прерывание по таймеру 1 точно раз в пол-секунды. Стоящий у...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru