В данной статье, мы постараемся по возможности просто объяснить работу библиотеки TimerOne, на примере зажигания светодиода привязанного к пину 13.

        Как многие уже знают, привязка светодиода к 13-му пину реализована на большинстве плат Arduino. При программировании плат Arduino, бывает так, что в задачу программиста, входит реализация выполнения каких либо операций с определённой частотой по времени. Причем эти операции должны выполняться независимо от операций содержащихся в теле основной функции loop(). Здесь, в помощь программисту и приходит функционал библиотеки TimerOne. Скачать библиотеку, можно конечно же с Github.

        Эта библиотека позволяет работать с одним из аппаратных таймеров микроконтроллеров AtMega328P-PU, именно эти микроконтроллеры и являются сердцем плат Arduino. Всего в микроконтроллере AtMega328P-PU, есть три таймера, Timer0, Timer1, Timer2. И описываемая библиотека работает именно с Timer1.

        Итак, не будем особо терзать читателя техническими терминами и описанием этих терминов, просто перейдём сразу к примеру, наверное так будет понятнее. Все те, кто когда то начинал свои экcперименты с платой Arduino, конечно же помнят и знают тестовый пример с зажиганием светодиода на 13-м пине платы Arduino. Этот тестовый пример прост и понятен в освоении для программистов любого уровня. Но всё же вы можете еще раз ознакомиться с ним ниже, пример даже прокомментирован, как говорится, повторенье - мать учения...

 

/*Пин к которому привязан светодиод*/
#define LED 13

void setup()
{
  /*Определяем пин как выходной*/
  pinMode(LED, OUTPUT);
}

void loop()
{
  /*
    Тело основной функции
    Комментарии излишни....
  */
  delay(500);
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
}

 

        Здесь, мы думаем, итак всё понятно. Светодиод включается - задержка полсекунды - светодиод выключается - задержка полсекунды, эти операции выполняются в теле основного цикла loop(). Во время выполнения команды delay(), микроконтроллер останавливает свою работу, и не делает ничего, естественно это время теряется впустую, а для микроконтроллера это очень много. За это время можно было бы произвести замер температуры, включение/выключение выходов, да и вообще проделать кучу операций с данными в программе. Однако же, при использовании функции delay(), микроконтроллер "замораживает" программу на время указанное в этой функции. Другое дело, если мы используем функционал библиотеки TimerOne, можно адаптировать программу под её функционал. Перепишем наш тестовый пример следующим образом:

 

#include "TimerOne.h"

/*Будем зажигать светодиод на пине 13*/
#define LED 13

/*Перекидной маркер состояния*/
bool ToggleLatch = false;

void setup()
{
  /*Данный пин назначен как выход*/
  pinMode(LED, OUTPUT);
  /*Инициализация таймера - 500 миллисекунд*/
  Timer1.initialize(500000);
  /*Привязываем функцию обработчик - Blinker*/
  Timer1.attachInterrupt(Blinker);
}

void loop()
{
  /*В основном цикле - вечная пауза*/
  while(1);
}

/*Функция обработчик прерывания*/
void Blinker(void)
{
  /*
    Каждый раз меняем статус маркера ToggleLatch
    на противоположный, "перекидываем" его состояние
    из true в false и обратно
  */
  if(ToggleLatch)
    ToggleLatch = false;
  else
    ToggleLatch = true;

  /*Состояние маркера назначаем пину 13*/
  digitalWrite(LED, ToggleLatch);
}

 

        Краткое разъяснение, во втором тестовом примере подключается библиотека TimerOne, и используется её функционал. В результате, мигание светодиодом происходит вообще без функции delay(), и выполняется не в теле функции loop(), а в обработчике аппаратного прерывания TimerOne. Это позволяет реализовать своего рода псевдо многозадачность(параллельную работу). И тогда как в основном цикле loop() у нас вечная пауза, в обработчике аппаратного прерывания идет переключение состояния светодиода на 13-м пине. На этом пока всё, мы надеемся что данная статья была для вас полезной, если есть какие то конструктивные замечания и предложения пишите на адрес Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.