Audytor.ru

Теплоснабжение "Аудитор"
3 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Таймер обратного отсчёта на чистом JavaScript

Таймер обратного отсчёта на чистом JavaScript

Александр Мальцев

В этой статье рассмотрим таймер обратного отсчета, построенный на чистом CSS и JavaScript. Он написан с использованием минимального количества кода без использования jQuery и каких-либо других сторонних библиотек.

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

Как вставить элемент «Таймер» в виджет

Разберем, как можно сделать в Convead виджет с таймером обратного отсчета. Выглядеть он может примерно так:

Чтобы реализовать такой таймер, нужно добавить на виджет блок <HTML>:

Теперь в этот блок нужно вставить код в зависимости от того, какой вы хотите таймер. Чаще всего наши клиенты используют один из двух таймеров:

  1. Единый таймер для всех посетителей на несколько дней в течение которых работает какая-то акция. Или «До Нового Года осталось…».
  2. Персональный таймер для каждого посетителя на несколько минут/часов в течение которых он может воспользоваться промокодом.

Ниже приведены коды для обоих вариантов:

HTML-код единого таймера до определенной даты

В коде задается дата, до которой показывается таймер обратного отсчета. Когда дата наступает, высвечивается надпись «Акция завершена». Скопируйте код таймера и вставьте его в HTML блок:

HTML-код уникального таймера для каждого посетителя

Этот таймер будет при каждом открытии начинать отсчитывать 100 секунд. Когда 100 секунд истекут, пользователь увидит надпись «Акция завершена». Скопируйте код таймера и вставьте его в HTML блок:

Не пугайтесь, что вместо счетчика в редакторе вы видите HTML-код. Чтобы увидеть, как выглядит счетчик – воспользуйтесь предпросмотром.

Настройка таймера

Вы можете отредактировать дату и время до которого будет работать виджет, а также подправить размер, цвет и стиль текста. Для этого потребуются базовые знания HTML и твердая рука. Стиль текста, дату и время окончания таймера можно подредактировать в самой верхней части HTML-кода:

Вы можете сделать любой таймер по аналогии с этими примерами. Ограничением тут является только ваша фантазия!

32 комментария

А мне совсем не понравился timegenerator.ru. Кроме задания даты больше ничего делать нельзя. А подключать сторонние плагины уж ооочень муторно. Поискал аналоги, нашел 2-3 сайта покруче таймгенератора. Больше всех впечатлил таймер для сайта e-timer.ru. Настроек куча, то, что мне нужно, советую всем)

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

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

Задержки

Простейшей с точки зрения использования функцией времени является задержка, их у нас две:

    delay(time) – “приостанавливает” выполнение кода на time миллисекунд. Дальше функции delay() выполнение кода не идёт, за исключением прерываний. Использовать рекомендуется только в самых крайних или тех случаях, когда delay не влияет на скорость работы устройства. time принимает тип данных unsigned long и может приостановить выполнение на срок от 1 мс до

Читайте так же:
Счетчик для спутниковых антенн

Задержки использовать очень просто:

И вот мы можем делать какое-то действие два раза в секунду. delayMicroseconds() иногда не совсем корректно работает с переменными, нужно стараться использовать константы ( const или просто число). Для создания микросекундных задержек с переменным периодом и корректной работы в циклах лучше использовать следующую конструкцию:

А что делать, если нам нужно выполнять одно действие два раза в секунду, а другое – три? А третье – 10 раз в секунду например. Сразу привыкаем к той мысли, что задержки лучше вообще не использовать в реальном коде. Разве что delayMicroseconds() , он бывает нужен для генерации каких-то протоколов связи. Нормальным инструментом для тайм-менеджмента своего кода являются функции, которые считают время со старта МК.

Функция yield()

Разработчики Arduino позаботились о том, чтобы функция delay() не просто блокировала выполнение кода, но и позволяла выполнять другой код во время этой задержки. Данный “костыль” получил название yield() и работает следующим образом: если объявить функцию

то расположенный внутри неё код будет выполняться во время работы любой задержки delay() в программе! Это решение хоть и кажется нелепым, но в то же время позволяет быстро и без описания лишних костылей и таймеров реализовать пару параллельно выполняющихся задач. Что вполне соответствует назначению Ардуино – максимально простая и быстрая разработка прототипа. Рассмотрим например такой простой пример: стандартный мигающий светодиод, но с опросом кнопки

Подробнее о том, как работать с yield() и строить программу на её основе мы рассмотрим в одном из следующих уроков о том, как написать скетч.

STM32: Урок 6.2 — Таймеры общего назначения и продвинутые

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

  • До 4-х каналов для:
    • Захвата сигнала (input capture).
    • Сравнения вывода (output compare).
    • Генерации сигнала ШИМ (выровненного по границе или по центру).
    • Генерации одиночных импульсов.
    • Обновление: переполнение счётчика.
    • Событие-триггер: старт, остановка, инициализация счётчика или его обновление внутренним или внешним триггером.
    • Захват сигнала.
    • Сравнение (output compare).
    • Включение BRK.

    Вот как вы думаете, если у таймеров общего назначения так много функций, чем тогда продвинутые (advanced-control) таймеры отличаются от них? o_O
    Правильный ответ — почти ничем, это по факту просто таймеры общего назначения, которые не имеют никаких ограничений: в них напихано по 4 канала (с комплементарными) и есть все возможности сразу, без какого-то ни было разброса. Так что остальная часть статьи будет относиться ко всем таймерам выше базовых, а продвинутые таймеры я отдельно упоминать не буду.

    В даташите на STM32F100xx ( ещё ссылка ) есть сводная таблица возможностей таймеров, в которую тоже удобно поглядывать для справки:

    Кстати, обращайте внимание на сноски. Например, там написано, что у МК семейства Low density Value line нет таймера TIM4.

    Захват сигнала

    В этом режиме с выбранного канала захватываются импульсы, на каждый из них текущее значение счётчика таймера кладётся в регистр TIM_CCRx, где x — номер канала. Таким образом, период следования импульсов равен разнице между текущим значением TIM_CCRx и предыдущим. Ну а для того, чтобы получить период в каких-то внятных единицах измерения, нужно настроить предделитель через функции базового таймера.

    При этом можно настроить генерацию прерывания и запроса DMA на приход очередного импульса, и если в это время предыдущее значение TIM_CCRx не было считано, будет сгенерировано так называемое прерывание over-capture, т.е. сигнал о том, что предыдущее значение потерялось.

    Ловить можно фронты, спады или и то, и другое вместе. Есть настройка так называемого фильтра — числа выборок, после которого переход уровня будет считаться состоявшимся (полезно для устранения дребезга). Значение фильтра может принимать значения от 0 (фильтр выключен) до 15 (0xF). Также настраивается делитель входной частоты — 2, 4 или 8: будет ловиться каждый 2й, 4й или 8й импульс соответственно.

    Примера ради подёргаем вывод PB15 и замерим таймером TIM3 период, подключив PB15 к его каналу 1 (PA6):

    Также существует режим захвата ШИМ. На самом деле, это не отдельный режим, а просто особое сочетание настроек с таким эффектом. Таймер настраивается так, чтобы один канал ловил фронты и сбрасывал счётчик таймера, а второй ловил спады — тогда первый будет захватывать период ШИМ, а второй — заполнение. При этом оба канала подключаются к одному и тому же физическому входу. Суть работы этого «режима» показана в даташите следующим образом:

    Изменим предыдущий пример, используя захват ШИМ (прокомментированы только изменения):

    Режим чтения энкодера

    Работу с энкодером я уже как-то описывал , и тогда я считывал и декодировал данные с энкодера программно, здесь же таймер сделает работу за нас (не всю, конечно же). Боковые выводы энкодера надо подключить к двум каналам таймера, а средний вывод — к GND. Таймер в этом режиме сам обрабатывает поступающие с энкодера импульсы, а также увеличивает/уменьшает свой счётчик на 4 при каждом щелчке энкодера, и запоминает направление вращения.

    Так как мне захотелось ещё и прерывание заиметь, я сделал период равным 4 и разрешил счёт в обе стороны, так что теперь прерывание будет возникать при каждом щелчке энкодера. Использовал я каналы 1 и 2 таймера TIM3 (PA6 и PA7):

    Сравнение вывода (output compare)

    В этом режиме выбранный канал таймера будет подключен к соответствующему выводу и будет изменять его (вывода) состояние каждый раз, когда счётчик таймера досчитает до значения регистра TIM_CCRx. Состояние вывода, в зависимости от настройки, будет меняться на ноль, на единицу или на противоположное текущему. У многих таймеров у каналов есть комплементарные выводы, которые по умолчанию являются инверсными: на такой выход подаётся тот же сигнал, что и на обычный, но с противоположным уровнем.

    Смотрим в сводную таблицу по таймерам в даташите и видим, что комплементарных выводов у TIM3 нет, но вот у единственного канала таймера TIM16 есть такой вывод — этот таймер я и использую для примера. Вообще, комплементарные выводы есть и у нескольких других таймеров, но вот TIM15 — особенный: у него есть два канала, но комплементарный вывод имеет только 1й канал. Будьте бдительны!

    В таблице пинаутов находим выводы канала 1 таймера TIM16 — PB8 (основной) и PB6 (комплементарный). Для иллюстрации работы таймера подключим эти выводы к светодиодам на плате STM32VLDiscovery — PC8 и PC9, которые в коде мы отключим от греха подальше. Таким образом, выводы канала таймера будут напрямую мигать светодиодами:

    В это примере я выбрал режим переключения вывода в противоположное состояние (TIM_OCMode_Toggle), а остальные настройки оставил по умолчанию. Кстати, не забывайте вызывать функции типа TIM_OCStructInit() для инициализации соответствующих структур, даже если заполняете все поля структур вручную: copy&paste-ориентированное программирование никто не отменял, но при нём легко забыть заполнить какое-нибудь поле и ловить потом баги.

    Для обоих выводов канала можно настроить (поля TIM_OCPolarity и TIM_OCNPolarity структуры) так называемую «полярность» — состояние вывода в промежуток времени от начала отсчёта и до TIM_Pulse. По умолчанию для выводов выставляются значения TIM_OCPolarity_High и TIM_OCNPolarity_High, но комплементарный вывод является инверсным — поэтому, если на нём нужен обычный (не инверсный) сигнал, нужно ему выставить TIM_OCNPolarity_Low.

    В режиме сравнения генерируется то же самое прерывание, что и в режиме захвата сигнала — TIM_IT_CCx, но здесь оно было не нужно, поэтому я его не разрешал.

    Генерация ШИМ

    Вот это куда более интересная и практичная штука. Принципы ШИМ уже неоднократно были описаны — как на нашем сайте , так и у Di Halt’a (уж там разжёвано всё до мелочей), а я сосредоточусь на особенностях реализации в STM32.

    Настройка этого режима не слишком отличается от настройки output compare: вместо режима TIM_OCMode_Toggle нужно выбрать один из режимов ШИМ, тогда TIM_Period будет трактоваться как период ШИМ, а поле TIM_Pulse — как заполнение (duty cycle). Режимов ШИМ имеется два — выровненный по границе и по центру (edge-aligned и center-aligned). У микроконтроллеров AVR они называются Fast PWM и Phase Correct PWM, соответственно.

    Отличной иллюстрацией крутизны таймеров STM32 для генерации ШИМ будет типичная прикладная задача — управление сервомашинкой : Как известно, сервы управляются импульсами переменной ширины, которые шлются с частотой примерно 50 Гц (каждые 20 мс). У сервы, которая оказалась под рукой (Robbe 4.3 g), ширина управляющего импульса от 500 мкс (0°) до 2250 мкс (175°), судя по замерам — то есть, по 10 мкс на каждый градус поворота:

    ΔT = T₂ — T₁ = 2250 — 500 = 1750 мкс
    ∠A = 175°
    ΔT/A = 10 мкс/°

    1. Установить таймеру такой делитель частоты, чтобы отсчёт вёлся каждые 10 мкс.
    2. Задать период ШИМ в 20 мс, то есть 2000 отрезков времени по 10 мкс.
    3. Класть в регистр сравнения число, равное 50 (500 мкс / 10 мкс) + задаваемый угол.
    4. Регистр сравнения лучше обновлять строго в момент окончания периода во избежание дёргания сервы.

    Dead-time

    Если кто не знает, это задержка фронтов сигналов на основном и комплементарном выводах канала таймера. Эта функция есть у некоторых таймеров (смотрите руководство), и нужна она бывает для исключения сквозных токов при управлении силовыми ключами [полу]мостовых схем. Даже не спрашивайте меня, что это такое — это вне моей компетенции.

    Настраивается этот самый dead-time в поле TIM_DeadTime структуры TIM_BDTRInitTypeDef и имеет диапазон значений с 0 по 255 (0xFF). Но смысл этого числа не так уж прямолинеен:

    Ага, вот так оно и рассчитывается. Здесь Tdts — это длительность такта генератора dead-time (DTG), зависящая от Tdts — текущей частоты тактирования таймера. Обычно таймеры тактируются системной частотой, и TIM_Prescaler на это никак не влияет, а влияет поле TIM_ClockDivision структуры TIM_TimeBaseInitTypeDef — делитель частоты таймера.

    Для примера положим, что таймер затактирован без деления частоты (делитель равен 1, TIM_CKD_DIV1), системная частота F равна 24 МГц, а значение DTG = 150. Тогда:

    Tdts = 1/F = 1/24 мкс
    DTG = 150 = 100101102 ⇒ DTG[7:5] = 1002
    Tdtg = 2⋅Tdts = 1/12 мкс
    DT = (64 + DTG[5:0])Tdtg = (64 + 6)/12 = 5.8(3) мкс

    «Just like that» ☯ ChosunNinja

    Я тут для примера набросал код с dead-time попроще для расчёта: DTG=96 ⇒ DT=96.

    Для того, чтобы узреть этот самый dead-time на одноканальном осциллографе, нужно подключить PB8 и PB6 через резисторы 1 кОм к его щупу:

    Т.к. на эти выводы идут взаимно инверсные сигналы, на экране будут прекрасно видны места, где во время dead-time уровень на обоих входах одинаков из-за задержки фронтов:

    Ну, и напоследок — имейте ввиду, что если длительность dead-time превышает длительность импульса на выводе, то соответствующий импульс не будет сгенерирован вообще.

    Счётчик повторений

    Этот счётчик имеется у нескольких таймеров (TIM15, TIM16 и TIM17) и выполняет он очень простую функцию: генерировать событие (прерывание или запрос DMA) update не на каждое переполнение счётчика, а на каждые N переполнений. То есть, вы задаёте счётчик повторений, таймер его копирует в скрытый регистр и при каждом переполнении уменьшает значение копии на 1. Когда значение достигает нуля, генерируется событие update, таймер снова копирует счётчик повторений и т.д. На самом деле, перечисленные таймеры и так задействуют этот счётчик, просто по умолчанию его значение равно нулю, и событие генерируется на каждое переполнение.

    Счётчик может принимать значения от 0 до 255 (0xFF). Описывать тут особо нечего, потому что для использования этой функции достаточно при инициализации таймера написать что-то вроде:

    и всё. В этом случае событие update будет генерироваться каждые 8 переполнений (7 повторений).

    Вход BRK

    Если вам вдруг понадобится резко перевести выводы каналов таймера в заранее определённое состояние (например, выключить), то эта функция — то, что нужно. Включить её проще пареной репы — нужно сконфигурировать пин TIMx_BKIN на вход, и при инициализации BDTR включить вход BRK:

    По умолчанию для активации функции break нужно на вход BRK подать логический ноль, но это можно настроить в поле TIM_BreakPolarity. Как только break активирован, все выводы каналов переходят в состояние, которое задаётся при их инициализации полями TIM_OCIdleState и TIM_OCNIdleState в структуре TIM_OCInitTypeDef (по умолчанию на выводах будет низкий уровень). Dead-time при этом учитывается.

    Синхронизация таймеров

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

    Второй случай (цепочка таймеров) больше подойдёт для иллюстрации, ибо интереснее он. Сделаем-ка для примера 32-битный таймер из двух обычных 16-битных. Для примера я возьму таймеры TIM2 и TIM3. Задача состоит в том, таймер TIM3 тактировал таймер TIM2 по переполнению своего счётчика: то есть, счётчик таймера TIM2 будет увеличиваться при переполнении счётчика TIM3 — получаем 32-битный счётчик, «состоящий» из TIM2_CNT (старшие биты) и TIM3_CNT (младшие).

    Для этого нужно настроить выходной триггер таймера TIM3 на переполнение (update), а входной триггер таймера TIM2 — на вход с триггера TIM3. Смотрим в таблицу соединения триггеров для таймеров TIM2-TIM4 (таких таблиц несколько — для разных групп таймеров):

    Здесь мы видим, что TIM3 соединён с входом ITR2 таймера TIM2. И тут выясняется, что в Reference manual рассматриваемый случай описан в разделе «Using one timer as prescaler for another», но там допущена ошибка: вместо ITR2 там указан ITR1. Я джва года час искал ошибку в коде!

    Таймер обратного отсчёта на основе JavaScript

    Этот метод хоть и требует определённого знания хотя бы HTMLи CSS, зато имеет максимум возможностей для настройки. Изменяя код htmlи настраивая стили css, можно легко подогнать данный счётчик под любой дизайн.

    Скопируйте архив с моего Яндекс.Диска и распакуйте архив на своём компьютере. Скачать архив .

    В архиве у вас будет 4 файла:

    Список файлов

    counter.html – собственно html каркас счётчика

    jquery.downCount.js – скрипт обратного отсчёта

    style.css – стили оформления

    time.png – изображения для счётчика

    Все необходимые изменения вы будете делать именно в этих файлах.

    Прежде чем приступить к установке счётчика, необходимо установить дату намеченного события. Дата должна быть в будущем времени, иначе счётчик не будет отображаться. Помните это, на случай если счётчик не отображается на экране.

    Установка даты осуществляется в файле counter.html . Необходимо просто изменить дату и время. Все необходимые подсказки в файле присутствуют.

    Установка даты

    Теперь необходимо скопировать всю папку с этими файлами на ваш сервер. Делайте это любым удобным для вас способом. Если у вас блог под управлением WordPress, загрузите папку в папку Вашей темы:

    В том месте, где необходимо отобразить таймер обратного отсчёта, нужно вставить вот такой код:

    Только учтите, делается вставка в редакторе кода. То есть вставляете код в html код той страницы, где нужно вывести таймер.

    Вставка кода

    Так будет выглядеть таймер:

    Таймер номер один

    Таймер номер один

    А вот и видеоурок «Как вставить таймер обратного отсчёта на сайт»

    5 последних уроков рубрики «WordPress»

    Почему WordPress лучше чем Joomla ?

    Этот урок скорее всего будет психологическим, т.к. многие люди работают с WordPress и одновременно с Joomla, но не могут решится каким CMS пользоваться.

    Про шаблоны WordPress

    После установки и настройки движка нам нужно поработать с дизайном нашего сайта. Это довольно долгая тема, но мы постараемся рассказать всё кратко и ясно.

    Самые первые настройки после установки движка WordPress

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

    10 стратегий эффективного продвижения статей в блогах на WordPress

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

    Топ WordPress альтернатив для создания персонального сайта

    Нужен персональный сайт, но вы не хотите задействовать WordPress? Тогда данная подборка для вас.

    голоса
    Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector