Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Таймер1
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Kesha123
Кто-нибудь подскажет, как запустить режим по совпадению таймера1? А, именно, имеется мега32 16МГц, нужно вызывать прерывание каждую миллисекунду. Заранее благодарен!
ALexx
Цитата(Kesha123 @ Jul 3 2006, 08:54) *
Кто-нибудь подскажет, как запустить режим по совпадению таймера1? А, именно, имеется мега32 16МГц, нужно вызывать прерывание каждую миллисекунду. Заранее благодарен!


В приложении - Хидер и Сишник для обслуживания таймеров

В процедуре инициализации ставите слкдующие строки:

//Запуск системного таймера
Timer1_SetMode(DISABLE_OC, DISABLE_OC, T1_NORMAL);
Timer1_SetMatchValue(CHANNEL_A,2000); // 1000Hz(T=1ms) on f=CLK/8 (CLK=16MHz)
Tim_EnableInt(OCIE1A);
Timer1_Start(T1_CLK_8);


Процедура обработки прерывания:

//*******************************************************************************
// Timer 1 output compare interrupt service routine
//*******************************************************************************
interrupt [TIM1_COMPA]void Tim1_compA_ISR(void){
TCNT1=0;

// Ваш код.....
}
Harvester
CS12...CS10 = 010 (регистр TCCR1B) - предделитель clk/8
значение для сравнения по формуле K = Tзад/(n/Fclk) = Fclk*Tзад/n
n - коэфф предделителя
Tзад - требуемый период
Fclk - тактовая частота
K = 16E6*1E-3/8 = 2000

1. биты WGM13...WGM10 = 0100 (WGM11, 10 - TCCR1A; WGM13, 12 - TCCR1B) - режим CTC
OCR1A = 2000 - с чем сравнивать
OCIE1A = 1 (регистр TIMSK) - прерывание
или
2. WGM13...WGM10 = 1100 - режим CTC
OCR1A = 2000 - с чем сравнивать
TICIE1 = 1 (регистр TIMSK) - прерывание
Kesha123
Цитата(ALexx @ Jul 3 2006, 11:24) *
Цитата(Kesha123 @ Jul 3 2006, 08:54) *

Кто-нибудь подскажет, как запустить режим по совпадению таймера1? А, именно, имеется мега32 16МГц, нужно вызывать прерывание каждую миллисекунду. Заранее благодарен!


В приложении - Хидер и Сишник для обслуживания таймеров

В процедуре инициализации ставите слкдующие строки:

//Запуск системного таймера
Timer1_SetMode(DISABLE_OC, DISABLE_OC, T1_NORMAL);
Timer1_SetMatchValue(CHANNEL_A,2000); // 1000Hz(T=1ms) on f=CLK/8 (CLK=16MHz)
Tim_EnableInt(OCIE1A);
Timer1_Start(T1_CLK_8);


Процедура обработки прерывания:

//*******************************************************************************
// Timer 1 output compare interrupt service routine
//*******************************************************************************
interrupt [TIM1_COMPA]void Tim1_compA_ISR(void){
TCNT1=0;

// Ваш код.....
}


Си - это, конечно, хорошо, но кто-нибудь может привести пример на Ассемблере?
Harvester
Цитата(Kesha123 @ Jul 3 2006, 11:38) *
Цитата(ALexx @ Jul 3 2006, 11:24) *

Цитата(Kesha123 @ Jul 3 2006, 08:54) *

Кто-нибудь подскажет, как запустить режим по совпадению таймера1? А, именно, имеется мега32 16МГц, нужно вызывать прерывание каждую миллисекунду. Заранее благодарен!


В приложении - Хидер и Сишник для обслуживания таймеров

В процедуре инициализации ставите слкдующие строки:

//Запуск системного таймера
Timer1_SetMode(DISABLE_OC, DISABLE_OC, T1_NORMAL);
Timer1_SetMatchValue(CHANNEL_A,2000); // 1000Hz(T=1ms) on f=CLK/8 (CLK=16MHz)
Tim_EnableInt(OCIE1A);
Timer1_Start(T1_CLK_8);


Процедура обработки прерывания:

//*******************************************************************************
// Timer 1 output compare interrupt service routine
//*******************************************************************************
interrupt [TIM1_COMPA]void Tim1_compA_ISR(void){
TCNT1=0;

// Ваш код.....
}


Си - это, конечно, хорошо, но кто-нибудь может привести пример на Ассемблере?


Я же написал, какие значения куда пихать!
Неужели трудно записать это на ассемблере? Там нужно всего-то пара команд - ldi и out
Kesha123
Кстати, нашел программку, с помощью которой можно быстро сосчитать всяческие предделители, OCR, TCNT и др.
Нажмите для просмотра прикрепленного файла
IgorKossak
Если требование по точности временнОго интервала жёсткое, то такой метод
Код
TCNT1=0;
не подойдёт.
В этом случае интервал удлинняется на непредсказуемую величину, зависящую от времени реакции на прерывание.
Лучше сделать так:
Код
OCR1A += INTERVAL_VALUE;
или так:
Код
ldi r17,HIGH(INTERVAL_VALUE)
ldi r16,LOW(INTERVAL_VALUE)
in r18,OCR1AL
add r16,r18
in r18,OCR1AH
adc r17,r18
out OCR1AH,r17
out OCR1AL,r16


Или ещё вариант - использовать режим обнуления таймера по совпадению (CTC).
Kesha123
Цитата(IgorKossak @ Jul 5 2006, 11:03) *
Или ещё вариант - использовать режим обнуления таймера по совпадению (CTC).


Именно, режим СТС!!!
singlskv
Цитата(Harvester @ Jul 3 2006, 11:38) *
CS12...CS10 = 010 (регистр TCCR1B) - предделитель clk/8
значение для сравнения по формуле K = Tзад/(n/Fclk) = Fclk*Tзад/n
n - коэфф предделителя
Tзад - требуемый период
Fclk - тактовая частота
K = 16E6*1E-3/8 = 2000


OCR1A = 2000 - с чем сравнивать


OCR1A = 2000 - 1 = 1999
Kesha123
OCR1A = 2000 - 1 = 1999
[/quote]

Да! Пробовал при OCR1A без вычитания единицы - погрешность измерения временного интервала была 0,053%, вычел единицу - в итоге погрешность стала 0,0035% smile.gif
=GM=
Цитата(Kesha123 @ Jul 6 2006, 04:38) *
Да! Пробовал при OCR1A без вычитания единицы - погрешность измерения временного интервала была 0,053%, вычел единицу - в итоге погрешность стала 0,0035% smile.gif


Поясните, что вы измеряете? И как определяете погрешность? В своё время я довел относительную погрешность измерения периода входного сигнала на авр8515 до 1Е-7, т.е. 0.00001%, так что вам есть куда развиваться(:-)
Kesha123
Цитата(=GM= @ Jul 6 2006, 13:53) *
Цитата(Kesha123 @ Jul 6 2006, 04:38) *

Да! Пробовал при OCR1A без вычитания единицы - погрешность измерения временного интервала была 0,053%, вычел единицу - в итоге погрешность стала 0,0035% smile.gif


Поясните, что вы измеряете? И как определяете погрешность? В своё время я довел относительную погрешность измерения периода входного сигнала на авр8515 до 1Е-7, т.е. 0.00001%, так что вам есть куда развиваться(:-)


Прерывание вызывается каждую миллисекунду. Контролирую по электронному секундомеру СТЦ-2М.
=GM=
Цитата(Kesha123 @ Jul 6 2006, 09:10) *
Прерывание вызывается каждую миллисекунду. Контролирую по электронному секундомеру СТЦ-2М.

Ну вы толком объясните, что вы измеряете. Ваш секундомер находится внутри процессора? Инфу из вас приходится клещами тянуть(:-).
Kesha123
Цитата(=GM= @ Jul 6 2006, 16:33) *
Цитата(Kesha123 @ Jul 6 2006, 09:10) *

Прерывание вызывается каждую миллисекунду. Контролирую по электронному секундомеру СТЦ-2М.

Ну вы толком объясните, что вы измеряете. Ваш секундомер находится внутри процессора? Инфу из вас приходится клещами тянуть(:-).


Грубо говоря, процессор выступает в роли счетчика времени (показания выводятся на ЖКИ). В роли образцового счетчика - СТЦ-2М. Начальные показания = 0. При подаче команды СТАРТ стартуют оба устройства. При подаче СТОП, оба тормозят. После чего снимаю показания обоих и вычисляю погрешность.
=GM=
Цитата(Kesha123 @ Jul 6 2006, 11:56) *
Грубо говоря, процессор выступает в роли счетчика времени (показания выводятся на ЖКИ). В роли образцового счетчика - СТЦ-2М. Начальные показания = 0. При подаче команды СТАРТ стартуют оба устройства. При подаче СТОП, оба тормозят. После чего снимаю показания обоих и вычисляю погрешность.


Если я правильно понял, исходя из параметров СТЦ-2, вы получаете разницу 35 мс на интервале в 1000 сек или что-то около того. Поскольку ваш измеритель дает погрешность в 1 мс, вы меряете не ошибку измерения периода, а погрешность вашего тактового генератора. Стоит подумать о замене генератора(:-).
Kesha123
Пожалуй, стоит думать о замене кварца на проце blink.gif
IgorKossak
Цитата(Kesha123 @ Jul 7 2006, 09:32) *
Пожалуй, стоит думать о замене кварца на проце blink.gif

После того как замените кварц и получите те же результаты, попытайтесь всё-таки сделать так, как я Вам говорил в моём предыдущем сообщении.
Такая погрешность как у Вас как раз говорит о неправильном подходе к измерению временнЫх интервалов, а вовсе не о точности кварца.
=GM=
Цитата(Kesha123 @ Jul 7 2006, 09:32) *
Пожалуй, стоит думать о замене кварца на проце

До смены кварца попробуйте поставить подстроечный конденсатор к ноге кварца и на землю (или последовательно, посмотрите что лучше, зависит от схемы включения), и поиграться настройкой.
В любом случае, если вы хотите сделать точный прибор, то лучше использовать внешний калиброванный кварцевый генератор, может быть с подогревом и термокомпенсацией...
И вот еще что. Достигнутая вами погрешность еще ни о чем не говорит. Попробуйте получить СКО на хотя бы 100 измерениях, тогда можно судить о достоверности ваших измерений.

Цитата(IgorKossak @ Jul 7 2006, 06:41) *
После того как замените кварц и получите те же результаты, попытайтесь всё-таки сделать так, как я Вам говорил в моём предыдущем сообщении.
Такая погрешность как у Вас как раз говорит о неправильном подходе к измерению временнЫх интервалов, а вовсе не о точности кварца.

У автора единица измерения = 1 мс. В принципе он должен был бы получить погрешность в 1 мс, ну или +-1 мс (поскольку команды старт и стоп асинхронны с источником 1 мс), а он получает на два порядка больше.
А вы хотите, чтобы он измерял точнее, чем одна миллисекунда. Объясните, откуда у него набегает ошибка в 35 мс? Он просто подсчитывает импульсы заполнения в течение длительного интервала - аналог частотомера.
IgorKossak
Когда я отвечал, я смотрел на вопрос в теме.
Если же речь идёт о замере временнОго интервала с большой точностью, то метод, о котором идёт речь не самый лучший. Тем более, что AVR позволяет замерять временнЫе интервалы с дискретностью своей тактовой частоты.
Здесь вполне достаточно стартовать/останавливаться по внешнему прерыванию и использовать прерывание переполнения счётчика для возможного увеличения его разрядности.
=GM=
Цитата(IgorKossak @ Jul 7 2006, 11:48) *
Когда я отвечал, я смотрел на вопрос в теме.
Если же речь идёт о замере временнОго интервала с большой точностью, то метод, о котором идёт речь не самый лучший. Тем более, что AVR позволяет замерять временнЫе интервалы с дискретностью своей тактовой частоты.
Здесь вполне достаточно стартовать/останавливаться по внешнему прерыванию и использовать прерывание переполнения счётчика для возможного увеличения его разрядности.

Понятно. Вообще, это мои догадки, как автор меряет и что. Я пытался его спросить, но он молчит, как партизан(:-). А в принципе, меряя частоту стабильного генератора на таком гигантском интервале в 1000 с, можно добиться высочайшей относительной точности, а абсолютная точность будет определяться только временной стабильностью данного генератора.
Kesha123
Погрешность стабильная на любых интервалах измерения. Плюс ко всему в обработчике прерывания идет математика, она, соответственно, тоже дает задержку.
=GM=
Цитата(Kesha123 @ Jul 10 2006, 03:24) *
Погрешность стабильная на любых интервалах измерения. Плюс ко всему в обработчике прерывания идет математика, она, соответственно, тоже дает задержку.


Последний раз попрошу объяснить, что вы, и как, меряете. Что за математика идет в обработчике прерывания и что это там за задержка и т.д.

Отвлекусь по делу(:-). Теоретически относительная погрешность измерения определяется суммой 3-х составляющих. Погрешностью опорного генератора, погрешностью измерения импульсов заполнения и погрешностью временного интервала измерения. Пусть, погрешность опорного состаляет 1Е-6, погрешность временного интервала можно свести к 0. Погрешность заполнения (для АВР с клоком на 10 МГц) на интервале 10000 сек составит 1Е-10. Таким образом, суммарная погрешность будет определяться в основном погрешностью опорного генератора и практически не зависит от погрешности заполнения.

Поставьте идеальный опорник и получите точность 1Е-10. Но не лучше(:-(.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.