Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Точное измерение длительности импульса таймером
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
MosVit
Сканирую вход микроконтролера (ATTiny2313) для измерения длительности импульса (переход от лог 1 к лог 0) 16 разрядным таймером (TIMER1).

Код на С (IAR WB)

while (PINB &= (1 << PB2));
TCCR1B = 0x00; // Stop timer

Дает ошибку в 5 МЦ (машинных циклов)
Пример: Разница между измеряными числами кратна 5
06564
06249
06529
06724
06484
06519

асемблерная вставка:
asm("nop");
asm("loop: sbic $16, 2");
asm("rjmp loop");
TCCR1B = 0x00; // Stop timer

Ошибка - 3 МЦ

По даташиту это вроде бы как предел точности, из-за того что команда "sbic" выполняется 3 МЦ при выполнении условия и 1 МЦ в противном случае.

Пример: Разница между измеряными числами кратна 3
00425
00425
00425
00434
00425
00428

Может кто подскажет как можно уменьшить ошибку до 1 МЦ?
Огурцов
Цитата(MosVit @ Nov 12 2008, 20:05) *
Может кто подскажет как можно уменьшить ошибку до 1 МЦ?

Разверните цикл - ошибка будет или 1 или 0 МЦ, т.е. то, что надо.
smac
Цитата(MosVit @ Nov 12 2008, 23:05) *
...
Может кто подскажет как можно уменьшить ошибку до 1 МЦ?

Мне приходит в голову использование устройства захвата таймера, но для этого нужно выполнить как минимум 1 "аппаратное условие" - завести сигнал на пин icp (вроде 1).
Далее мне видится такое решение (опишу псевдоалгоритмом ибо в С не силен)

Код
запретить прерывания при переполнении таймера;
настроить тактирование таймера (без предделителя);
настроить устройство захвата по фронту импульса;
flag=0
izmerenie_provedeno=0
ovfl=0

main ()
{
     if (izmerenie_provedeno)
     {
         T_imp=t_end + ovfl*0x10000 - t_start;
         izmerenie_provedeno=0;
         ovfl=0;
     }


Прерывание от устройства захвата
{
               if (flag)
           {
                         t_end=icr1w; // вожможно не так называется в общем я имею ввиду пару ICR1H:ICR1L
                         flag=0;
                 izmerenie_provedeno=1;
                 настроить устройство захвата по фронту импульса;
                                 запретить прерывания по переполнению таймера;
           }
                  else
           {
                 t_start=icr1w;
                 flag=1;
                 настроить устройство захвата по спаду импульса;
                                разрешить прерывания по переполнению таймера;
          }
}

прерывание по переполнению таймера
{
            ovfl++;
}

конечно это не отлаженый код, поэтому дополню описанием на словах:
0)нужно сначала настроить устройство захвата по фронту имульса (естественно если мы измеряем имульс начиная от перехода из 0 в 1 и заканчивая переходом из 1 в 0) и запустить таймер, не разрешая при этом прерывания по переполнению;
1)по прерыванию от устройства захвата в регистре icr1 появится текущее значение таймера ("тайм стамп") соответствующее началу (фронту) импульса, в это время мы перенастраиваем устройство сравнения на спад импульса, разрешаем прерывания по переполнению таймера и запоминаем icr1 в t_start (ветка else);
2)по след прерыванию от устройства сравнения в регистре icr1 появится новое значение соответствующее концу (спаду) импульса, в это время мы перенастраиваем устройство на фронт импульса, запрещаем прерывания по переполнению таймера и запоминаем icr1 в t_end (ветка if(fag));
3) по окончанию измерения вычисляем длительность импульса в тиках таймера1 (при делителе 1 как раз будет равна МЦ).

З. Ы. Прошу прощения за кривость оформления и изложения, также надо подумать о граничном условии (если захват и переполнение произойдут одновременно, то что будет?)
З. З. Ы. По моему на этом форуме пользователем =GM= (прошу извинить если неправильно привел ник) предлагалось использование устройства захвата при измерении частоты. Нужно поискать по форуму - тема заметная была, т. е. я никаких претензий на оригинальность не имею.
Artem_Petrik
В tiny2313 на таймере 1 есть вход захвата (input capture). C его помощью можно мерять с точностью до такта. Он (вход захвата) вообщем-то для этого и предназначен.

Упс, опоздал smile.gif.
VAHOO
Цитата(Artem_Petrik @ Nov 13 2008, 01:27) *
В tiny2313 на таймере 1 есть вход захвата (input capture). C его помощью можно мерять с точностью до такта. Он (вход захвата) вообщем-то для этого и предназначен.

Упс, опоздал smile.gif.


скажите пожалуйста а как правилно настроить?
Artem_Petrik
Цитата(VAHOO @ Nov 13 2008, 13:42) *
скажите пожалуйста а как правилно настроить?

Сам таймер настроить можно в принципе как угодно, но если он используется только для захвата - то пусть себе считает от 0 до 0xFFFF без всяких прерываний.
В TCCR1B бит ICES1 отвечает за то, какой именно фронт будет захватываться. Как только таймер засечет этот самый фронт на ICP1 он скопирует содержимое TCCR в ICR. Так у нас появилась временнАя метка. По прерыванию ICIE мы ее считываем. Если мы меряем период, т.е. расстояние, например, между передними фронтами, то мы ждем следующее прерывание от захвата, вычитаем из новой метки предыдущую (по модулю 65536, т.е. 0x0001 - 0xFFFF = 2) и получаем точную длительность периода. Если нужно мерять длительность "еденички", то в каждом прерывании нужно менять значение ICES1 на противоположное, чтоб ловить и передние фронты и задние(срезы).
А вообще, читайте datasheet, там много всего интересного smile.gif.
MosVit
Спасибо за ответы:
Возможность использования блока захвата расматривал, но сбило с толку информация о том что величина задержки между изминением состояния входа и копированием значения таймера проходит 2.5-3.5 МЦ, а при включении схемы подавления помех еще + 4 МЦ.
Если эта задержка проходит после того как фронт зафиксирован, то тут проблем нет, но если он фиксирует все это время фронт, то собственно ошибка измирения будет такой же как и без использования захвата. Вобщем, буду проверять.

Цитата(smac @ Nov 13 2008, 01:22) *
З. З. Ы. По моему на этом форуме пользователем =GM= (прошу извинить если неправильно привел ник) предлагалось использование устройства захвата при измерении частоты. Нужно поискать по форуму - тема заметная была, т. е. я никаких претензий на оригинальность не имею.


Использование блока захвата для датчиков с сигналом ШИМ:
AVR135: Using Timer Capture to Measure PWM Duty Cycle
http://www.atmel.com/dyn/resources/prod_do...nts/doc8014.pdf
Artem_Petrik
Цитата(MosVit @ Nov 13 2008, 22:27) *
Возможность использования блока захвата расматривал, но сбило с толку информация о том что величина задержки между изминением состояния входа и копированием значения таймера проходит 2.5-3.5 МЦ, а при включении схемы подавления помех еще + 4 МЦ.
Если эта задержка проходит после того как фронт зафиксирован, то тут проблем нет, но если он фиксирует все это время фронт, то собственно ошибка измирения будет такой же как и без использования захвата. Вобщем, буду проверять.

Эта задержка на точность измерения не влияет потому что все фронта задерживаются одинаково (ну ч точностью до одного такта), и в результате расстояние между ними не меняется.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.