клас Timer – керування внутрішніми таймерами

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

Кожен таймер складається з лічильника, який рахує з певною швидкістю. Швидкість відліку – це частота тактування периферійного пристрою (у Гц), поділена на попередній подільник таймера. Коли лічильник досягає значення periodу таймера, він генерує подію, і лічильник скидається до нуля. За допомогою методу 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

Ініціалізує таймер. Ініціалізація повинна виконуватися або за частотою (у Гц), або за допомогою попереднього подільника та period:

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 таймера (тобто коли лічильник циклюється). Лічильник таймера перекидатиметься після 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 - визначає, чи використовується режим зупинки для вимкнення виходу PWM, коли стверджується вхід BRK_IN. Значення цього аргументу визначає, чи увімкнена зупинка та яка полярність, і може бути одним із Timer.BRK_OFF, Timer.BRK_LOW або Timer.BRK_HIGH. Щоб вибрати вивід BRK_IN, створіть об’єкт Pin із mode=Pin.ALT, alt=Pin.AFn_TIMx. Функції GPIO входу виводу доступні в режимі alt: pull=, value() і irq().

  • hard може бути одним із:

    • True - Зворотний виклик буде виконано в контексті жорсткого переривання, що мінімізує затримку і джиттер, але підпорядковується обмеженням, описаним у Написання обробників переривань, зокрема неможливості виділяти пам’ять в купі.

    • False - Зворотний виклик буде запланований як м’яке переривання, що дозволяє виділяти пам’ять, але може також вносити затримки збирання сміття і джиттер.

    Значення за замовчуванням цього параметра – True.

Необхідно вказати або freq, або обидва параметри: period і prescaler.

deinit() None

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

Вимикає зворотний виклик (і пов’язане переривання).

Вимикає будь-які зворотні виклики каналів (і пов’язані переривання). Зупиняє таймер і вимикає периферійний пристрій таймера.

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

Встановлює функцію, яка буде викликана при спрацьовуванні таймера. fun отримує 1 аргумент – об’єкт таймера. Якщо fun має значення None, зворотний виклик буде вимкнено.

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

Якщо передається лише номер каналу, повертається попередньо ініціалізований об’єкт каналу (або None, якщо попереднього каналу немає).

Інакше ініціалізується і повертається об’єкт TimerChannel.

Кожен канал може бути налаштований для виконання PWM, порівняння виходу або захоплення входу. Всі канали використовують один і той самий базовий таймер, а отже, мають спільний тактовий сигнал таймера.

Аргументи ключових слів:

  • mode може бути одним із:

    • Timer.PWM — налаштовує таймер в режимі PWM (активний рівень – високий).

    • Timer.PWM_INVERTED — налаштовує таймер в режимі PWM (активний рівень – низький).

    • 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 таймера за допомогою Pin API.

  • Зчитайте значення енкодера за допомогою методу timer.counter().

  • Працює лише з CH1 і CH2 (але не з CH1N або CH2N)

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

Приклад PWM – на кожному STM32 OpenMV Cam канали 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

Отримує або встановлює частоту таймера (змінює prescaler і period при встановленні).

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

Отримує або встановлює period таймера.

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

Отримує або встановлює prescaler таймера.

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 (активний рівень – високий).

PWM_INVERTED: int

Налаштовує канал для виходу PWM (активний рівень – низький).

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

Захоплення по будь-якому фронту.