【ESP32-IDF】基础外设开发5:定时器
本文详细介绍了ESP32的定时器功能及其开发应用。ESP32内置4个64位硬件定时器,分为2组(TIMERG0/TIMERG1),每组含2个定时器。定时器具有16位预分频器(分频比2-65536)、64位计数器、自动重载和中断触发功能,支持精确的时间控制和周期性任务。定时器核心功能包括预分频调节、计数器方向控制(上/下计数)、报警触发、中断管理(电平/边沿触发)以及自动重载机制。开发时建议优先使用
系列文章目录
持续更新…
前言
在嵌入式开发中,定时器是实现精确控制和任务调度的关键组件。ESP32 作为一款功能强大的微控制器,内建了多个高精度的硬件定时器,广泛应用于定时任务、周期性中断、PWM 输出、看门狗监控等场景。
本篇文章将深入介绍 ESP32 的定时器模块,涵盖其硬件架构、功能特性、配置方法以及实际应用示例。我们将重点讲解如何利用 ESP32 的 64 位定时器实现精确的时间控制,并通过中断机制响应特定事件。
参考文档:ESP32-S3技术参考手册;ESP32-S3编程指南
一、定时器概述
ESP32 提供了强大的硬件定时器功能,能够为嵌入式系统提供精准的定时控制。ESP32 内置了 4 个 64 位通用定时器,分为 2 组,每组包含 2 个定时器。每个定时器都包括一个 16 位的时钟预分频器和一个 64 位的时基计数器。定时器可用于设定时间间隔、触发中断、产生报警等功能,广泛应用于定时任务、周期性任务等。
定时器组结构
ESP32 定时器分为两个定时器组:定时器组 0(TIMERG0)和定时器组 1(TIMERG1)。每个定时器组内包含两个通用定时器,分别标识为 TIMGn_Tx,其中 n 表示定时器组编号(0 或 1),x 表示定时器编号(0 或 1)。定时器可用于多种任务,包括精确时间控制、周期性报警、中断触发等。

定时器特性:
1.16 位预分频器:能够对时钟源进行 2 到 65536 之间的分频。
2.64 位时基计数器:可配置为向上计数或向下计数,支持高精度定时。
3.自动重载:定时器可以在触发报警时自动重新加载初始值。
4.报警功能:定时器可以在当前计数值达到报警值时触发报警,支持定时中断。
5.软件控制:可以通过软件即时重新加载计数器的值。
6.中断支持:支持电平触发中断和边沿触发中断,适合用于定时任务管理。
每个定时器的工作原理包括以下几个部分:
1.16位预分频器
定时器的预分频器用于将输入的时钟信号进行分频,以产生适合的时基时钟(TB_CLK)供时基计数器使用。ESP32 的定时器支持配置分频系数,范围从 2 到 65536,可以对 APB 时钟(通常为 80 MHz)进行灵活的分频。
预分频器配置:通过寄存器 TIMG_Tx_DIVIDER 配置分频系数。当配置为 0 时,分频系数为 65536;当配置为 1 时,分频系数为 2。
2.64位时基计数器
定时器的时基计数器基于 TB_CLK,可以配置为向上计数或向下计数。定时器计数器的值可以通过软件读取,也可以配置为在特定条件下触发报警。
计数器配置:可以通过寄存器 TIMG_Tx_INCREASE 来控制计数器的增减方向(向上或向下)。定时器计数器达到预设的报警值时,会触发报警或中断。
读取计数器值:由于计数器为 64 位,CPU 只能以两个 32 位的值来读取计数器的高低位。读取操作需要通过寄存器 TIMG_TxUPDATE_REG 来锁存计数器值。
ESP32 系列芯片的时基计数器位宽因型号而异,其中 ESP32 为 64 位,ESP32-S3 为 54 位。请查阅相应型号的技术参考手册以获取详细信息。
3.报警产生
定时器支持报警功能,可以在计数器值达到某个报警值时触发报警。报警值分别通过寄存器 TIMG_TxALARMLO_REG 和 TIMG_TxALARMHI_REG 进行设置。
报警触发:报警会在定时器计数器值等于报警值时触发。为了避免“报警使能过晚”而错过触发,定时器支持在计数器值高于报警值(向上计数器)或低于报警值(向下计数器)时立即触发报警。
报警自动重新加载:报警触发后,可以通过寄存器 TIMG_Tx_AUTORELOAD 启用自动重新加载功能,从而使计数器在报警后重新加载初始值,继续计数。
4.中断
定时器可以触发中断来通知 CPU 执行特定任务。ESP32 支持电平触发中断和边沿触发中断,可以用于周期性任务和精确时间控制。
中断控制:通过 TIMG_Tx_INT_ENA 寄存器使能定时器中断,触发后会通过 TIMG_Tx_INT_RAW 和 TIMG_Tx_INT_ST 寄存器反映中断状态。
清除中断:可以通过 TIMG_Tx_INT_CLR 寄存器清除定时器中断,确保在下一个中断发生之前清除先前的中断状态。
二、定时器类型定义及相关API
在 ESP32 中,存在两种定时器 API:一种是传统的硬件定时器(Hardware Timer),另一种是通用定时器在 ESP32 平台上,底层硬件资源都是同一套“定时器组(Timer Group / TIMG)”——两组定时器(TIMG0/TIMG1),每组各含两个通用硬件定时器;经典 ESP32 的通用定时器为 64 位计数器 + 16 位预分频器(详见 TRM),驱动层则提供了两套 API:
早期提供的 Timer Group 驱动(driver/timer.h):直接面向 TIMG 外设的“旧式”接口;
自 IDF 4.4 起引入并在 5.x 里主推的 GPTimer 驱动(driver/gptimer.h):更现代的“新式”通用定时器抽象。
GPTimer 新驱动,功能更全、更易用:支持更灵活的时钟源与分辨率、报警(自动重装载)、ISR 回调、(按需)获取电源管理锁,且能与 ETM/clock tree 更好集成,适合新项目与后续维护。
Timer Group API 旧驱动:直接操作 TIMG 外设,API 粒度偏底层,官方已给出迁移到 GPTimer的指引;更适合维护老代码或确实要与旧示例保持一致时使用。
ESP32定时器类型定义
//=============================================================================
// ESP32/ESP32-S3 定时器类型总览(仅类型定义,无函数)
// - Part A: 旧版 Timer Group(driver/timer.h → driver/timer_types_legacy.h)
// - Part B: 新版 GPTimer(driver/gptimer.h → driver/gptimer_types.h / hal/timer_types.h)
//=============================================================================
#include <stdint.h>
#include <stdbool.h>
//=============================================================================
// Part A) 旧版 Timer Group(LEGACY)类型定义
// 说明:适配 driver/timer.h;在 IDF v5.x 中标记为 deprecated,建议迁移 GPTimer。
//=============================================================================
// 1) 定时器组
typedef enum {
TIMER_GROUP_0 = 0, // 组 0(TIMERG0)
TIMER_GROUP_1 = 1, // 组 1(TIMERG1)
TIMER_GROUP_MAX
} timer_group_t;
// 2) 组内定时器索引
typedef enum {
TIMER_0 = 0, // 每组定时器 0
TIMER_1 = 1, // 每组定时器 1
TIMER_MAX
} timer_idx_t;
// 3) 计数方向
typedef enum {
TIMER_COUNT_UP = 0, // 向上计数
TIMER_COUNT_DOWN = 1, // 向下计数
TIMER_COUNT_MAX
} timer_count_dir_t;
// 4) 启停控制(用于立即启动/暂停)
typedef enum {
TIMER_START = 0, // 使能计数
TIMER_PAUSE = 1, // 暂停计数
TIMER_START_MAX
} timer_start_t;
// 5) 报警使能
typedef enum {
TIMER_ALARM_DIS = 0, // 禁用报警
TIMER_ALARM_EN = 1, // 使能报警
TIMER_ALARM_MAX
} timer_alarm_t;
// 6) 中断触发模式
typedef enum {
TIMER_INTR_LEVEL = 0, // 电平触发
TIMER_INTR_EDGE = 1, // 边沿触发
TIMER_INTR_MAX
} timer_intr_mode_t;
// 7) 自动重载
typedef enum {
TIMER_AUTORELOAD_DIS = 0, // 报警后不自动重装载
TIMER_AUTORELOAD_EN = 1, // 报警后自动重装载
TIMER_AUTORELOAD_MAX
} timer_autoreload_t;
// 8) 组中断位掩码(用于 group 级别开关中断)
typedef enum {
TIMER_INTR_T0 = 1 << 0, // 组内定时器0中断
TIMER_INTR_T1 = 1 << 1, // 组内定时器1中断
TIMER_INTR_WDT = 1 << 2, // 主看门狗中断(属于定时器组模块)
} timer_intr_t;
// 9) 定时器 ISR 回调原型与句柄(LEGACY 回调接口)
typedef bool (*timer_isr_t)(void *arg); // 返回 true 表示在 ISR 末尾需要执行一次 YIELD
typedef void *timer_isr_handle_t; // 中断句柄
// 10) 旧版定时器配置结构体
typedef struct {
uint32_t divider; // 预分频:2~65536(0→65536,1/2→2)
timer_count_dir_t counter_dir; // 计数方向(上/下)
timer_start_t counter_en; // 上电后计数器启/停
timer_alarm_t alarm_en; // 报警使能
timer_intr_mode_t intr_type; // 中断类型(电平/边沿)
timer_autoreload_t auto_reload; // 自动重载
// 说明:老驱动默认使用 APB 时钟;不同芯片/版本可能还有扩展字段,请以目标版本头文件为准
} timer_config_t;
//=============================================================================
// Part B) 新版 GPTimer 类型定义
// 说明:适配 driver/gptimer.h & driver/gptimer_types.h
//=============================================================================
// 1) 计数方向(新版)
typedef enum {
GPTIMER_COUNT_DOWN = 0, // 向下计数
GPTIMER_COUNT_UP = 1, // 向上计数
} gptimer_count_direction_t;
// 2) 定时器时钟源(别名到 SoC 专用枚举)
// 注:不同芯片的可选值不同(如 APB、XTAL、RC_FAST 等),请查 soc_periph_gptimer_clk_src_t
typedef soc_periph_gptimer_clk_src_t gptimer_clock_source_t;
// 3) GPTimer 句柄与回调原型
typedef struct gptimer_t *gptimer_handle_t; // 定时器句柄类型
typedef struct {
uint64_t count_value; // 当前计数值(捕获时刻)
uint64_t alarm_value; // 当前报警比较值
} gptimer_alarm_event_data_t; // 报警事件数据(ISR 环境可读)
typedef bool (*gptimer_alarm_cb_t)(gptimer_handle_t timer,
const gptimer_alarm_event_data_t *edata,
void *user_ctx); // 报警回调;返回 true 可唤醒高优任务
// 4) 事件回调集合(目前仅报警回调)
typedef struct {
gptimer_alarm_cb_t on_alarm; // 报警回调(ISR 环境执行)
} gptimer_event_callbacks_t;
// 5) GPTimer 基本配置
typedef struct {
gptimer_clock_source_t clk_src; // 时钟源(SoC 相关)
gptimer_count_direction_t direction; // 计数方向
uint32_t resolution_hz; // 计数分辨率 Hz(1 tick = 1/resolution_hz 秒)
int intr_priority; // 中断优先级(0→由驱动选择较低优先级 1/2/3)
struct {
uint32_t intr_shared : 1; // 允许与其他外设共享中断号
} flags;
} gptimer_config_t;
// 6) 报警配置
typedef struct {
uint64_t alarm_count; // 报警触发计数值(比较值)
uint64_t reload_count; // 自动重装载的重载值(仅当 auto_reload_on_alarm=1 生效)
struct {
uint32_t auto_reload_on_alarm : 1; // 报警发生时由硬件立即重装载
} flags;
} gptimer_alarm_config_t;
ESP32定时器相关API
//=============================================================================
// ESP32 定时器相关函数总表(GPTimer / Legacy Timer Group / esp_timer)
// 依据 ESP-IDF 官方头文件与文档梳理(v5.x 系列)。
// 说明:仅列出公开 API 原型与简要注释;名称以官方为准,无臆造函数。
//=============================================================================
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
//=============================================================================
// 一、通用硬件定时器 GPTimer(新版驱动:driver/gptimer.h)
//=============================================================================
// 创建 GPTimer 并返回句柄(新建后处于 "init" 态)
esp_err_t gptimer_new_timer(
const gptimer_config_t *config, // [in] 定时器配置
gptimer_handle_t *ret_timer // [out] 返回定时器句柄
);
// 删除 GPTimer 句柄(需在 "init" 态)
esp_err_t gptimer_del_timer(
gptimer_handle_t timer // [in] 定时器句柄
);
// 设置原始计数值(可在 ISR 中调用;对运行中定时器立即生效)
esp_err_t gptimer_set_raw_count(
gptimer_handle_t timer, // [in]
uint64_t value // [in] 计数值
);
// 读取原始计数值(会触发一次软件捕获;可在 ISR 中调用)
esp_err_t gptimer_get_raw_count(
gptimer_handle_t timer, // [in]
uint64_t *value // [out] 当前计数
);
// 读取“实际分辨率”(Hz),用于把 count 换算为秒
esp_err_t gptimer_get_resolution(
gptimer_handle_t timer, // [in]
uint32_t *out_resolution // [out] 实际分辨率(Hz)
);
// 读取最近一次“捕获”值(不触发捕获;可在 ISR 中调用)
esp_err_t gptimer_get_captured_count(
gptimer_handle_t timer, // [in]
uint64_t *value // [out] 捕获计数值
);
// 注册事件回调(如报警回调);首次调用需在 enable 之前
esp_err_t gptimer_register_event_callbacks(
gptimer_handle_t timer, // [in]
const gptimer_event_callbacks_t *cbs, // [in] 回调集合(只包含 on_alarm)
void *user_data // [in] 透传给回调的用户数据
);
// 设置报警行为(目标值、是否自动重载、重载值;传 NULL 可关闭报警)
esp_err_t gptimer_set_alarm_action(
gptimer_handle_t timer, // [in]
const gptimer_alarm_config_t *config // [in] 报警配置(或 NULL 关闭)
);
// 使能 GPTimer(状态从 init -> enable;也会安装中断等)
esp_err_t gptimer_enable(gptimer_handle_t timer);
// 禁用 GPTimer(状态从 enable -> init;卸载中断、释放电源管理锁)
esp_err_t gptimer_disable(gptimer_handle_t timer);
// 启动 GPTimer 计数(状态从 enable -> run;可在 ISR 中调用)
esp_err_t gptimer_start(gptimer_handle_t timer);
// 停止 GPTimer 计数(状态从 run -> enable;可在 ISR 中调用)
esp_err_t gptimer_stop(gptimer_handle_t timer);
//=============================================================================
// 二、硬件定时器(旧版 Timer Group 驱动:driver/timer.h)
// 说明:此驱动已标注“deprecated”,官方建议迁移到 GPTimer。
//=============================================================================
// 读当前计数值(64-bit)
esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *timer_val);
// 以秒为单位读取计数值(double)
esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double *time);
// 写计数器当前值
esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val);
// 启动/暂停计数器
esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num);
esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num);
// 设置计数方向(向上/向下)
esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir);
// 报警时是否自动重载
esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload);
// 设置分频(2~65536)
esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint32_t divider);
// 设置/获取报警阈值(64-bit)
esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value);
esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t *alarm_value);
// 使能/禁用报警功能
esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en);
// 以“回调”方式添加/移除 ISR(由驱动代为处理状态位)
esp_err_t timer_isr_callback_add(timer_group_t group_num, timer_idx_t timer_num, timer_isr_t isr_handler, void *arg, int intr_alloc_flags);
esp_err_t timer_isr_callback_remove(timer_group_t group_num, timer_idx_t timer_num);
// 直接注册完整 ISR(自行处理寄存器与自旋锁等)
esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void *), void *arg, int intr_alloc_flags, timer_isr_handle_t *handle);
// 初始化/反初始化
esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer_config_t *config);
esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num);
// 读取当前配置
esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config);
// 组级中断屏蔽控制(启用/禁用)
esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t intr_mask);
esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t intr_mask);
// 单个定时器中断使能/禁用
esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num);
esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num);
// —— 下列为“仅可在 ISR 中调用”的便捷函数 ——
// 清中断状态 / 重新使能报警
void timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t timer_num);
void timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num);
// ISR 中读计数 / 改报警阈值 / 控制定时器使能
uint64_t timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx_t timer_num);
void timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val);
void timer_group_set_counter_enable_in_isr(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en);
// ISR 中读取组中断状态 / 读取自动重载使能状态
uint32_t timer_group_get_intr_status_in_isr(timer_group_t group_num);
bool timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num);
//=============================================================================
// 三、ESP 高分辨率软件定时器(esp_timer.h)
// 说明:基于 64-bit 微秒计时,运行在系统软件层,非 Timer Group 硬件资源。
//=============================================================================
// 早期初始化 / 初始化 / 反初始化(多用于系统层或特殊场合)
void esp_timer_early_init(void);
esp_err_t esp_timer_init(void);
esp_err_t esp_timer_deinit(void);
// 创建 / 删除定时器
esp_err_t esp_timer_create(const esp_timer_create_args_t *args, esp_timer_handle_t *out_handle);
esp_err_t esp_timer_delete(esp_timer_handle_t timer);
// 启动一次性 / 周期性定时器;重启(修改超时/周期)
esp_err_t esp_timer_start_once(esp_timer_handle_t timer, uint64_t timeout_us);
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period_us);
esp_err_t esp_timer_restart(esp_timer_handle_t timer, uint64_t timeout_or_period_us);
// 停止 / 查询活动状态
esp_err_t esp_timer_stop(esp_timer_handle_t timer);
bool esp_timer_is_active(esp_timer_handle_t timer);
// 读取当前时间(自启动以来的微秒数)
int64_t esp_timer_get_time(void);
// 调试输出当前定时器状态(到给定流,如 stdout)
esp_err_t esp_timer_dump(FILE *stream);
// 从 ISR 回调中请求调度切换(用于高优任务唤醒)
void esp_timer_isr_dispatch_need_yield(void);
// 读取下次唤醒点(微秒)—— 供电源管理/睡眠流程使用
int64_t esp_timer_get_next_alarm(void);
int64_t esp_timer_get_next_alarm_for_wake_up(void);
// 查询周期或到期时间(若适用)
esp_err_t esp_timer_get_period(esp_timer_handle_t timer, uint64_t *period_us);
esp_err_t esp_timer_get_expiry_time(esp_timer_handle_t timer, uint64_t *expiry_us);
// ETM 集成:导出 “esp_timer 报警事件” 供 ETM 连接其他外设
esp_err_t esp_timer_new_etm_alarm_event(esp_etm_event_handle_t *out_event);
三、定时器示例程序
基于ESP32-S3:
1秒周期自动重载中断示例
#include <stdio.h>
#include "driver/gptimer.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "GPTIMER";
bool on_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *event_data, void *user_data)
{
ESP_EARLY_LOGI(TAG, "Alarm triggered!\n"); // 打印报警信息
return false; // 通常返回 false
}
void app_main(void)
{
// 1) 新建定时器(1 MHz 分辨率:1 tick = 1 us)
gptimer_handle_t timer = NULL;
gptimer_config_t cfg = {
.clk_src = GPTIMER_CLK_SRC_APB, // 默认 APB 时钟
.direction = GPTIMER_COUNT_UP, // 向上计数
.resolution_hz = 1 * 1000 * 1000, // 1 MHz -> 1us/tick
.intr_priority = 1, // 中断优先级(1/2/3 越小越低)
};
ESP_ERROR_CHECK(gptimer_new_timer(&cfg, &timer));
// 2) 注册中断回调
gptimer_event_callbacks_t cbs = {
.on_alarm = on_alarm_cb,
};
ESP_ERROR_CHECK(gptimer_register_event_callbacks(timer, &cbs, NULL));
// 3) 启用定时器(进入 enable 状态)
ESP_ERROR_CHECK(gptimer_enable(timer));
// 4) 配置报警动作:1秒触发一次,并硬件自动重装
// 由于分辨率 1 MHz,1 Hz 周期 = 1,000,000 tick
gptimer_alarm_config_t alarm_cfg = {
.alarm_count = 1 * 1000 * 1000ULL, // 到达该计数值产生报警
.reload_count = 0, // 报警后从 0 重新计数
.flags.auto_reload_on_alarm = 1, // 自动重装(周期模式)
};
ESP_ERROR_CHECK(gptimer_set_alarm_action(timer, &alarm_cfg));
// 5) 启动计数(进入 run 状态)
ESP_ERROR_CHECK(gptimer_start(timer));
ESP_LOGI(TAG, "Timer started.");
while (1)
{
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
1 秒周期自动重载中断(累计 5 秒后停止并重启系统)示例
#include <stdio.h>
#include "driver/gptimer.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
static const char *TAG = "GPTIMER";
bool IRAM_ATTR on_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *event_data, void *user_data)
{
static uint32_t count = 0;
count++;
ESP_EARLY_LOGI(TAG, "Time: %d s", count);
if (count >= 5)
{
ESP_EARLY_LOGI(TAG, "Stopping timer");
gptimer_stop(timer);
gptimer_del_timer(timer);
count = 0;
ESP_EARLY_LOGI(TAG, "System restarting...");
esp_restart(); // 重启系统
}
return false;
}
void app_main(void)
{
// 1) 创建定时器:1 MHz 分辨率(1 tick = 1 us)
gptimer_handle_t tmr = NULL;
gptimer_config_t cfg = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1 * 1000 * 1000, // 1 MHz
};
ESP_ERROR_CHECK(gptimer_new_timer(&cfg, &tmr));
// 2) 配置回调(先注册,再 enable)
gptimer_event_callbacks_t cbs = {
.on_alarm = on_alarm_cb,
};
ESP_ERROR_CHECK(gptimer_register_event_callbacks(tmr, &cbs, NULL));
// 3) 配置报警:每 1_000_000 tick 触发(即 1 s),自动重装载
gptimer_alarm_config_t alarm = {
.reload_count = 0,
.alarm_count = 1 * 1000 * 1000, // 1 s @ 1 MHz
.flags.auto_reload_on_alarm = true, // 周期模式
};
ESP_ERROR_CHECK(gptimer_set_alarm_action(tmr, &alarm));
// 4) 启动定时器
ESP_ERROR_CHECK(gptimer_enable(tmr));
ESP_ERROR_CHECK(gptimer_start(tmr));
ESP_LOGI(TAG, "1 Hz timer started");
while (1)
{
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
总结
本文系统梳理了 ESP32 的定时器子系统,涵盖硬件结构(两组四个 64 位 通用定时器、16 位预分频)、报警与中断机制、以及 GPTimer 新驱动 与 Timer Group 旧驱动 的核心用法。通过示例展示了 1 Hz 周期报警及回调处理流程,并给出回调最小化与任务化处理的实践建议。结合合适的时钟源与分辨率配置、自动重装载和中断回调,开发者可以在低开销前提下实现精确、可靠的定时任务与事件调度,适配从简单周期任务到更复杂的实时控制场景。希望本文能帮助你在实际项目中快速落地与优化基于 ESP32 的定时与调度。
更多推荐



所有评论(0)