Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странно работает прерывание при совпадении таймера!
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
_Олег_
Всем привет!
Ситуация такая: МК должен прибавлять фиксированную задержку к импульсу, 8 - аппаратных и 8 - программных. Почему-то получаются 3 вида задержки 1 нормальная, 2 - нормальная минус дельта t, 3 - 0-я + та де дельта t, t меньше самой задержки. Ни как не могу понять почему!

Спасибо, если поможете!
GDI
Ниччо не понятно , ни в ваших словах, ни в ващем коде smile.gif
Вы опишите, что у вас за устройство, что вы ожидаете увидеть и что вы реально видите.
Но чудес то не бывает, если у вас плавает задержка, то где то , наверное, происходит наложение прерываний, непример, у вас произошло внешнее прерывание, и вы вошли в обработчик прерывания и в момент выполнения предыдущего обработчика у вас должно произойти прерывание от вашего таймера, но обработчик прерывания таймера вызовется только после окончания обработчика внешнего прерывания + 1 команда из основного цикла. Это во-первых.

Затем, во-вторых, вместо
Код
if (i == 16)
я бы написал
Код
if (i >= 16)
.
_Олег_
можете посмотреть это, что бы понять принцип, но там не видно нестабильности задержки.
Да, нужен proteus
GDI
Протеуса нету, описывайте словами. Хорошо заданный вопрос содержит в себе половину ответа, может и сами разберетесь когда по полочкам все разложите.
Попробуйте вложенные прерывания разрешить, может поможет хотя бы понять место, в котором проблема.
_Олег_
Цитата(GDI @ Nov 17 2008, 15:52) *
Протеуса нету, описывайте словами. Хорошо заданный вопрос содержит в себе половину ответа, может и сами разберетесь когда по полочкам все разложите.
Попробуйте вложенные прерывания разрешить, может поможет хотя бы понять место, в котором проблема.


да, я сейчас посмотрел входной сигнал 3,3 В может из-за этого неправильно срабатывает прерывание на INT0 Mode: Any change, а входной импульс 1Гц, скважность 0,5. Попробую найти с амплитудой 5 В.
_Олег_
Нет, проблема не в этом. Меня еще смущает то что иногда, TIM0_COMPA сразу же срабатывает, как буд-то счетчик таймера не обнулился.Период импульса всего 1 с, скважность 0,5
_Олег_
Спасибо за ответы и просмотры. Решение найдено, пока полет нормальный smile.gif
VladimirYU
Цитата(_Олег_ @ Nov 18 2008, 08:35) *
Спасибо за ответы и просмотры. Решение найдено, пока полет нормальный smile.gif

Все таки поделитесь с народом, в чем была проблема и как разрешилась. Получется, что топик затеяли и все?
_Олег_
Цитата(VladimirYU @ Nov 18 2008, 09:14) *
Все таки поделитесь с народом, в чем была проблема и как разрешилась. Получется, что топик затеяли и все?



Да все оказалось просто - нужно было останавливать таймер после прерывания совпадения, т.е.
Код
// Timer 0 output compare A interrupt service routine*****************************
interrupt [TIM0_COMPA] void __timer0_compa_isr(void)
{
M_PPS = PPS; //устанавлиаем программный pps

TCCR0B = 0; //останавливаем таймер0
} //***********************************************************************


Да, еще хочу оптимизировать, включить режим Mode: CTC top=OCR0A что бы счетчик TCNT0 сам обнулялся, тогда, наверно то же надо будет таймер останавливать.
_Олег_
Еще раз всем привет!

Хочу спросить у экспертов: вот отладил программу, но ни как не могу избавиться от неточности таймера, она конечно маленькая но плавающая +- 140 нс получилась.
Работает так: приходит фронт импульса, запускается таймер и отсчитывает 4 мкс, потом выставляется этот же фронт на выходе. Так вот , таймер плавает +- 140 нс. Посмотрите пожалуйста код, возможно от этого избавиться?

Спасибо.

вот
=GM=
Цитата(_Олег_ @ Nov 21 2008, 13:45) *
Хочу спросить у экспертов: никак не могу избавиться от неточности таймера, она конечно маленькая но плавающая +- 140 нс получилась

Это как раз 0, 1 или 2 такта вашего проца. Прерывание ждёт завершения очередной команды, отсюда получается такая неравномерность, так называемый джиттер прерывания. Избежать до конца не удастся, но можно сгладить, например, непосредственно перед прерыванием ползёте по цепочке нопов (однотактных команд в общем случае), задержка будет одинаковая.
aesok
Цитата(=GM= @ Nov 21 2008, 19:21) *
Это как раз 0, 1 или 2 такта вашего проца. Прерывание ждёт завершения очередной команды, отсюда получается такая неравномерность. Избежать можно, не так сложно, как нудно, если знать, какая команда выполнялась до входа в прерывание. Залезаете в стек, смотрите адрес возврата, определяете тип команды, корректируете данные для таймера соответствующе.


А как вычислить коррекцию, если запрос на прерывание таймера, пришол во время обработки другого прерывания?

Анатолий.
=GM=
Цитата(aesok @ Nov 21 2008, 16:31) *
А как вычислить коррекцию, если запрос на прерывание таймера, пришол во время обработки другого прерывания?

Я текст предыдущего поста поправил, извините, подумал, что не всегда такое возможно. Можно использовать ICR, затем смотреть на захваченное время, тогда джиттер уменьшится до полтакта в среднем, т.е. 34 нс. Не так плохо, думаю.
_Олег_
Цитата(=GM= @ Nov 21 2008, 19:21) *
Это как раз 0, 1 или 2 такта вашего проца. Прерывание ждёт завершения очередной команды, отсюда получается такая неравномерность, так называемый джиттер прерывания. Избежать до конца не удастся, но можно сгладить, например, непосредственно перед прерыванием ползёте по цепочке нопов (однотактных команд в общем случае), задержка будет одинаковая.


Спасибо, буду пробовать, значит все команды в основном цикле нужно сделать однотактными.

Вот попробовал только однотактные команды, все равно джиттер 2 такта.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.