classe Timer – controlar temporizadores internos

Os temporizadores podem ser utilizados para uma grande variedade de tarefas. De momento, apenas o caso mais simples está implementado: o de chamar uma função periodicamente.

Cada temporizador consiste num contador que conta de forma crescente a uma determinada taxa. A taxa a que conta é a frequência do clock do periférico (em Hz) dividida pelo prescaler do temporizador. Quando o contador atinge o período do temporizador, desencadeia um evento e o contador repõe-se a zero. Utilizando o método callback, o evento do temporizador pode chamar uma função Python.

Exemplo de utilização para alternar um LED a uma frequência fixa:

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())

Exemplo utilizando uma função com nome para o callback:

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

Outros exemplos:

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

Nota: Timer(1) é utilizado para a câmara. Da mesma forma, Timer(5) controla o driver de servo, e Timer(6) é usado para leitura/escrita temporizada de ADC/DAC. Recomenda-se a utilização dos outros temporizadores nos seus programas.

Nota: Não é possível alocar memória durante um callback (uma interrupção), pelo que as exceções levantadas num callback não fornecem muita informação. Consulte micropython.alloc_emergency_exception_buf() para saber como contornar esta limitação.

Construtores

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

Constrói um novo objeto temporizador com o id fornecido. Se forem fornecidos argumentos adicionais, o temporizador é inicializado por init(...). O conjunto de valores id válidos depende do MCU STM32 presente na OpenMV Cam em uso; consulte o manual de referência do STM32 para os temporizadores de uso geral e de controlo avançado disponíveis.

Métodos

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

Inicializa o temporizador. A inicialização deve ser feita por frequência (em Hz) ou por prescaler e período:

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

Argumentos de palavra-chave:

  • freq — especifica a frequência periódica do temporizador. Pode também interpretar isto como a frequência com que o temporizador completa um ciclo completo.

  • prescaler [0-0xffff] - especifica o valor a carregar no Registo de Prescaler (PSC) do temporizador. A fonte de clock do temporizador é dividida por (prescaler + 1) para obter o clock do temporizador. A fonte de clock provém do barramento APB pai do temporizador e é dependente do MCU. No STM32, os temporizadores no APB1 geralmente funcionam a 2 * pclk1 e os do APB2 a 2 * pclk2; leia as frequências atuais do barramento com pyb.freq() e consulte o manual de referência do STM32 para o MCU da sua OpenMV Cam.

  • period [0-0xffff] para os temporizadores 1, 3, 4 e 6-15. [0-0x3fffffff] para os temporizadores 2 e 5. Especifica o valor a carregar no Registo de AutoRecarga (ARR) do temporizador. Isto determina o período do temporizador (ou seja, quando o contador recicla). O contador do temporizador irá transbordar após period + 1 ciclos de clock do temporizador.

  • mode pode ser um dos seguintes:

    • Timer.UP - configura o temporizador para contar de 0 até ARR (predefinição)

    • Timer.DOWN - configura o temporizador para contar de ARR até 0.

    • Timer.CENTER - configura o temporizador para contar de 0 até ARR e depois de volta até 0.

  • div pode ser 1, 2 ou 4. Divide o clock do temporizador para determinar o clock de amostragem utilizado pelos filtros digitais.

  • callback - como em Timer.callback()

  • deadtime - especifica a quantidade de tempo «morto» ou inativo entre transições em canais complementares (ambos os canais estarão inativos durante este tempo). deadtime pode ser um inteiro entre 0 e 1008, com as seguintes restrições: 0-128 em passos de 1, 128-256 em passos de 2, 256-512 em passos de 8, e 512-1008 em passos de 16. deadtime mede ticks de source_freq dividida pelos ticks de clock de div. deadtime só está disponível nos temporizadores 1 e 8.

  • brk - especifica se o modo de interrupção é utilizado para desativar a saída do PWM quando a entrada BRK_IN é ativada. O valor deste argumento determina se a interrupção está ativada e qual é a polaridade, podendo ser Timer.BRK_OFF, Timer.BRK_LOW ou Timer.BRK_HIGH. Para selecionar o pino BRK_IN, construa um objeto Pin com mode=Pin.ALT, alt=Pin.AFn_TIMx. As características de entrada GPIO do pino estão disponíveis no modo alt - pull=, value() e irq().

  • hard pode ser um dos seguintes:

    • True - O callback será executado em contexto de interrupção hard, o que minimiza o atraso e o jitter, mas está sujeito às limitações descritas em Escrita de tratadores de interrupções, incluindo a incapacidade de alocar na heap.

    • False - O callback será agendado como uma interrupção soft, permitindo a alocação, mas possivelmente introduzindo atrasos de recolha de lixo e jitter.

    O valor predefinido desta opção é True.

Tem de especificar freq ou ambos period e prescaler.

deinit() None

Desinicializa o temporizador.

Desativa o callback (e a irq associada).

Desativa quaisquer callbacks de canal (e as irq associadas). Para o temporizador e desativa o periférico do temporizador.

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

Define a função a chamar quando o temporizador é acionado. fun recebe 1 argumento, o objeto temporizador. Se fun for None, o callback será desativado.

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

Se for passado apenas um número de canal, é devolvido um objeto de canal previamente inicializado (ou None se não existir canal anterior).

Caso contrário, é inicializado e devolvido um objeto TimerChannel.

Cada canal pode ser configurado para executar pwm, comparação de saída ou captura de entrada. Todos os canais partilham o mesmo temporizador subjacente, o que significa que partilham o mesmo clock do temporizador.

Argumentos de palavra-chave:

  • mode pode ser um dos seguintes:

    • Timer.PWM — configura o temporizador no modo PWM (ativo alto).

    • Timer.PWM_INVERTED — configura o temporizador no modo PWM (ativo baixo).

    • Timer.OC_TIMING — indica que nenhum pino é controlado.

    • Timer.OC_ACTIVE — o pino será ativado quando ocorrer uma correspondência de comparação (ativo é determinado pela polaridade)

    • Timer.OC_INACTIVE — o pino será desativado quando ocorrer uma correspondência de comparação.

    • Timer.OC_TOGGLE — o pino será alternado quando ocorrer uma correspondência de comparação.

    • Timer.OC_FORCED_ACTIVE — o pino é forçado ativo (a correspondência de comparação é ignorada).

    • Timer.OC_FORCED_INACTIVE — o pino é forçado inativo (a correspondência de comparação é ignorada).

    • Timer.IC — configura o temporizador no modo de Captura de Entrada.

    • Timer.ENC_A — configura o temporizador no modo Encoder. O contador apenas muda quando CH1 muda.

    • Timer.ENC_B — configura o temporizador no modo Encoder. O contador apenas muda quando CH2 muda.

    • Timer.ENC_AB — configura o temporizador no modo Encoder. O contador muda quando CH1 ou CH2 muda.

  • callback - como em TimerChannel.callback()

  • pin None (a predefinição) ou um objeto Pin. Se especificado (e não None), isto fará com que a função alternativa do pino indicado seja configurada para este canal do temporizador. Será levantado um erro se o pino não suportar quaisquer funções alternativas para este canal do temporizador.

Argumentos de palavra-chave para os modos Timer.PWM:

  • pulse_width - determina o valor inicial da largura de pulso a utilizar.

  • pulse_width_percent - determina a percentagem inicial da largura de pulso a utilizar.

Argumentos de palavra-chave para os modos Timer.OC:

  • compare - determina o valor inicial do registo de comparação.

  • polarity pode ser um dos seguintes:

    • Timer.HIGH - saída ativa alta

    • Timer.LOW - saída ativa baixa

Argumentos de palavra-chave opcionais para os modos Timer.IC:

  • polarity pode ser um dos seguintes:

    • Timer.RISING - captura na flanco ascendente.

    • Timer.FALLING - captura no flanco descendente.

    • Timer.BOTH - captura em ambos os flancos.

Note que a captura só funciona no canal primário, e não nos canais complementares.

Notas para os modos Timer.ENC:

  • Requer 2 pinos, pelo que um ou ambos os pinos terão de ser configurados para usar o AF do temporizador adequado utilizando a API Pin.

  • Leia o valor do encoder utilizando o método timer.counter().

  • Só funciona em CH1 e CH2 (e não em CH1N ou CH2N)

  • O número do canal é ignorado ao definir o modo encoder.

Exemplo de PWM – em todas as OpenMV Cam STM32, os canais 1 e 2 do TIM4 estão ligados aos pinos do conector P7 e P8 respetivamente:

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

Obtém ou define o contador do temporizador.

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

Obtém ou define a frequência do temporizador (altera o prescaler e o período se definido).

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

Obtém ou define o período do temporizador.

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

Obtém ou define o prescaler do temporizador.

source_freq() int

Obtém a frequência da fonte do temporizador.

Constantes

Constantes do modo de contagem (argumento mode de init()):

UP: int

Conta de 0 até ARR (o modo predefinido).

DOWN: int

Conta de ARR até 0.

CENTER: int

Conta de 0 até ARR e depois de volta até 0.

Constantes do modo de interrupção (argumento brk de init()):

BRK_OFF: int

A entrada de interrupção está desativada.

BRK_LOW: int

A entrada de interrupção está ativa-baixa.

BRK_HIGH: int

A entrada de interrupção está ativa-alta.

Constantes de modo de canal (argumento mode de channel()):

PWM: int

Configura o canal para saída PWM (ativo alto).

PWM_INVERTED: int

Configura o canal para saída PWM (ativo baixo).

OC_TIMING: int

Modo de temporização de comparação de saída; nenhum pino é controlado.

OC_ACTIVE: int

Modo ativo de comparação de saída; o pino é ativado na correspondência de comparação.

OC_INACTIVE: int

Modo inativo de comparação de saída; o pino é desativado na correspondência de comparação.

OC_TOGGLE: int

Modo de alternância de comparação de saída; o pino alterna na correspondência de comparação.

OC_FORCED_ACTIVE: int

Modo forçado-ativo de comparação de saída; o pino é forçado ativo e a correspondência de comparação é ignorada.

OC_FORCED_INACTIVE: int

Modo forçado-inativo de comparação de saída; o pino é forçado inativo e a correspondência de comparação é ignorada.

IC: int

Configura o canal para o modo de captura de entrada.

ENC_A: int

Modo encoder: o contador apenas muda quando CH1 muda.

ENC_B: int

Modo encoder: o contador apenas muda quando CH2 muda.

ENC_AB: int

Modo encoder: o contador muda sempre que CH1 ou CH2 mudam.

Polaridade de comparação de saída (argumento polarity de channel() nos modos OC):

HIGH: int

A saída está ativa-alta.

LOW: int

A saída está ativa-baixa.

Polaridade de captura de entrada (argumento polarity de channel() no modo IC):

RISING: int

Captura no flanco ascendente.

FALLING: int

Captura no flanco descendente.

BOTH: int

Captura em qualquer flanco.