Программные таймер и счетчик

Таймеры-счетчики

Таймером называется средство микропроцессора, служащее для измерения времени и реализации задержек. Основой таймера служит суммирующий счетчик, который считает количество импульсов генератора тактовой частоты.
Для таймера могут быть указаны:

  • разрядость таймера;
  • коэффициент предварительного деления;
  • диапазон изменения счетного регистра;
  • режим работы.

Разрядность таймера представляет собой разрядность двоичного счетчика, используемого для его реализации и определяет верхнюю допустимую границу счетного регистра. Например, для 8-разрядного таймера верхняя граница счетного регистра будет 2 8 -1 = 255.

Предварительный делитель – делитель частоты тактового сигнала, работающий как один или несколько последовательно соединенных T-триггеров. Таймер изменяет свое значение на 1 каждые n сигналов тактового импульса. n называют коэффициентом предварительного деления .

Зная частоту тактового генератора fosc и коэффициент предварительного деления Kpre, легко определить частоту таймера по формуле:

Время одного тика таймера соответственно будет

Полное время счета таймера (время перебора всех допустимых значений двоичного счетчика) определится как

Например, если требуется реализовать задержку 1с на 8-разрядном таймере с коэффициентом предварительного деления Kpre=1 и тактовой частотой fosc=8 МГц, имеем

tic = 0,125 мкс;
Tcount = 0,125*2 8 = 32 мкс
1с/32мкс = 31250 повторений

Широтно-импульсная модуляция

Широтно-импульсная модуляция (ШИМ) – импульсный сигнал постоянной частоты и переменной скважности.
Скважность есть отношения периода следования импульса к длительности импульса.
С помощью задания скважности (длительности импульсов) можно менять среднее напряжение на выходе ШИМ.
Обратная величина, то есть отношение длительности импульса к периоду, называется коэффициентом заполнения .

Разрядностью ШИМ называется разрядность таймера, используемого для формирования ШИМ-сигнала.
Существуют два основных режима работы ШИМ:

Быстрый ШИМ

Период ШИМ определяется максимальным значением, до которого считает счетчик. В этот момент ШИМ-сигнал устанавливается в «1». При достижении счетчиком значения, поданного на второй вход цифрового компаратора, осуществляется сброс выходного ШИМ-сигнала.

Фазовый ШИМ

В данном режиме счетчик работает как суммирующий и считает от 0 до максимального значения, а при достижении максимального значения работает как вычитающий, считая до 0.

При совпадении значения счетчика с некоторым установленным значением, происходит переключение выхода ШИМ.

Частотно-импульсная модуляция — сигнал переменной частоты и постоянной скважности, равной 2. При таком виде модуляции изменяется период сигнала, а длительность импульса всегда составляет половину периода.

CAMOKAT-BETEPAHA › Блог › ПРОГРАММИРОВАНИЕ МИКРОКОНТРОЛЛЕРОВ: таймер

Для самых маленьких познавателей микроконтроллеров.
Поговорим про таймеры-счетчики микроконтроллеров AVR и конкретно ATTiny13A.
Начинающим очень сложно порой понять, как работают таймеры, в даташите столько написано про таймеры и так непонятно, что жуть. Да ещё и по-английски.

Обычно описание работы начинают как в даташите сверху вниз, а я начну снизу вверх, так более понятно начинающим.

Работа таймера-счетчика очень похожа на работу механического колесика одометра в панели приборов автомобиля. Вот и с ним будем сравнивать.

Долее по даташиту:

TCNT0 Timer/Counter Register. Это регистр таймера счетчика. Это колесико одометра. Если этому колесику придать вращение от какого нибудь сигнала, то он начнет крутиться. У колесика 255 положений, а не от нуля до девяти, как у одометра авто. Крутится он по кругу, то есть 0,1,2,3…254,255,0,1,2,3… Этот регистр открыт для чтения и записи, то есть можно считывать его значение и писать свое. простой пример: колесико должно крутится до 127, а потом сразу сбрасываться в ноль и считать дальше:

По-русски:
Если значение счетчика равно 127 if(TCNT0==127)
То сбрасываем этот же счетчик в ноль (присваиваем регистру нулевое значение )

В этом примере есть и чтение регистра TCNT0 и запись в этот же регистр.

Теперь выше по даташиту: как и чем и отчего заставить крутится это колесико одометра?

Для этого есть два способа:

1.- От тактового генератора микроконтроллера.
2. — От состояние входа( ножки) Т0

От тактового генератора:

Счетчик крутится от тактового генератора, “скорость” вращения колесика можно выбирать делителем. Отвечает за делитель регистр TCCR0B

Пример расчета “скорости”: тактовый генератор лопатит на 1,2МГц:

TCCR0B=0x00 счетчик выключен.Можно использовать это значение как выключалку таймера-счетчика
TCCR0B=0x01 счетчик лопатит на 1,2МГц: деление на единицу типа)
TCCR0B=0x02 счетчик лопатит на 150кГц: деление на 8
TCCR0B=0x03 счетчик лопатит на 18,75кГц: деление на 64
TCCR0B=0x04 счетчик лопатит на 4,688кГц: деление на 256
TCCR0B=0x05 счетчик лопатит на 1,172кГц: деление на 1024

От состоянии на входной ножке Т0 (это 7 ножка порт РВ2)

TCCR0B=0x06 по спаду сигнала
TCCR0B=0x07 по фронту сигнала

Например: на входе Т0 логический ноль. В регистре TCCR0B=0x06 стоит по спаду сигнала. Счетчик стоит. Появилась единица на входе. Счетчик почуял это и приготовился, ибо по спаду. Пропала единица — стал ноль на входе Т0 — регистр таймера счетчика TCNT0 прибавил себе единичку и опять следит за состоянием по входу Т0

Колесико то крутится, но в холостую. Надо теперь сделать так, чтоб оно делало полезную работу. А вот тут уже много возможностей.

Есть несколько основных выводов полезной работы счетчика-таймера.

Делать работу, можно если значение счетчика (колесико TCNT0) сравняется с регистром сравнения-совпадения OCR0х. Это ещё составная часть таймера счетчика, состоящая из двух равнозначных регистра OCR0A и OCR0B.
OCR0A и OCR0B — это как колесики на кодовом навесном замке. Если уж совсем так сравнивать, то это два отдельных кодовых навесных замка с одним колесиком:

То есть можно выставлять свое значение колесика замка OCR0A или OCR0B, затем крутить колесико таймера одометра TCNT0, при совпадении значений замок открывается и происходит какое либо событие. Описание этого события зависит от того, в каком режиме работы находится таймер-счетчик. От этого режима зависит алгоритм работы и взаимодействия этих регистров. Режимы можно посмотреть в мастере CodeVisionAVR:

Читайте также:  Простой индикатор антенного тока

Далее простым детским языком уже достаточно сложно объяснять, поэтому резко взрослеем, и начинаем понимать, что такое прерывание, что такое Широтно Импульсная Модуляция и что такое прерывание по переполнению таймера и как эти слова можно использовать к нашему таймеру счетчику, чтоб получить полезное действие.

Теперь примеры, созданные для среды разработки CodeVisionAVR:
значение фьюзов по умолчанию, поэтому тактовая частота равна 1.2МГц. Значения настройки портов и т.п. не указано, только мясо:

TCCR0B=0x03; //Запускаем таймер в обычном счетном режиме на 18,750 kHz
OCR0A=0xF0; // Указываем значение регистра сравнения равное 0хF0
TIMSK0=0x04;//Разрешаем выполнение прерываний по совпадению в OCR0A
#asm(“sei”) // Разрешаем сами глобальные прерывания
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
<
// Здесь малюем код
TCNT0=0x00;
>

Скриншот мастера:

Внутри фигурных скобок есть сброс колесика одометра в ноль: TCNT0=0x00;, то есть после выполнения кода счетчик сбрасывается и начинается счет с нуля. И так циклично.

Этот код применяется, если необходимо производить какое либо действо через определенный точно заданный промежуток времени: делать опрос какого либо устройства, мерять температуру, сканировать состояние энкодера да еще много что можно. Ну или например, если настроить вызов прерывания ровно раз в секунду, то можно сделать секундомер. Конкретно данный пример срабатывает 18750/240=78,125 раза в секунду.

Теперь интереснее: запускаем ШИМ:

TCCR0A=0x81;//запускаем ШИМ с фазовой коррекцией и назначаем выход ножки PB0(OC0A) на выход импульсов ШИМа
TCCR0B=0x02;//частота работы таймера 150 кГц
TIMSK0=0x02;//разрешаем прерывания по переполнению таймера
#asm(“sei”)// Разрешаем сами глобальные прерывания
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
<
// Малюем код
>

Ну а здесь описание совсем короткое: на выходе PB0 микроконтроллера (ножка 5) будет присутствовать ШИМ сигнал (если будет правильно сконфигурирован этот порт на выход), с заполнением пропорционально значению регистра OCR0A
Примеры:
OCR0A=0; — ШИМа небудет, ноль на выходе
OCR0A=127; — на выходе ровный меандр с заполнением 50/50
OCR0A=255; — на выходе единица, ШИМа нет

Так как включено прерывание по переполнению таймера, то когда счетчик насчитает максимальное значение, то будет срабатывать прерывание (выполняться код “Малюем код”)
Скриншот мастера:

Теперь, освоив и поняв принцип работы таймера, несложно понять, как работает таймер в других режимах, чем отличается ШИМ с фазовой коррекцией от обычного Fast PWM и так далее и тому подобное. Но это вы уже сами.

Исходный код библиотеки

Для наглядности я объединил хедер и сишный файл.

//состояния таймера – неработающий, активный, отработавший
enum StateTimer ;

//структура программного таймера
typedef struct <
unsigned int time; //через какое время запустить
unsigned int period; //период повторения
enum StateTimer state; //текущее состояние
void (*pFunc)( void ); //указатель на функцию
>SoftTimer;

//максимальное число таймеров
#define MAX_TIMERS 4

//число созданных таймеров
unsigned char AmountTimers = 0;

//массив указателей на таймеры
SoftTimer* SoftTimers[MAX_TIMERS];

//функция создания программного таймера
void CreateTimer(SoftTimer *CurSoftTimer, unsigned int time, unsigned int period , enum StateTimer state, void (*pFunc)( void )) <
SoftTimers[AmountTimers] = CurSoftTimer;
CurSoftTimer->time = time;
CurSoftTimer->period = period;
CurSoftTimer->state = state;
CurSoftTimer->pFunc = pFunc;
AmountTimers++;
>

//функция проверки таймеров
void CheckTimer( void ) <
for ( unsigned char i = 0; i if (SoftTimers[i]->state == ACTIVE) <
if (SoftTimers[i]->time == 0) <
SoftTimers[i]->pFunc();
if (SoftTimers[i]->period != 0) SoftTimers[i]->time = (SoftTimers[i]->period-1);
else SoftTimers[i]->state = DONE;
>
else (SoftTimers[i]->time)–;
>
>
>

Пояснение к коду

На основании этих требований определяем структуру SoftTimer.

//состояния таймера – неработающий, активный, отработавший
enum StateTimer ;

//структура программного таймера
typedef struct <
unsigned int time; //через какое время запустить
unsigned int period; //период повторения
enum StateTimer state; //текущее состояние
void (*pFunc)( void ); //указатель на функцию
>SoftTimer;

Массив указателей на таймеры

//максимальное число таймеров
#define MAX_TIMERS 4

//число созданных таймеров
unsigned char AmountTimers = 0;

//массив указателей на таймеры
SoftTimer* SoftTimers[MAX_TIMERS];

Создание таймера

void CreateTimer(SoftTimer *CurSoftTimer, unsigned int time, unsigned int period , enum StateTimer state, void (*pFunc)( void )) <
SoftTimers[AmountTimers] = CurSoftTimer;
CurSoftTimer->time = time;
CurSoftTimer->period = period;
CurSoftTimer->state = state;
CurSoftTimer->pFunc = pFunc;
AmountTimers++;
>

Функция опроса таймеров

Функция опроса таймеров запускается в прерывании аппаратного таймера/счетчика

//функция проверки таймеров
void CheckTimer( void ) <
for ( unsigned char i = 0; i if (SoftTimers[i]->state == ACTIVE) <
if (SoftTimers[i]->time == 0) <
SoftTimers[i]->pFunc();
if (SoftTimers[i]->period != 0) SoftTimers[i]->time = (SoftTimers[i]->period-1);
else SoftTimers[i]->state = DONE;
>
else (SoftTimers[i]->time)–;
>
>
>

Тестовый проект

//программирование микроконтроллеров AVR на Си
//тестовый проект с программными таймерами
//Pashgan ChipEnable.ru

#include
#include
#include “Timers.h”
#include “bits_macros.h”

//объявляем переменные типа SoftTimer
SoftTimer timer1;
SoftTimer timer2;
SoftTimer timer3;
SoftTimer timer4;

//расписываем функции программных таймеров
void Clk1( void ) <
InvBit(PORTB, 0);
>

void Clk2( void ) <
InvBit(PORTB, 1);
>

void Clk3( void ) <
InvBit(PORTB, 2);
>

void Clk4( void ) <
InvBit(PORTB, 3);
>

int main( void )
<
//инициализация порта
PORTB = 0x00;
DDRB = 0xff;

//инициализация таймера Т0 – прерывания каждую ms
TIMSK = (1 //инициализируем таймеры
CreateTimer(&timer1, 0, 1, ACTIVE, Clk1);
CreateTimer(&timer2, 0, 2, ACTIVE, Clk2);
CreateTimer(&timer3, 0, 3, ACTIVE, Clk3);
CreateTimer(&timer4, 0, 4, ACTIVE, Clk4);

//разрешаем прерывания и тупим в цикле
__enable_interrupt ();
while (1);
return 0;
>

Заключение

Алгоритм, конечно, расточительный. Во-первых в прерывании запускается функция. Во-вторых перебор таймеров происходит последовательно – чем больше программных таймеров, тем больше времени это займет. В-третьих функции программных таймеров тоже запускаются в прерывании. Как можно оптимизировать? Не использовать много таймеров. Сделать функцию CheckTimer встраиваемой. Период работы аппаратного таймера выбрать большим. Функции программных таймеров сделать короткими.

Файлы

Comments

Программный таймер в такой реализации бесполезен без диспетчера задач.

гораздо эффективней при такой организации сделать просто “Системное время” скажем 32байтное, учитывающее каждый такт процессора. И относительно него отслеживать все процессы.

Как показала практика – реализация методом инкрементирован ия не удачная по нескольким причинам,а именно:
1) повышенный расход ресурсов (инкремент + прерывания);
2) не всегда высокая точность, т.к. прерывание не очень-то хочется делать слишком частыми. Если в качестве таймера использовать таймер RTOS – разрешающая способность выходит ну явно не лучше 1 мс, а скорее даже 5-10. Приведённые расслуждения о точности справедливы только для случая программировани я методом шагового автомата, при этом время для каждой задачи должно быть явно не больше требуемой точности.

Читайте также:  Повышающий преобразователь с mppt контролером заряда для солнечных батарей

Достоинства приведённого мною метода:
1) потребление ресурсов на таймер минимально, особенности если используется каскад таймеров с различными периодами в пределах одной функции-проверк и срабатывания одних таймеров можно легко выполнять при срабатывании других.
2) создание таймера – определение одной (счётчик) или двух переменных (счётчик и период, если T = 0, считаем, что таймер не активен; как вариант ещё – счётчик и флаг) в любой точке шагового автомата.
Недостатки:
1) для задач предельно жесткого реального времени данный метод не даём существенных преимуществ, т.к. всё равно надо работать в прерывании.
2) можно пропустить момент срабатывания таймера при малых периодах таймера и сложных, не поддающихся переписыванию на шаговый автомат.

Кстати, callback-функци и, вызываемые из прерывания – не очень хорошая идея, т.к. подходят только для очень быстрых функций.

У вас недостаточно прав для комментирования.

Программные таймер и счетчик

Программные таймеры. Что это, и с чем их “едят”

Что такое программный таймер? Это таймер-счётчик, основой которого является системный таймер. Т.е., другими словами, это обычная переменная, считающая переполнения системного таймера. Программному таймеру, как минимум, нужен ещё один бит-флаг, управляющий(указывающий) состоянием(на состояние) таймера.

Давайте разберём это на примере.
Что нам нужно ? Нам нужно создать переменную, которая будет счётчиком ,и флаг состояния таймера.
Можно объявить 2 переменных. Одна будет счётчик(например unsigned int), другая – типа bit. Но мы пойдём немного другим путём. Мы будем использовать старший бит переменной как бит состояния. Т.е. знак переменной у нас будет состоянием таймера. Но, тут есть один минус. Разрешение нашего таймера сократиться ровно в 2 раза, т.к. один бит будет занят. Т.е., если переменная = 2 байтам, то считать мы сможем только до 32767.

Создаём 2-х байтную знаковую переменную. Именно знаковую, т.к. знак у нас – состояние таймера.

Форум по микроконтроллерам: Программные таймеры – Форум по микроконтроллерам
  • Форум по микроконтроллерам
  • >Микроконтроллеры
  • >PIC
  • >Примеры оформления программ
  • Правила форума
  • Просмотр новых публикаций

Программные таймеры Что это, и с чем их “едят”

#1 Alex

  • Убиватель МК
  • Группа: Пользователи
  • Сообщений: 1 903
  • Регистрация: 15 Февраль 11

Здесь статья
Что такое программный таймер ? Это таймер-счётчик, основой которого является системный таймер. Т.е., своими словами, это обычная переменная, считающая переполнения системного таймера. Программному таймеру, как минимум, нужен ещё один бит-флаг, управляющий(указывающий) состоянием(на состояние) таймера.
Давайте разберём это на примере.
Что нам нужно ? Нам нужно создать переменную, которая будет счётчиком ,и флаг состояния таймера.
Можно объявить 2 переменных. Одна будет счётчик(например unsigned int), другая – типа bit. Но мы пойдём немного другим путём. Мы будем использовать старший бит переменной как бит состояния. Т.е. знак переменной у нас будет состоянием таймера. Но, тут есть один минус. Разрешение нашего таймера сократиться ровно в 2 раза, т.к. один бит будет занят. Т.е., если переменная = 2 байтам, то считать мы сможем только до 32767.

Создаём 2-х байтную знаковую переменную. Иименно знаковую, т.к. знак у нас – состояние таймера.

Далее, нам необходимо создать обработчик прерываний от любого, имеющегося на “борту” МК, таймера.
Возьмём за основу 1-й таймер. Тактовая частота МК = 20Мгц. Таймер настраиваем на 1 мс.
Системные тики имеем. Теперь нам нужно их считать, т.е. сделать обработчик нашего программного таймера.
Сделаем проверку флага состояния, и, если таймер запущен, уменьшим счётчик на единицу.
Добавляем в ОП системного таймера такой кодПроверяем переменную на отрицательность (старший бит переменной). Тем самым, мы проверяем состояние таймера, и, если переменная отрицательна( cnt – не ошибка. Счётчик у нас будет считать от -n до 0. Где n-это устанавливаемое значение таймера. По этому мы делаем инкремент переменной(это и есть уменьшение счётчика таймера на единицу).
Программный таймер и его обработка созданы. Осталось всё это применить на деле.
В процедуре main() инициализируем системный таймер(TMR1) и разрешаем прерывания.

Далее зацикливаем программу
В этом цикле установим программный таймер на 500 тиков и будем ждать окончания его счёта. По окончанию счёта, проинвертируем один из ПИНов порта.
И у нас получится мигалка с частотой в 1Гц
timers_1.rar (49,56К)
Количество загрузок:: 324

Естественно, для мигания светодиода зацикливать программу, в ожидании окончания отсчёта таймера, глупо. Но мы можем не зацикливать программу, а просто проверять флаг состояния и мигать светодиодом. А программа, после проверки флага будет продолжать работат дальше.
Например, установим таймер, будем его проверять и продолжать выполнять программу дальше. Если проверка прошла, перезапустим таймер заного и проинвертируем ПИН светодиода.
В итоге, результат получился как и в предыдущем примере, но программа не зациклина, она продолжает свою работу. А LED инвертируется только когда отсчитает таймер. В том и прелесть программных таймеров, что они считают “в фоне”, а проверяем их и работаем с ними только по необходимости.
timers_2.rar (48,97К)
Количество загрузок:: 342

Для справочки, кусочек дизасмаЗаметьте, компилятор не делает никаких ужасных вычислений, он просто проверяет старший бит переменной.

Бесплатный таймер

Бесплатный, полнофункциональный и простой таймер для Windows

Программа Free Timer позволяет создавать таймеры обратного отсчета, которые отображают оставшееся время в виде цветного участка циферблата.

Вы можете установить время в секундах, минутах и ​​часах. Цветная часть циферблата будет отображать время, соответствующее заданному интервалу:

  • Если интервал составляет одну минуту или меньше, таймер считает в секундах (полный круг – 60 секунд).
  • Если интервал составляет один час или меньше, таймер считает в минутах (полный круг – 60 минут).
  • Если интервал составляет 12 часов или меньше, таймер считает в часах (полный круг – 12 часов).
  • Если интервал больше 12 часов, циферблат будет полностью покрыт указанным цветом. Что касается обратного отсчета, цветная секция будет постепенно уменьшаться в размере в соответствии с оставшимся временем.

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

Запускать несколько таймеров одновременно

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

Быстрый старт

Установите интервал и нажмите кнопку «Пуск». Когда Free Timer завершит обратный отсчет, выбранная вами музыка начнет воспроизводиться и таймер остановится.

Вы можете выбрать, какую музыку или звук воспроизводить и сколько раз она будет повторяться. Вы можете изменить цвет секции обратного отсчета, а также вы можете изменить цвет фона с белого на черный (отрицательный).

Во весь экран

Free Timer имеет специальную кнопку для полноэкранного режима. Нажмите эту кнопку, и таймер увеличится до размеров монитора или проектора. Это особенно удобно во время экзаменов, тестов, отчетов, лабораторных экспериментов и так далее. Таймер будет виден из любой части классной комнаты или аудитории. Чтобы выйти из полноэкранного режима, нажмите кнопку Esc или нажмите на экран.

Предварительное уведомление

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

Бесплатный таймер обратного отсчета может воспроизводить музыкальные файлы

Вы можете выбрать звук, который вы хотите для таймера. Free Timer поставляется с несколькими звуками и предлагает полный доступ к вашей музыкальной библиотеке.

Запустите его с вашего портативного USB-накопителя

Вы можете сохранить Free Timer на флеш-накопителе и запустить его прямо оттуда. Таким образом, все ваши таймеры всегда будут с вами, настройки будут сохранены в файле Data.ini.
Скачать: Free Timer Portable.
Просто распакуйте его в любую папку, где вы хотите его сохранить, и запустите FreeTimer.exe, чтобы запустить программу.

Вам нужно больше информации? Взгляните на страницу помощи: Справка онлайн.

Скачать Бесплатный таймер

Версия: 4.0
Дата выпуска: 14.01.2016
Поддерживаемые операционные системы:
Microsoft Windows 10/8.1/8/7/Vista/XP

При поддержке

Hot Alarm Clock позволит вам установить любой интервал времени для обратного отсчета, включая месяцы или годы. Вы также можете создавать цепочки таймеров, а встроенный метроном уведомит вас о приближающемся конце обратного отсчета.

Будильники и таймеры обратного отсчета, секундомеры и список дел, напоминания о днях рождения и многое другое.

Рейтинг
( Пока оценок нет )
Загрузка ...
Adblock
detector