Timer
O timer é um periférico responsável por contar tempo, normalmente utiliza o clock do próprio micro-controladador para isso. O timer da pico possui os seguintes usos:
- System timer: Usado para gerar uma base de tempo para outros periféricos.
- Counter: Possibilita a leitura de quanto tempo já se passou (64 bits -> tempo máximo de
846957946
anos!) - Alarm: Possibilita contarmos tempo dado uma base (32bits -> tempo máximo
72
minutos).
A base de tempo da rp2040 é de 1us
e o temporizador possui 4 alarmes e emite uma interrupção separada para cada alarme. Os alarmes correspondem aos 32 bits inferiores do contador de 64 bits, o que significa que eles podem ser disparados no máximo a 2^32 microssegundos no futuro. Isso é equivalente ao período máximo de ~72 minutes
.
High Level APIs
Iremos acessar o timer usando a biblioteca de alto nível da rp2040, existe uma forma de configurar o timer diretamente acessando o periférico, mas ai a fica a cargo do desenvolvedor lidar com uma série de detalhes. Este conjunto de APIs está disponível no sdk
da pico, não precisamos fazer nada para usarmos.
Snippets
Snippets relacionados ao uso do timer via iso das funções diponíveis no high level api.
Tempo absoluto
É possível termos uma base de tempo que é fornecida pelo periférico do Timer, a contagem deste tempo é independente do que está acontecendo com o programa ou com o CORE.
Código:
#include <stdio.h>
#include "pico/stdlib.h"
int main() {
stdio_init_all();
while(1){
uint32_t start_ms = to_ms_since_boot(get_absolute_time());
uint64_t start_us = to_us_since_boot(get_absolute_time());
sleep_ms(100);
}
}
Este trecho mostra como utilizar as funções to_ms_since_boot
e to_us_since_boot
para obter o tempo em milissegundos e microssegundos desde a inicialização do sistema, respectivamente. Utiliza-se get_absolute_time()
para obter o tempo atual. Isso pode ser útil para temporizações precisas e medições de intervalos de tempo no desenvolvimento de aplicações com o Raspberry Pi Pico.
Timer repetitivo
Cria um timer que chama uma função de callback a cada x
Hz. Se a função de callback
retornar true
o timer continua repetindo, caso contrário interrompe e não acontece mais.
Warning
Diferente do GPIO, aqui devemos configurar uma função de callback
para cada timer gerado!
Simulação no wokwi / pico-examples/timer/hello_timer
#include <stdio.h>
#include "pico/stdlib.h"
volatile int g_timer_0 = 0;
bool timer_0_callback(repeating_timer_t *rt) {
g_timer_0 = 1;
return true; // keep repeating
}
int main() {
stdio_init_all();
int timer_0_hz = 5;
repeating_timer_t timer_0;
if (!add_repeating_timer_us(1000000 / timer_0_hz,
timer_0_callback,
NULL,
&timer_0)) {
printf("Failed to add timer\n");
}
while(1){
if(g_timer_0){
printf("Hello timer 0 \n");
g_timer_0 = 0;
}
}
}
Você pode usar:
add_repeating_timer_ms
ouadd_repeating_timer_us
.
Você pode criar mais de um timer, seguindo a mesma estrutura. Lembre de que para cada timer você precisa declarar um novo repearing_timer
e uma nova função de callback
.
Se a função de callback
retornar true
, o timer executa mais uma vez, false
para de executar.
Para cancelar o timer a qualquer momento, use: cancel_repeating_timer(&timer);
Tempo negativo ou positivo:
- Se o atraso for
> 0
, então este é o atraso entre o término do callback anterior e o início do próximo. - Se o atraso for negativo, então a próxima chamada ao callback será exatamente 500ms após o início da chamada ao último callback.
Alarm
O alarm é uma maneira de conseguirmos usar o periférico do timer para gerar um evento não periódico, o alarme é disparado uma única vez.
Warning
Diferente do GPIO, aqui devemos configurar uma função de callback
para cada timer gerado!
#include <stdio.h>
#include "pico/stdlib.h"
volatile bool timer_fired = false;
int64_t alarm_callback(alarm_id_t id, void *user_data) {
timer_fired = true;
// Can return a value here in us to fire in the future
return 0;
}
int main() {
stdio_init_all();
// Call alarm_callback in 300 ms
// usar esse alarm para cancelar
alarm_id_t alarm = add_alarm_in_ms(300, alarm_callback, NULL, false))
if (!alarm) {
printf("Failed to add timer\n");
}
while(1){
if(timer_fired){
timer_fired = 0;
printf("Hello from alarm!");
}
}
}