学习ESP32—高分辨率定时器(ESP Timer)使用指南
ESP32 高分辨率定时器ESP Timer使用指南目录1. ESP Timer 简介2. 头文件与依赖3. 定时器回调函数4. 定时器初始化与配置5. 启动定时器6. 完整使用示例7. 常用 API 参考8. 注意事项1. ESP Timer 简介ESP Timer 是 ESP-IDF 提供的高分辨率软件定时器 API。它具有以下特点高精度定时精度可达微秒级μs基于系统时钟使用 64 位硬件计数器不受 APB 频率变化影响灵活的回调机制支持从任务或 ISR 上下文进入回调单次/周期模式支持单次定时和周期性定时两种模式适用场景精确延时控制周期性任务执行如 LED 闪烁、传感器采样超时检测需要微秒级精度的定时操作2. 头文件与依赖使用 ESP Timer 需要包含以下头文件#includeesp_timer.h// ESP Timer API核心#includeesp_err.h// 错误检查宏可选用于 ESP_ERROR_CHECK在自己的定时器模块头文件中声明#ifndef__ESPTIMER_H#define__ESPTIMER_H#includeesp_timer.h/* 函数声明 */voidesptimer_init(uint64_ttps);/* 初始化高分辨率定时器 */#endif注意使用 ESP Timer 之前通常需要初始化 NVS非易失性存储因为 ESP-IDF 系统组件可能依赖 NVS。3. 定时器回调函数定时器回调函数在定时时间到达时被自动调用。编写回调函数需遵循以下规范函数原型voidesptimer_callback(void*arg);参数说明参数类型说明argvoid *创建定时器时传入的用户参数不需要时可设为NULL代码示例/** * brief 定时器回调函数 * param arg: 不携带参数 * retval 无 */voidesptimer_callback(void*arg){LED0_TOGGLE();// 每到达定时周期翻转一次 LED 状态}回调函数注意事项回调函数应尽量简短避免长时间阻塞不要在回调中使用会阻塞的 API如等待信号量超过很短时间回调执行时间应远小于定时周期4. 定时器初始化与配置4.1 配置结构体esp_timer_create_args_t创建定时器前需要先填充esp_timer_create_args_t结构体来配置定时器参数成员类型说明.callbackesp_timer_cb_t定时到达时执行的回调函数指针.argvoid *传递给回调函数的参数.dispatch_methodesp_timer_dispatch_t回调执行方式.nameconst char *定时器名称用于调试和日志.skip_unhandled_eventsbool是否跳过未处理的事件可选4.2dispatch_method取值值说明ESP_TIMER_TASK回调由专用定时器任务执行推荐适合大多数场景ESP_TIMER_ISR回调在中断上下文中执行延迟最低但限制较多4.3 初始化函数实现/** * brief 初始化高分辨率定时器(ESP_TIMER) * param tps: 定时器周期以微秒为单位(μs) * 若以一秒为定时器周期来执行一次定时器中断那此处 tps 1s 1000000μs * retval 无 */voidesptimer_init(uint64_ttps){esp_timer_handle_tesp_tim_handle;/* 定义定时器句柄 *//* 定义一个定时器结构体设置定时器配置参数 */esp_timer_create_args_ttimer_arg{.callbackesptimer_callback,/* 计时时间到达时执行的回调函数 */.argNULL,/* 传递给回调函数的参数 */.dispatch_methodESP_TIMER_TASK,/* 进入回调方式从定时器任务进入 */.nameTimer,/* 定时器名称 */};ESP_ERROR_CHECK(esp_timer_create(timer_arg,esp_tim_handle));/* 创建定时器 */ESP_ERROR_CHECK(esp_timer_start_periodic(esp_tim_handle,tps));/* 启动周期性定时器 */}4.4 参数说明参数说明tps定时器触发周期单位微秒μs。例如1000000表示 1 秒5. 启动定时器ESP Timer 提供两种启动方式5.1 启动周期性定时器定时器以固定周期反复触发回调esp_err_tesp_timer_start_periodic(esp_timer_handle_ttimer,uint64_tperiod_us);参数说明timer定时器句柄period_us定时周期单位微秒μs返回值ESP_OK成功其他值表示失败5.2 启动单次定时器定时器仅触发一次回调后自动停止esp_err_tesp_timer_start_once(esp_timer_handle_ttimer,uint64_ttimeout_us);参数说明timer定时器句柄timeout_us超时时间单位微秒μs返回值ESP_OK成功其他值表示失败5.3 停止与删除定时器esp_err_tesp_timer_stop(esp_timer_handle_ttimer);/* 停止定时器 */esp_err_tesp_timer_delete(esp_timer_handle_ttimer);/* 删除定时器释放资源 */6. 完整使用示例以下是一个完整的 ESP Timer 使用示例实现 LED 每秒闪烁一次6.1 工程结构05_esptimer/ ├── CMakeLists.txt ├── main/ │ ├── CMakeLists.txt │ └── main.c ├── components/ │ └── BSP/ │ ├── LED/ │ │ ├── led.h │ │ └── led.c │ └── ESPTIMER/ │ ├── esptimer.h │ └── esptimer.c └── README.md6.2 main.c#includefreertos/FreeRTOS.h#includefreertos/task.h#includenvs_flash.h#includestdio.h#includeled.h#includeesptimer.h/** * brief 程序入口 * param 无 * retval 无 */voidapp_main(void){esp_err_tret;retnvs_flash_init();/* 初始化NVS */if(retESP_ERR_NVS_NO_FREE_PAGES||retESP_ERR_NVS_NEW_VERSION_FOUND){ESP_ERROR_CHECK(nvs_flash_erase());ESP_ERROR_CHECK(nvs_flash_init());}led_init();/* 初始化LED */esptimer_init(1000000);/* 初始化ESP_TIMER周期1秒1000000μs*/while(1){vTaskDelay(pdMS_TO_TICKS(10));/* 延时10ms */}}6.3 实验现象程序运行后LED0 每隔1 秒翻转一次电平状态即 LED 以 2 秒为周期闪烁。7. 常用 API 参考7.1 定时器生命周期 APIAPI功能esp_timer_create()创建定时器esp_timer_start_once()启动单次定时器esp_timer_start_periodic()启动周期性定时器esp_timer_restart()重新启动已启动的定时器更新超时时间esp_timer_stop()停止定时器esp_timer_delete()删除定时器7.2 时间获取 APIAPI功能esp_timer_get_time()获取自启动以来的时间微秒64位esp_timer_dump()打印所有定时器的状态信息调试用7.3 系统初始化 APIAPI功能esp_timer_init()初始化 ESP Timer 子系统在调用esp_timer_create前自动调用esp_timer_deinit()反初始化 ESP Timer 子系统8. 注意事项8.1 回调上下文选择上下文优点限制ESP_TIMER_TASK可调用大部分 FreeRTOS API实现灵活延迟稍高取决于任务优先级ESP_TIMER_ISR延迟极低不能调用阻塞 API不能使用 printf 打印浮点数等一般应用场景推荐使用ESP_TIMER_TASK。8.2 精度与周期最小定时周期取决于系统负载和回调执行时间理论上可达微秒级定时周期不宜过短如几微秒否则回调可能来不及执行1 秒 1,000,000 微秒μs8.3 资源管理不再使用的定时器应及时调用esp_timer_delete()删除释放内存一个定时器同一时刻只能启动一次如需更改周期先停止再重新启动使用ESP_ERROR_CHECK宏检查 API 返回值便于调试8.4 NVS 初始化ESP Timer 的某些依赖如日志、系统时间等需要 NVS 支持建议在app_main中首先初始化 NVSesp_err_tretnvs_flash_init();if(retESP_ERR_NVS_NO_FREE_PAGES||retESP_ERR_NVS_NEW_VERSION_FOUND){ESP_ERROR_CHECK(nvs_flash_erase());ESP_ERROR_CHECK(nvs_flash_init());}8.5 与 FreeRTOS 软件定时器的区别特性ESP TimerFreeRTOS 软件定时器精度微秒级毫秒级受 tick 频率限制基于硬件 64 位计数器FreeRTOS tick 计数使用复杂度简单API 直观需要配置定时器任务适用场景高精度定时低精度周期性任务