Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ТАЙМЕР1
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
dvs85
Здравствуйте!

Я только недавно начал осваивать МК ATMEL. Не мог бы кто нибудь дать пример программмы по инициализации таймера1 для подсчета временных интервалов и вывода этого подсчитаного времени на ЖКИ? Уже неделю бьюсь с ним и ничего не получается. wacko.gif
Пишу на СИ. Компилятор AVR Studio 4. Контроллер Мега1 .

Зараннее благодарю..
IDE
вот примерно так:

void timer1_init(void)
{
TIMSK |= (1 << TOIE1);
ICR1H=0x7A;
ICR1L=0x12;
}

void timer1_start(void)
{
TCCR1B=0x13;
}

void timer1_stop(void)
{
TCCR1B = 0x00;
}

если контроллер mega16

или так, если к примеру 169:

#define timer1_init() do { TIMSK1 |= (1 << TOIE1); } while (false)
#define timer1_start() do { TCCR1B |=(1 << CS10); } while (false)
dvs85
Спасибо.

МК - Мега16. Не заметил как стер
А в какой регистр записывается время? В ICR1H и ICR1L?

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

void timer1_init(void)
{
TIMSK |= (1 << TOIE1)|(1<<TICIE1);

ICR1H=0x7A;
ICR1L=0x12;
}
IDE
1. В оба
2. Да именно так
dvs85
То есть получается приходит сигнал на вход захвата, срабатывает прерывание, таймер начинает тикать и натиканое значение скидывает в регистры ICR1H и ICR1L? А когда происходит переполнение таймера, то что происходит? То есть можно сделать счетчик прерываний этих переполнений и значение этого счетчика и будет значение в секундах? Я все правильно понял?

И еще вопросик - для чего служит бит WGM1 регистра TCCR1B?
Qwertty
Цитата(dvs85 @ Apr 21 2008, 05:07) *
То есть получается приходит сигнал на вход захвата, срабатывает прерывание, таймер начинает тикать и натиканое значение скидывает в регистры ICR1H и ICR1L? А когда происходит переполнение таймера, то что происходит? То есть можно сделать счетчик прерываний этих переполнений и значение этого счетчика и будет значение в секундах? Я все правильно понял?

И еще вопросик - для чего служит бит WGM1 регистра TCCR1B?

Все совсем не так. Писать в регистры ICR1x имеет смысл только при работе таймера в режиме PWM, когда этими регистрами определяется максимальное значение - т.е. частота PWM. В других режимах в эти регистры копируется содержимое счетчика, во время возникновения события захвата. Т.е. регистры 'TCNT1H->ICR1H TCNTL->ICR1L копируются аппаратно. Сам по себе захват никаким образом не управляет таймером.
При переполнении таймера содержимое регистров TCNT1H:TCNT1L становится равным 0 и устанавливается флаг OVF1. Если разрешены прерывания по переполнению, то также вызывается соответствующее прерывание.
dvs85
Что то я совсем запутался.. 07.gif

Как же мне сделать такую программу, чтобы при подаче на какую - либо ногу МК сигнала срабатывал таймер? При этом, чтобы он считал, считал, а когда сигнал пропадает, то выводил замерянное время на ЖКИ?

Подскажите, очень надо разобраться..
domowoj
Цитата(dvs85 @ Apr 21 2008, 07:57) *
ICR1H=0x7A;
ICR1L=0x12;

Зачем же туда что-то записывать,
в ICR1 должен записаться ваш код интервала
по внешнему сигналу ICP.
Читайте Евстифеева, там все прописано
http://lord-n.narod.ru/walla.html
(или даташит).

Можно и так:
ваш интервал подавать на INTn и програмно
включать/выключать Т1.
dvs85
Цитата
Читайте Евстифеева, там все прописано


Спасибо, почитаю..

Цитата
в ICR1 должен записаться ваш код интервала
по внешнему сигналу ICP.


Кстати что это означает?
Палыч
Цитата(dvs85 @ Apr 21 2008, 03:19) *
... пример программмы по инициализации таймера1 для подсчета временных интервалов и вывода этого подсчитаного времени на ЖКИ?...
После обсуждения в соседней конференции (http://electronix.ru/forum/lofiversion/index.php/t46414.html) у Вас остались вопросы? Хотелось бы уточнить задачу, а то, может быть, весь этот огород с захватом счетчика и не нужен вовсе. Какие интервалы времени Вы планируете замерять? С какой точностью?
domowoj
Цитата(dvs85 @ Apr 21 2008, 09:10) *
Спасибо, почитаю..
Кстати что это означает?


Уже вам ответили #6.
dvs85
Цитата
После обсуждения в соседней конференции (http://electronix.ru/forum/lofiversion/index.php/t46414.html) у Вас остались вопросы? Хотелось бы уточнить задачу, а то, может быть, весь этот огород с захватом счетчика и не нужен вовсе. Какие интервалы времени Вы планируете замерять? С какой точностью?


Вопросы остались. Программа не работает.. Я наверно тупой просто crying.gif

Задача такая: устройство включается и через некоторое время выключается. Необходимо замерить это время между включением и выключением. Время порядка милисекунд, до секунд. Точность до микросекунд.
Палыч
Цитата(dvs85 @ Apr 22 2008, 01:06) *
Необходимо замерить это время между включением и выключением. Время порядка милисекунд, до секунд. Точность до микросекунд.
C такой точностью без захвата счетчика таймера не обойтись...
Программа должна содержать следующие части:

1. Инициализация таймера
2. Обработчик Timer1 Capture
3. Обработчик Timer1 Overflow
4. Расчет интервала времени
Какая часть вызывает затруднение? Что не работает?
Maik-vs
Цитата(dvs85 @ Apr 22 2008, 02:06) *
Вопросы остались. Программа не работает.. Я наверно тупой просто crying.gif

Задача такая: устройство включается и через некоторое время выключается. Необходимо замерить это время между включением и выключением. Время порядка милисекунд, до секунд. Точность до микросекунд.

Я бы повесил этот сигнал на внешнее прерывание по обоим фронтам. Его обработчик пусть быстренько переписывает в регистр значение таймера, потом определяет задний или передний фронт. Если задний, то вычисляет длительность. Таймер бы я взял самый приоритетный, разрядность бы расширил софтом: в прерывании таймера по переполнению пусть наращивается регистр или хоть два, получится 24-разрядный таймер, 2 секунды на 16 мегагерцах.
dvs85
Цитата
C такой точностью без захвата счетчика таймера не обойтись...
Программа должна содержать следующие части:

1. Инициализация таймера
2. Обработчик Timer1 Capture
3. Обработчик Timer1 Overflow
4. Расчет интервала времени
Какая часть вызывает затруднение? Что не работает?


Затруднение вызывает расчет интервала времени. То есть я понял, как расчитывается время переполнения. Но там получаются неокругленные числа времени переполнения. Например при коэф. деления 16 и частоте 4 МГц получается 0,226сек. А как сделать, чтобы он считал допустим каждые 0,2 секунды?
Насколько я понял, надо в TCNT1 поместить значение 63035?


Цитата
Я бы повесил этот сигнал на внешнее прерывание по обоим фронтам. Его обработчик пусть быстренько переписывает в регистр значение таймера, потом определяет задний или передний фронт. Если задний, то вычисляет длительность. Таймер бы я взял самый приоритетный, разрядность бы расширил софтом: в прерывании таймера по переполнению пусть наращивается регистр или хоть два, получится 24-разрядный таймер, 2 секунды на 16 мегагерцах.


Спасибо. Но мне бы для начала разобраться с работой самого таймера.. Потом буду пробовать Ваше предложение
domowoj
Цитата(Maik-vs @ Apr 22 2008, 16:02) *
Я бы повесил этот сигнал на внешнее прерывание по обоим фронтам. Его обработчик пусть быстренько переписывает в регистр значение таймера, потом определяет задний или передний фронт. Если задний, то вычисляет длительность. Таймер бы я взял самый приоритетный, разрядность бы расширил софтом: в прерывании таймера по переполнению пусть наращивается регистр или хоть два, получится 24-разрядный таймер, 2 секунды на 16 мегагерцах.

Делай так,
хотя, для более глубокого изучения таймеров, можно спад твоего сигнала завести и на ICP.
dvs85
Код
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//========================================
//Инициализация таймера
void Timer1_Init(void)
{
  TIMSK |= (1 << TOIE1)|(1<<TICIE1);            //разрешение переполнения по захвату и по переполнению
  TCCR1B=(1<< ICES1)|(1 << CS21);
  TCNT1=60535;                        // Начинать считать с этого значения
}
//==========================================
//Окончание работы таймера

void Timer1_Stop(void)
{
  TCCR1B = 0x00;                                //Останов. работы
}
//=========================================
//Прерывание по захвату

ISR(TIMER1_CAPT_vect)                        
{
    unsigned int timer;
    timer = ICR1;                        
}
//=========================================
//Программа расчета времени
void Timer1_Inc(void)
{
    unsigned int timer;
    timer ++;
}
//========================================
//Прерывание по переполнению таймера

ISR(TIMER1_OVF_vect)                  //Если возникает прерывание по переполнению таймера,
{
    Timer1_Inc();                        //то перейти к функции Timer1_Inc()
}

//========================================
int main (void)
{
    Timer1_Init();
    
}


Это правильно сделано?
И я не понял как по сохраненым значением счетчика таймера и конечным значением счетчика таймера и счетчиком числа переполнений посчитать временной интервал.


Цитата
можно спад твоего сигнала завести и на ICP.


А как это сделать? Как он отличит, что это спад?

Цитата
Я бы повесил этот сигнал на внешнее прерывание по обоим фронтам. Его обработчик пусть быстренько переписывает в регистр значение таймера, потом определяет задний или передний фронт. Если задний, то вычисляет длительность. Таймер бы я взял самый приоритетный, разрядность бы расширил софтом: в прерывании таймера по переполнению пусть наращивается регистр или хоть два, получится 24-разрядный таймер, 2 секунды на 16 мегагерцах.


Как таймер узнает, что поступает задний фронт?
Maik-vs
Цитата(dvs85 @ Apr 24 2008, 06:57) *
[А как это сделать? Как он отличит, что это спад?
Как таймер узнает, что поступает задний фронт?


Всё это описано в документации. К сожалению, нужно всё это внимательно прочесть и понять. Если трудности с английским, то выучи язык! то можно поискать перевод на gaw.ru. Я когда разбирался, сделал вот это в екселе (Макросы не выключай!) Там меняешь битики в регистрах, оно показывает.
dvs85
Цитата
Если трудности с английским, то выучи язык!

Спасибо за совет, пытаюсь.. wassat.gif

Цитата
Я когда разбирался, сделал вот это в екселе (Макросы не выключай!) Там меняешь битики в регистрах, оно показывает.


Спасибо за файлик smile.gif рад любой помощи в освоении программирования МК

В общем попытаюсь изучать все досконально..
dvs85
Я уже наверно надоел, но увы.. Прочитал я все вроде очень хорошо, но вопросы остались те же crying.gif

Как таймер узнает, что сигнал прекращается?

Цитата
И я не понял как по сохраненым значением счетчика таймера и конечным значением счетчика таймера и счетчиком числа переполнений посчитать временной интервал.
domowoj
В TCCR1B есть бит ICЕSn.

А зачем TCNT1=60535; ?
не понял.
dvs85
Цитата
В TCCR1B есть бит ICTSn.


Я почему то не нашел такого бита
ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10 TCCR1B

В даташите только такие регистры написаны wassat.gif Что этот бит делает?

Цитата
А зачем TCNT1=60535; ?
не понял.


Ну это я почитал разную литературу и прочитал где то в ней, что
например при коэф. деления 8 и частоте 4 МГц получается 0,13сек. А как сделать, чтобы он считал допустим каждые 0,1 секунды(то есть время между прерываниями по переполнению)? Было написано, что надо в счетчик записать число (65535 - ((4000000*0.1)/8)), т.е. 63035. Чтобы потом было удобнее считать. Или я что то опять не понял?
domowoj
ICES1=0 - по заднему фр.
ICES1=1 ло переднему
одновременно с сохранением устанавливается флаг
ICF1 в TIFR

И каковы параметры интервала и с какой точностью его нужно мерить?
dvs85
Цитата
И каковы параметры интервала и с какой точностью его нужно мерить?


Программу я для примера написал, без учета всех требований.
Время порядка милисекунд, до секунд. Точность до микросекунд.

Цитата
ICES1=0 - по заднему фр.
ICES1=1 ло переднему
одновременно с сохранением устанавливается флаг
ICF1 в TIFR


Это то я понял.. Я не понял как сделать.. Ну поставил я бит чтобы захват срабатывал по переднему импульсу.. Запомнил счетчик свое значение.. Посчитал число переполнений. А как ему дать знать, что нада бы уже закончить считать? Я этого понять не могу laughing.gif
domowoj
Фиксировать значение таймера можно по тому же сигналу(ICP) , прямому или инверсному.
В обработчике флага захвата нужно ввести еще и признак -начало или конец интервала.
Можно пользоваться флагом Т .
В обработчике флага захвата сначала анализируешь Т, Т=0 допустим - начало,
установил Т-начал считать, пришел конец интервала, а Т уже =1 и ты идешь по другой ветке -
подсчитываешь - кол. переполнений умножаешь на 65536 и прибавляешь содерж. TCNT1
дальше на экран.
Сбросил Т и новый цикл .
А чтобы цикл был 0,1 сек 60535(или ?) нужно записывать в OCR1 и таймер в реж. CTC-сброс при совпадении-в даташите и у Евстифеева есть формула.
dvs85
Цитата(domowoj @ Apr 25 2008, 04:51) *
Фиксировать значение таймера можно по тому же сигналу(ICP) , прямому или инверсному.
В обработчике флага захвата нужно ввести еще и признак -начало или конец интервала.
Можно пользоваться флагом Т .
В обработчике флага захвата сначала анализируешь Т, Т=0 допустим - начало,
установил Т-начал считать, пришел конец интервала, а Т уже =1 и ты идешь по другой ветке -
подсчитываешь - кол. переполнений умножаешь на 65536 и прибавляешь содерж. TCNT1
дальше на экран.
Сбросил Т и новый цикл .
А чтобы цикл был 0,1 сек 60535(или ?) нужно записывать в OCR1 и таймер в реж. CTC-сброс при совпадении-в даташите и у Евстифеева есть формула.


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