LINUX.ORG.RU

Таймеры AVR

 


0

1

Доброго всем времени суток. Понадобилось собрать таймер. Да еще и такой, чтобы микросекунды считал. Собиралось это все на плате с atmega32u4 (клон arduino). Поставил резонатор на 16 МГц. Младший фьюз-бит прошит значением 0xFF. По идее таймер должен работать с частотой 16 Мгц. Таймер работает в режиме СТС с делителем равным единице. По подсчетам получается, что период у таймера 62.5 нс (1 / 16000000). В байте сравнения стоит значение 0x0F (в OCR0A). Прерывание по совпадению разрешено. В прерывании происходит декремент переменной. По идее, он должен срабатывать каждую микросекунду (62.5 * 16 = 1000 нс = 1 мкс). А вот фиг там. Ведет он себя вообще странно. Выставляю, чтобы отсчитал секунду, а он примерно восемь считает. Инициализировал OCR0A значением 0х00 — тоже примерно восемь секунд (измерить вообще нечем). Задал 0хFF — около 16 секунд. Где мой промах и чего я не учел? Питается плата от USB. Заранее спасибо за помощь.

код что ли покажи, который это всё настраивает

Harald ★★★★★
()

Давай сюда полные значения всех остальных регистров, имеющих отношение к этому таймеру (OCR0A, TCCR0A, TCCR0B, OCR0B, TIMSK0).

ddos3
()

у тебя мк с ардуиновским бутлоадером?

Deleted
()
Последнее исправление: medossa (всего исправлений: 1)

Прескалер выставил? Инициализацию таймера показывай

minakov ★★★★★
()

Может прямо таймером и считать микросекунды? Зачем программно в прерывании это делать?

Puzan ★★★★★
()
Ответ на: комментарий от Puzan

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

А причин выставить прерывание таймера на одну микросекунду и считать время программно может быть множество. Первое, что приходит в голову: необходимость одновременно считать несколько интервалов (т.е. событие А происходит раз в 10 uс,событие Б раз в 25 uс, событие В раз в 15 uс). Такое на хардварном таймере сделать не получится.

ddos3
()
Ответ на: комментарий от Puzan

ПыСы: Понятно, что я понятия не имею, какая на самом деле задача стоит перед ТСом, но я предполагаю, что раз он так делает, значит ему так нужно. В конце концов, он просил помочь не с дизайном его фирмваря, а с настройкой таймера, как бы он его не использовал.

ddos3
()
Ответ на: комментарий от ddos3

Я не поленился заглянуть с даташит и посмотреть количество тактов, нужное для обработки прерывания. 5 тактов нужно для перехода на вектор, 3 такта на jump в обработчик, 5 тактов на выход из обработчика. Это минимум 13 тактов. Плюс инкремент, плюс ожидание прерваной многотактовой команды или выход из спячки 5 тактов (если такое имеется).

Вопрос к ТС: уверен, что за 16 тактов обработчик успеет вернуть управление?

PS: чтение даташита заняло 5 минут.

Puzan ★★★★★
()
Последнее исправление: Puzan (всего исправлений: 1)
Ответ на: комментарий от Puzan

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

ddos3
()

Прошу извинения за то, что не отвечал. Спасибо всем за ответы. Задача стоит следующая: отсчет временных интервалов от единиц микросекунд до десятков секунд. Поэтому пытался сделать через прерывания. Даташит уже тоже внимательно перечитал и понял, что прерывание не успевает вернуть управление, так как в нем после декремента идет проверка условия и выполнение действия. Минимум, при котором обработчик работает корректно равен трем микросекундам (если брать целое число), а это 48 тактов. Не очень хорошо. И видимо ничего уже не придумать. Ладно, попробую на ARMе сделать. Еще раз всем спасибо.

baldman88
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.