Files
espressif--esp-idf/examples/system/esp_timer/main/esp_timer_example_main.c
T
2026-07-13 13:04:25 +08:00

155 lines
6.2 KiB
C

/* esp_timer (high resolution timer) example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "esp_timer.h"
#include "esp_log.h"
#if SOC_LIGHT_SLEEP_SUPPORTED
#include "esp_sleep.h"
#endif
#include "sdkconfig.h"
static void periodic_timer_callback(void* arg);
static void timed_periodic_timer_callback(void* arg);
static void oneshot_timer_callback(void* arg);
static void timed_oneshot_timer_callback(void* arg);
static const char* TAG = "example";
void app_main(void)
{
/* Create four timers:
* 1. a periodic timer which will run every 0.5s, and print a message
* 2. a periodic timer which will run every 0.5s, starting 3.05s from now
* using an absolute timestamp, and print a message
* 3. a one-shot timer which will fire after 5.1s, and re-start periodic
* timer 1 with period of 1s.
* 4. a one-shot timer which will fire 6s from now using an absolute
* timestamp, and re-start periodic timer 2 with period of 1s, firing
* for the first time 1s later.
*/
const esp_timer_create_args_t periodic_timer_args = {
.callback = &periodic_timer_callback,
/* name is optional, but may help identify the timer when debugging */
.name = "periodic"
};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
/* The timer has been created but is not running yet */
const esp_timer_create_args_t timed_periodic_timer_args = {
.callback = &timed_periodic_timer_callback,
.name = "timed_periodic"
};
esp_timer_handle_t timed_periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&timed_periodic_timer_args, &timed_periodic_timer));
const esp_timer_create_args_t oneshot_timer_args = {
.callback = &oneshot_timer_callback,
/* argument specified here will be passed to timer callback function */
.arg = (void*) periodic_timer,
.name = "one-shot"
};
esp_timer_handle_t oneshot_timer;
ESP_ERROR_CHECK(esp_timer_create(&oneshot_timer_args, &oneshot_timer));
const esp_timer_create_args_t timed_oneshot_timer_args = {
.callback = &timed_oneshot_timer_callback,
.arg = (void*) timed_periodic_timer,
.name = "timed_one-shot"
};
esp_timer_handle_t timed_oneshot_timer;
ESP_ERROR_CHECK(esp_timer_create(&timed_oneshot_timer_args, &timed_oneshot_timer));
/* Start the timers */
int64_t start_time = esp_timer_get_time();
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 500000));
/* Keep callback times staggered so logging/restart work in one callback
* does not delay another callback and make the example test flaky.
*/
ESP_ERROR_CHECK(esp_timer_start_periodic_at(timed_periodic_timer, 500000, start_time + 3050000));
ESP_ERROR_CHECK(esp_timer_start_once(oneshot_timer, 5100000));
ESP_ERROR_CHECK(esp_timer_start_once_at(timed_oneshot_timer, start_time + 6000000));
ESP_LOGI(TAG, "Started timers, time since boot: %lld us", esp_timer_get_time());
/* Print debugging information about timers to console every 2 seconds */
for (int i = 0; i < 5; ++i) {
ESP_ERROR_CHECK(esp_timer_dump(stdout));
usleep(2000000);
}
#if SOC_LIGHT_SLEEP_SUPPORTED
/* Timekeeping continues in light sleep, and timers are scheduled
* correctly after light sleep.
*/
int64_t t1 = esp_timer_get_time();
ESP_LOGI(TAG, "Entering light sleep for 0.5s, time since boot: %lld us", t1);
ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(500000));
esp_light_sleep_start();
int64_t t2 = esp_timer_get_time();
ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", t2);
assert(((t2 - t1 - 500000) < 1000) && ((t2 - t1 - 500000) > -2000));
#endif
/* Let the timer run for a little bit more */
usleep(2000000);
/* Clean up and finish the example */
ESP_ERROR_CHECK(esp_timer_stop(periodic_timer));
ESP_ERROR_CHECK(esp_timer_stop(timed_periodic_timer));
ESP_ERROR_CHECK(esp_timer_delete(periodic_timer));
ESP_ERROR_CHECK(esp_timer_delete(timed_periodic_timer));
ESP_ERROR_CHECK(esp_timer_delete(oneshot_timer));
ESP_ERROR_CHECK(esp_timer_delete(timed_oneshot_timer));
ESP_LOGI(TAG, "Stopped and deleted timers");
}
static void periodic_timer_callback(void* arg)
{
int64_t time_since_boot = esp_timer_get_time();
ESP_LOGI(TAG, "Periodic timer called, time since boot: %lld us", time_since_boot);
}
static void timed_periodic_timer_callback(void* arg)
{
int64_t time_since_boot = esp_timer_get_time();
ESP_LOGI(TAG, "Timed periodic timer called, time since boot: %lld us", time_since_boot);
}
static void oneshot_timer_callback(void* arg)
{
int64_t time_since_boot = esp_timer_get_time();
ESP_LOGI(TAG, "One-shot timer called, time since boot: %lld us", time_since_boot);
esp_timer_handle_t periodic_timer_handle = (esp_timer_handle_t) arg;
/* To start the timer which is running, need to stop it first */
ESP_ERROR_CHECK(esp_timer_stop(periodic_timer_handle));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer_handle, 1000000));
time_since_boot = esp_timer_get_time();
ESP_LOGI(TAG, "Restarted periodic timer with 1s period, time since boot: %lld us",
time_since_boot);
}
static void timed_oneshot_timer_callback(void* arg)
{
int64_t time_since_boot = esp_timer_get_time();
ESP_LOGI(TAG, "Timed one-shot timer called, time since boot: %lld us", time_since_boot);
esp_timer_handle_t timed_periodic_timer_handle = (esp_timer_handle_t) arg;
/* To start the timer which is running, need to stop it first */
ESP_ERROR_CHECK(esp_timer_restart_at(timed_periodic_timer_handle, 1000000, time_since_boot + 1000000));
time_since_boot = esp_timer_get_time();
ESP_LOGI(TAG, "Restarted timed periodic timer with 1s period, time since boot: %lld us",
time_since_boot);
}