9. Таймеры

У pyboard есть 14 таймеров, каждый из которых является независимым счётчиком, работающим на определённой пользователем частоте. Их можно использовать для запуска функций через определённые промежутки времени. Все 14 таймеров пронумерованы от 1 до 14, но 3-й зарезервирован внутренних нужд, также как 5-й и 6-й используются для сервоприводов и ADC/DAC контроллеров. Старайтесь не использовать эти зарезервированные таймеры.

Давайте создадим таймер:

>>> tim = pyb.Timer(4)

Теперь давайте посмотрим что мы только что создали:

>>> tim
Timer(4)

Pyboard говорит нам, что tim прикреплён к таймеру номер 4, но он ещё не инициализирован. Итак, давайте инициализируем его с частотой 10 Гц (это 10 раз в секунду):

>>> tim.init(freq=10)

Теперь таймер инициализирован и мы можем информацию о нём:

>>> tim
Timer(4, prescaler=255, period=32811, mode=0, div=0)

Из этого следует, что этот таймер настроен на цикличную работу с тактовой частотой в 255 и он будет считать до 32811, после чего он вызывает прерывание, и начинает отчёт снова с 0. Этот набор чисел задаёт частоту вызова прерывания в 10 Гц.

9.1. Счётчик таймера

Так что мы можем сделать с нашим таймером? Самое простое, что можно получить - текущее значение счётчика:

>>> tim.counter()
21504

Этот счётчик будет непрерывно меняться и подсчитывать.

9.2. Таймер с функцией обратного вызова

Следующее что мы можем сделать - это создать функцию обратного вызова для таймера чтобы выполнить её при срабатывании (смотри [switch tutorial](tut-switch) введение в функции обратного вызова):

>>> tim.callback(lambda t:pyb.LED(1).toggle())

Красный светодиод немедленно начнёт мигать с частотой 5 Гц (два переключения необходимы для одного такта “горения” светодиода, так что переключение с частотой 10 Гц означает, что гореть светодиод будет с частотой 5 Гц). Мы можем изменить частоту, повторно инициализировав таймер:

>>> tim.init(freq=20)

Мы можем отключить функцию обратного вызова, передав ей None:

>>> tim.callback(None)

Функция, которую мы передаём в коллбэк-функцию должна принемать 1 аргумент - таймер. Это позволяет нам управлять таймером внутри функции обратного вызова.

Мы можем создать 2 таймера и запустить их независимо друг от друга:

>>> tim4 = pyb.Timer(4, freq=10)
>>> tim7 = pyb.Timer(7, freq=20)
>>> tim4.callback(lambda t: pyb.LED(1).toggle())
>>> tim7.callback(lambda t: pyb.LED(2).toggle())

Так как коллбэк-функции это настоящие аппаратные прерывания - мы можем продолжать использовать pyboard на своё усмотрение при работающих таймерах.

9.3. Создание счётчика микросекунд

Мы можем использовать таймер для создания микросекуного счётчика - это может быть полезно когда вы делаете что-то, что требует точной синхронизации. Для этого мы будем использовать 2 таймера: таймер №2 имеет 32-х разрядный счётчик (так же как и таймер №5, но если мы используем его - не сможем использовать сервомотор).

Мы создадим таймер №2 следующим образом:

>>> micros = pyb.Timer(2, prescaler=83, period=0x3fffffff)

Заданная тактовая частота равна (prescaler) 83, это делает из таймера счётчик с частотой 1 МГц. Это происходит потому что тактовая частота процессора, работающего на частоте 168 МГц, делится на 2 и тогда к заданной частоте прибавляется единица (prescaler+1); всё это даём нам частоту таймера №2: 168МГц/2/(83 + 1) = 1МГц. Период равен огромному числу, так что таймер не скоро вернётся к нулевому значению. В данном случае таймер вернётся к нулю примерно через 17 минут.

Перед тем как использовать этот таймер, его лучше всего сбросить в ноль:

>>> micros.counter(0)

и затем выполнить свой код:

>>> start_micros = micros.counter()

... код ...

>>> end_micros = micros.counter()