class Timer —— 控制内部定时器

定时器可用于各种各样的任务。目前只实现了最简单的情况:周期性地调用一个函数。

每个定时器都包含一个以特定速率向上计数的计数器。其计数速率为外设时钟频率(单位 Hz)除以定时器预分频系数。当计数器达到定时器周期值时会触发一个事件,随后计数器复位归零。通过 callback 方法,定时器事件可以调用一个 Python 函数。

以固定频率切换 LED 的示例用法:

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 值集合取决于所用 OpenMV Cam 上的 STM32 MCU;请查阅 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

初始化定时器。初始化必须通过频率(单位 Hz)或通过预分频系数与周期来完成:

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 总线,并且 取决于具体 MCU。在 STM32 上,APB1 上的定时器通常以 2 * pclk1 的频率计时,APB2 上的定时器以 2 * pclk2 计时;可用 pyb.freq() 读取当前的总线频率,并查阅你的 OpenMV Cam 所用 MCU 的 STM32 参考手册。

  • period 对于定时器 1、3、4 以及 6-15 的取值范围为 [0-0xffff],对于定时器 2 和 5 的取值范围为 [0-0x3fffffff]。指定要载入定时器自动重装载寄存器(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 取值。deadtimesource_freq 除以 div 后的时钟节拍来度量。deadtime 仅在定时器 1 和 8 上可用。

  • brk - 指定是否使用刹车(break)模式,在 BRK_IN 输入被置位时关断 PWM 的输出。该参数的值决定是否启用刹车以及其极性,可以是 Timer.BRK_OFFTimer.BRK_LOWTimer.BRK_HIGH 之一。要选择 BRK_IN 引脚,请用 mode=Pin.ALT, alt=Pin.AFn_TIMx 构造一个 Pin 对象。在 alt 模式下仍可使用该引脚的 GPIO 输入功能——pull=value()irq()

  • hard 可以是以下之一:

    • True - 回调将在硬中断上下文中执行,这能最大限度地减少延迟和抖动,但会受到 编写中断处理程序 中所述限制的约束,包括无法在堆上分配内存。

    • False - 回调将被调度为软中断,从而允许其分配内存,但也可能引入垃圾回收带来的延迟和抖动。

    此选项的默认值为 True。

你必须指定 freq,或者同时指定 period 和 prescaler。

deinit() None

反初始化定时器。

禁用回调(以及相关的 irq)。

禁用所有通道回调(以及相关的 irq)。停止定时器,并禁用定时器外设。

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

设置定时器触发时要调用的函数。fun 会被传入 1 个参数,即定时器对象。如果 funNone,则回调将被禁用。

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 个引脚,因此需要使用 Pin API 将其中一个或两个引脚配置为使用相应的定时器 AF(复用功能)。

  • 使用 timer.counter() 方法读取编码器的值。

  • 仅在 CH1 和 CH2 上有效(在 CH1N 或 CH2N 上无效)

  • 设置编码器模式时会忽略通道编号。

PWM 示例 —— 在每一款 STM32 OpenMV Cam 上,TIM4 的通道 1 和通道 2 分别连接到排针引脚 P7P8:

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

获取定时器时钟源的频率。

常量

计数模式常量(init()mode 参数):

UP: int

0 向上计数到 ARR(默认模式)。

DOWN: int

从 ARR 递减计数到 0

CENTER: int

0 向上计数到 ARR,然后再递减回到 0

刹车模式常量(init()brk 参数):

BRK_OFF: int

刹车输入被禁用。

BRK_LOW: int

刹车输入为低电平有效。

BRK_HIGH: int

刹车输入为高电平有效。

通道模式常量(channel()mode 参数):

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 任一变化时改变。

输出比较极性(OC 模式下 channel()polarity 参数):

HIGH: int

输出为高电平有效。

LOW: int

输出为低电平有效。

输入捕获极性(IC 模式下 channel()polarity 参数):

RISING: int

在上升沿捕获。

FALLING: int

在下降沿捕获。

BOTH: int

在任一边沿捕获。