Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.97/37: Рейтинг темы: голосов - 37, средняя оценка - 4.97
Opyk
0 / 0 / 0
Регистрация: 29.03.2010
Сообщений: 44
1

Отсчет разных промежутков времени на 1 таймере

20.08.2011, 10:04. Просмотров 6960. Ответов 6
Метки нет (Все метки)

Здравствуйте.
Есть один 16-разрядный таймер/счетчик.
Нужно на нем обеспечить отсчет разных промежутков времени. Если бы они шли друг за другом - проблем бы не возникало - но они могут пересекаться. Т.е. одновременно нужно считать 2 времени (1 минут и 15 минут).

Т.к. таймеров в AVR не так уж и много - наверняка кто-то из вас уже сталкивался с такой задачей. Подскажите пожалуйста алгоритм действий.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.08.2011, 10:04
Ответы с готовыми решениями:

ATmega128. Отсчет длительного интервала времени
Добрый вечер форумчане, Обращаюсь к Вам с просьбой помочь мне в одном задании, необходимо...

Неправильный отсчет в таймере
Проблема состоит в том, что таймер пропускает секунды (9:58...9:56...9:54...9:52...). Интервал...

Поиск одинаковых промежутков времени
Очень нужна помощь. Буду очень признателен. Самому не удается выполнить. В колл-центре ведётся...

Измерение больших промежутков времени.
Кто-нибудь когда-нибудь измерял в своих программах промежутки времени длительностью более 6 часов...

Добавить вывод промежутков времени в цикле
Есть цикл for (int i=0;i<=1000;i++) { Console.WriteLine(i); } Надо добавить время, то есть...

6
surosk
0 / 0 / 0
Регистрация: 17.01.2011
Сообщений: 25
20.08.2011, 10:16 2
Цитата Сообщение от Opyk
Здравствуйте.
Есть один 16-разрядный таймер/счетчик.
Нужно на нем обеспечить отсчет разных промежутков времени. Если бы они шли друг за другом - проблем бы не возникало - но они могут пересекаться. Т.е. одновременно нужно считать 2 времени (1 минут и 15 минут).

Т.к. таймеров в AVR не так уж и много - наверняка кто-то из вас уже сталкивался с такой задачей. Подскажите пожалуйста алгоритм действий.
генерить прерывание раз в минуту, а в обработчике прерывания ввести счётчики. например, иметь переменную типа char и в обработчике инкрементировать её. как только она стала равна 15, значит прошло 15 минут. после этого не забыть обнулить счётчик:)
0
swk
0 / 0 / 0
Регистрация: 22.10.2015
20.08.2011, 10:30 3
Цитата Сообщение от Opyk
Т.к. таймеров в AVR не так уж и много - наверняка кто-то из вас уже сталкивался с такой задачей. Подскажите пожалуйста алгоритм действий.
Нет проблем. Делаем на нем "системный таймер" с некоторым удобным значением (я обычно делаю 1 мс). В обработчике прерывания делаем сколько угодно "программных таймеров", которые только инкрементируем, (или декрементируем, пока не 0). Сами же эти программные таймеры - простая переменная. Если она 2х байтовая - получаем 65535 мс, или более 65 сек.
Можно загружать в него значение 60000 и при переходе через нуль инкрементировать уже другой счетчик - минут. Или сделать 1000, - получим секунду, а по нему менять значение других счетчиков - секундомеров, и так далее. Я так когда - то еще на 8048 с единственным таймером делал кучу программных задержек, да еще и часы с календарем. По окончании выдержки таких программных таймеров выставляется соответствующий флаг, который проверяется в главном цикле программы для принятия соответствующих действий.
Вот пример такого обработчика таймера в одной из моих программ - ходового контроллера робота:
Код
//==== interrupt =====
procedure interrupt;
begin
if (T0IF <> 0) then //  Int_Timer0;
begin
if cnt_1   > 0 then Dec(cnt_1);  {- таймер опроса контроллера бамперов}
if cnt_2   > 0 then Dec(cnt_2);  {- таймер для АЦП}
if pauza   > 0 then Dec(pauza);  {- таймер для ПРД RS232}
if tim_aut > 0 then Dec(tim_aut);{- таймер для ПРМ RS232}
PORTC := PORTC xor $01;          {- Звук!}
if cnt_10 = 1 then
begin
if T_sound > 0 then Dec(T_sound);// Таймер продолжительности звука.
if DWL_2 > 0 then Dec(DWL_2);    // Время работы оставшееся ДВ_ЛЕВ
if DWP_2 > 0 then Dec(DWP_2);    // Время работы оставшееся ДВ_ПРАВ
end;
if cnt_10 = 0 then cnt_10 := 10 else Dec(cnt_10); {- таймер для двигателей}
if UART1_Data_Ready() = 1 then
begin
if SSP_1.6 = 1 then received_byte := UART1_Read()  // Читаем принятый байт
else Sost_Prm.6 := 1; // Есть принятый байт с R232
end;
INTCON.2 := 0;   //clear T0IF
end;
end;
//===================
Всего 102 байта после компиляции. Частота контроллера (PIC16F876) - 16МГц.
Аналогично можете сделать и на AVR, главное - понять сам принцип.
0
Opyk
0 / 0 / 0
Регистрация: 29.03.2010
Сообщений: 44
20.08.2011, 10:34 4
surosk:
Была такая идея, и так собирался сделать, но есть несколько минусов:
Отсчеты времени начинаются не одновременно. Сначала может начаться отсчет 1 минуты, а потом к нему подключиться 15 минут, а может наоборот. И если отсчет 15 минут начался - через пару минут к нему присоединяется отсчет 1 минуты, как тут отследить?

Как вариант - брать предыдущее значение переменной, и ждать пока она увеличится на единицу. Но тоже не кошерно - вдруг переполнение, (а также увеличение) произойдет через 5-10 секунд после нашего замера - ни разу не минута пройдет. Т.е. надо брать промежутки времени более короткие, минимум по 1 секунде (точное время не критично).

Но тоже минус - переменные наши не бесконечны. Взять например unsykned char - макс. значение 255. Возьмем отсчет 15 минут на значении переменной 253. Чтобы прошло 15 минут, переменная должна показать 268, а она столько не покажет (я так понимаю если при 255 ее не обнулить - программа будет хз что творить.

Можно конечно взять и более длинные переменные - но ведь та же проблема. Какое бы число не было - оно закончится. А устройство может стоять и работать постоянно (например год).

В общем как-то выкрутиться тут наверное можно, но может есть способ попроще?

SWK: спасибо. Попробую вкурить :)))
0
obdomk
0 / 0 / 0
Регистрация: 17.08.2011
Сообщений: 37
20.08.2011, 15:13 5
Используете функцию "захват" этого таймера. Это может выглядеть так. Таймер считает бесконечный цикл с известным квантом времени. По приходу любого события ("1 мин" или "15 мин") фиксируем в регистре захвата текущее состояние таймера, далее расчитываем через сколько циклов переполнения + хвост (неполный цикл) случится окончание соответствующего события. Циклы считаем по прерыванию по переполнению счета. После обнаружения последнего цикла устанавливаем хвост в регистре сравнения А - для одного события или В - для другого и разрешаем прерывания по сравнению. Обратите внимание, что перед разрешением прерывания по сравнению надо сбросить флаг этого прерывания, который мог установиться ранее.
0
ZPS
0 / 0 / 0
Регистрация: 16.02.2010
Сообщений: 511
20.08.2011, 16:53 6
Цитата Сообщение от Opyk
Можно конечно взять и более длинные переменные - но ведь та же проблема. Какое бы число не было - оно закончится. А устройство может стоять и работать постоянно (например год).
А в чем проблема?
Например, так
char таймер1_годы
char таймер1_месяцы
char таймер1_дни
char таймер1_часы
char таймер1_минуты
char таймер1_секунды.

переполнились секунды, обнуляем, минуты +1 и тд
таймер будет ограничен в 256 лет.

Это если грубо влоб решать.
0
drvtos
1 / 1 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
20.08.2011, 17:25 7
Цитата Сообщение от Opyk
Была такая идея, и так собирался сделать, но есть несколько минусов:
Отсчеты времени начинаются не одновременно.
так как уважаемый SWK не отвечает, то позволю себе дополнить его. Ибо автор темы не понял предложенного метода.

Итак, у тебя есть системный клок - пусть те же 1 мс, неважно. В каждый такой тик ты влетаешь в прерывание и там занимаешься своими МНОГОЧИСЛЕННЫМИ счетчиками.

По возникновению события, от которого ты хочешь отсчитать некое время, ты заряжаешь СООТВЕТСТВУЮЩИЙ программный счетчик. Размер этого счетчика делаешь такой, чтобы его хватило на любой желаемый интервал времени. Один байт, 2 байта, да хоть сто байт - в чем проблема?

Теперь в прерывании (системный клок) ты уменьшаешь этот счетчик, если он еще не ноль. А если ноль - то уже не вычитаешь, а устанавливаешь флаг ЗАКОНЧИВШЕГОСЯ интервала. Или просто делаешь то, что задумывал. Например, включаешь самоликвидацию. Или выдаешь там какой-то импульс и перезаряжаешь счетчик на следующий интервал времени.

А если у тебя НЕСИНХРОННО возникает другое событие - так и работаешь с ним и с ДРУГИМ уже счетчиком.

И никакого ограничения тут нет. Пусть твой девайс работает хоть 100 лет.
0
20.08.2011, 17:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2011, 17:25

Отсчёт времени в таймере
Как мне запилить вывод отсчёта времени из таймера в лейбл? И как при нажатии на клавишу мне таймер...

Подсчет времени в таймере даже при выключенном ПК
Всем доброй ночи! Ребята подскажите на форме есть таймер который показывает секунды минуты и сутки,...

Определить по графику среднюю скорость движения тела для промежутков времени
Определить по графику среднюю скорость движения тела для промежутков времени: 2 с - 2,5 с, 2 с - 3...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru