класс Timer – управление внутренними таймерами

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

Каждый таймер состоит из счётчика, который ведёт счёт вверх с определённой скоростью. Скорость счёта равна тактовой частоте периферийного устройства (в Гц), делённой на предделитель таймера. Когда счётчик достигает периода таймера, он генерирует событие и сбрасывается обратно в ноль. С помощью метода callback событие таймера может вызывать функцию Python.

Пример использования для переключения светодиода с фиксированной частотой:

tim = pyb.Timer(4)              # create a timer object using timer 4
tim.init(freq=2)                # trigger at 2Hz
tim.callback(lambda t:pyb.LED(1).toggle())

Пример с использованием именованной функции для функции обратного вызова:

def tick(timer):                # we will receive the timer object when being called
    print(timer.counter())      # show current timer's counter value
tim = pyb.Timer(4, freq=1)      # create a timer object using timer 4 - trigger at 1Hz
tim.callback(tick)              # set the callback to our tick function

Дополнительные примеры:

tim = pyb.Timer(4, freq=100)    # freq in Hz
tim = pyb.Timer(4, prescaler=0, period=99)
tim.counter()                   # get counter (can also set)
tim.prescaler(2)                # set prescaler (can also get)
tim.period(199)                 # set period (can also get)
tim.callback(lambda t: ...)     # set callback for update interrupt (t=tim instance)
tim.callback(None)              # clear callback

Примечание: Timer(1) используется для камеры. Аналогично, Timer(5) управляет драйвером сервопривода, а Timer(6) используется для синхронизированного чтения/записи ADC/DAC. В своих программах рекомендуется использовать остальные таймеры.

Примечание: Память не может быть выделена во время функции обратного вызова (прерывания), поэтому исключения, возникающие внутри функции обратного вызова, не дают много информации. См. micropython.alloc_emergency_exception_buf(), чтобы узнать, как обойти это ограничение.

Конструкторы

class pyb.Timer(id: int, *args, **kwargs)

Создаёт новый объект таймера с заданным id. Если переданы дополнительные аргументы, то таймер инициализируется через init(...). Набор допустимых значений id зависит от микроконтроллера STM32 на используемой OpenMV Cam; обратитесь к справочному руководству STM32 за списком доступных таймеров общего назначения и таймеров расширенного управления.

Методы

init(*, freq: int | float | None = None, prescaler: int | None = None, period: int | None = None, mode: int = Timer.UP, div: int = 1, callback: Callable[[Timer], None] | None = None, deadtime: int = 0, brk: int = Timer.BRK_OFF, hard: bool = True) None

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

tim.init(freq=100)                  # set the timer to trigger at 100Hz
tim.init(prescaler=83, period=999)  # set the prescaler and period directly

Именованные аргументы:

  • freq — задаёт периодическую частоту таймера. Её также можно рассматривать как частоту, с которой таймер проходит один полный цикл.

  • prescaler [0-0xffff] - задаёт значение, загружаемое в регистр предделителя таймера (PSC). Тактовый источник таймера делится на (prescaler + 1) для получения тактовой частоты таймера. Тактовый источник поступает от родительской шины APB таймера и зависит от микроконтроллера. На STM32 таймеры на шине APB1 обычно тактируются на 2 * pclk1, а таймеры на APB2 – на 2 * pclk2; считайте текущие частоты шин с помощью pyb.freq() и обратитесь к справочному руководству STM32 для микроконтроллера вашей OpenMV Cam.

  • period [0-0xffff] для таймеров 1, 3, 4 и 6-15. [0-0x3fffffff] для таймеров 2 и 5. Задаёт значение, загружаемое в регистр автоперезагрузки таймера (ARR). Это определяет период таймера (то есть момент, когда счётчик завершает цикл). Счётчик таймера переполнится после period + 1 тактов таймера.

  • mode может быть одним из:

    • Timer.UP - настраивает таймер на счёт от 0 до ARR (по умолчанию)

    • Timer.DOWN - настраивает таймер на счёт от ARR вниз до 0.

    • Timer.CENTER - настраивает таймер на счёт от 0 до ARR и затем обратно вниз до 0.

  • div может быть равен 1, 2 или 4. Делит тактовую частоту таймера для определения тактовой частоты дискретизации, используемой цифровыми фильтрами.

  • callback - как в Timer.callback()

  • deadtime - задаёт величину «мёртвого» или неактивного времени между переключениями на комплементарных каналах (оба канала будут неактивны в течение этого времени). deadtime может быть целым числом от 0 до 1008 со следующими ограничениями: 0-128 с шагом 1, 128-256 с шагом 2, 256-512 с шагом 8 и 512-1008 с шагом 16. deadtime измеряется в тактах source_freq, делённых на div тактов. deadtime доступен только на таймерах 1 и 8.

  • brk - задаёт, используется ли режим отключения (break) для сброса выхода ШИМ при активации входа BRK_IN. Значение этого аргумента определяет, включён ли режим отключения и какова его полярность, и может быть одним из Timer.BRK_OFF, Timer.BRK_LOW или Timer.BRK_HIGH. Чтобы выбрать вывод BRK_IN, создайте объект Pin с mode=Pin.ALT, alt=Pin.AFn_TIMx. Функции GPIO-входа вывода доступны в альтернативном режиме - pull=, value() и irq().

  • hard может быть одним из:

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

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

    Значение этого параметра по умолчанию равно True.

Необходимо указать либо freq, либо одновременно period и prescaler.

deinit() None

Деинициализирует таймер.

Отключает функцию обратного вызова (и связанное прерывание irq).

Отключает все функции обратного вызова каналов (и связанные прерывания irq). Останавливает таймер и отключает периферийное устройство таймера.

callback(fun: Callable[[Timer], None] | None) None

Задаёт функцию, вызываемую при срабатывании таймера. fun передаётся 1 аргумент - объект таймера. Если fun равно None, то функция обратного вызова будет отключена.

channel(channel: int, mode: int | None = None, *args, **kwargs) TimerChannel | None

Если передан только номер канала, то возвращается ранее инициализированный объект канала (или None, если предыдущего канала нет).

В противном случае инициализируется и возвращается объект TimerChannel.

Каждый канал может быть настроен для выполнения ШИМ, сравнения выхода или захвата входа. Все каналы используют один и тот же базовый таймер, что означает, что они используют одну и ту же тактовую частоту таймера.

Именованные аргументы:

  • mode может быть одним из:

    • Timer.PWM — настраивает таймер в режим ШИМ (активный высокий уровень).

    • Timer.PWM_INVERTED — настраивает таймер в режим ШИМ (активный низкий уровень).

    • Timer.OC_TIMING — указывает, что ни один вывод не управляется.

    • Timer.OC_ACTIVE — вывод становится активным при совпадении сравнения (активность определяется полярностью)

    • Timer.OC_INACTIVE — вывод становится неактивным при совпадении сравнения.

    • Timer.OC_TOGGLE — вывод переключается при совпадении сравнения.

    • Timer.OC_FORCED_ACTIVE — вывод принудительно активен (совпадение сравнения игнорируется).

    • Timer.OC_FORCED_INACTIVE — вывод принудительно неактивен (совпадение сравнения игнорируется).

    • Timer.IC — настраивает таймер в режим захвата входа.

    • Timer.ENC_A — настраивает таймер в режим энкодера. Счётчик изменяется только при изменении CH1.

    • Timer.ENC_B — настраивает таймер в режим энкодера. Счётчик изменяется только при изменении CH2.

    • Timer.ENC_AB — настраивает таймер в режим энкодера. Счётчик изменяется при изменении CH1 или CH2.

  • callback - как в TimerChannel.callback()

  • pin None (по умолчанию) или объект Pin. Если указан (и не None), это приведёт к настройке альтернативной функции указанного вывода для данного канала таймера. Будет возбуждена ошибка, если вывод не поддерживает никаких альтернативных функций для данного канала таймера.

Именованные аргументы для режимов Timer.PWM:

  • pulse_width - определяет начальное значение ширины импульса.

  • pulse_width_percent - определяет начальное процентное значение ширины импульса.

Именованные аргументы для режимов Timer.OC:

  • compare - определяет начальное значение регистра сравнения.

  • polarity может быть одним из:

    • Timer.HIGH - выход активен по высокому уровню

    • Timer.LOW - выход активен по низкому уровню

Необязательные именованные аргументы для режимов Timer.IC:

  • polarity может быть одним из:

    • Timer.RISING - захват по нарастающему фронту.

    • Timer.FALLING - захват по спадающему фронту.

    • Timer.BOTH - захват по обоим фронтам.

Обратите внимание, что захват работает только на основном канале, а не на комплементарных каналах.

Примечания для режимов Timer.ENC:

  • Требует 2 вывода, поэтому один или оба вывода необходимо будет настроить на использование соответствующей альтернативной функции таймера AF с помощью API Pin.

  • Считывайте значение энкодера с помощью метода timer.counter().

  • Работает только на CH1 и CH2 (а не на CH1N или CH2N)

  • Номер канала игнорируется при установке режима энкодера.

Пример ШИМ – на каждой OpenMV Cam на базе STM32 каналы 1 и 2 TIM4 направлены на выводы разъёма P7 и P8 соответственно:

timer = pyb.Timer(4, freq=1000)
ch1 = timer.channel(1, pyb.Timer.PWM, pin=pyb.Pin.board.P7,
                    pulse_width=8000)
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.P8,
                    pulse_width=16000)
counter(value: int | None = None) int | None

Получает или устанавливает значение счётчика таймера.

freq(value: int | float | None = None) int | float | None

Получает или устанавливает частоту таймера (при установке изменяет предделитель и период).

period(value: int | None = None) int | None

Получает или устанавливает период таймера.

prescaler(value: int | None = None) int | None

Получает или устанавливает предделитель таймера.

source_freq() int

Получает частоту источника таймера.

Константы

Константы режима счёта (аргумент mode метода init()):

UP: int

Счёт от 0 вверх до ARR (режим по умолчанию).

DOWN: int

Счёт от ARR вниз до 0.

CENTER: int

Счёт от 0 вверх до ARR и затем обратно вниз до 0.

Константы режима отключения (аргумент brk метода init()):

BRK_OFF: int

Вход отключения деактивирован.

BRK_LOW: int

Вход отключения активен по низкому уровню.

BRK_HIGH: int

Вход отключения активен по высокому уровню.

Константы режима канала (аргумент mode метода channel()):

PWM: int

Настраивает канал на вывод ШИМ (активный высокий уровень).

PWM_INVERTED: int

Настраивает канал на вывод ШИМ (активный низкий уровень).

OC_TIMING: int

Режим временной диаграммы сравнения выхода; ни один вывод не управляется.

OC_ACTIVE: int

Активный режим сравнения выхода; вывод становится активным при совпадении сравнения.

OC_INACTIVE: int

Неактивный режим сравнения выхода; вывод становится неактивным при совпадении сравнения.

OC_TOGGLE: int

Режим переключения сравнения выхода; вывод переключается при совпадении сравнения.

OC_FORCED_ACTIVE: int

Режим принудительной активности сравнения выхода; вывод принудительно активен, а совпадение сравнения игнорируется.

OC_FORCED_INACTIVE: int

Режим принудительной неактивности сравнения выхода; вывод принудительно неактивен, а совпадение сравнения игнорируется.

IC: int

Настраивает канал на режим захвата входа.

ENC_A: int

Режим энкодера: счётчик изменяется только при изменении CH1.

ENC_B: int

Режим энкодера: счётчик изменяется только при изменении CH2.

ENC_AB: int

Режим энкодера: счётчик изменяется при любом изменении CH1 или CH2.

Полярность сравнения выхода (аргумент polarity метода channel() в режимах OC):

HIGH: int

Выход активен по высокому уровню.

LOW: int

Выход активен по низкому уровню.

Полярность захвата входа (аргумент polarity метода channel() в режиме IC):

RISING: int

Захват по нарастающему фронту.

FALLING: int

Захват по спадающему фронту.

BOTH: int

Захват по любому фронту.