клас 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#

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