esp32定时器的使用demo
1、介绍
ESP32芯片包含两个硬件定时器组。每组有两个通用硬件定时器。它们都是基于16位预分频器和64位自动重载功能的向上向下计数器的64位通用定时器。
2、API接口函数
创建定时器函数: esp_timer_create();
esp_err_t esp_timer_create (const esp_timer_create_args_t* create_args, esp_timer_handle_t* out_handle)
功能:
创建一个esp_timer实例
注意:
使用计时器完成后,请使用esp_timer_delete函数将其删除。
返回:
- ESP_OK成功
- 如果某些create_args无效,则为ESP_ERR_INVALID_ARG
- ESP_ERR_INVALID_STATE如果esp_timer库尚未初始化
- 如果内存分配失败,则为ESP_ERR_NO_MEM
参数:
- create_args:指向带有计时器创建参数的结构的指针。未由库保存,可以在堆栈上分配。
- [out] out_handle:输出,指向esp_timer_handle_t变量的指针,该变量将保存创建的计时器句柄。
esp_err_t esp_timer_start_once(esp_timer_handle_t timer,uint64_t timeout_us )
功能:
启动单发计时器。
调用此函数时,计时器不应运行。
返回
- ESP_OK成功
- ESP_ERR_INVALID_ARG如果句柄无效
- ESP_ERR_INVALID_STATE,如果计时器已经在运行
参数:
- timer:使用esp_timer_create创建的计时器句柄
- timeout_us:计时器超时,相对于当前时刻,以微秒为单位
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer,uint64_t period )
功能:
启动一个定期计时器。
调用此函数时,计时器不应运行。此功能将启动计时器,该计时器将触发每个“周期”微秒。
返回:
- ESP_OK成功
- ESP_ERR_INVALID_ARG如果句柄无效
- ESP_ERR_INVALID_STATE,如果计时器已经在运行
参数:
- timer:使用esp_timer_create创建的计时器句柄
- period:计时器时间(以微秒为单位)
esp_err_t esp_timer_stop(esp_timer_handle_t timer )
功能:
停止计时器。
此函数停止先前使用esp_timer_start_once或esp_timer_start_periodic启动的计时器。
返回
- ESP_OK成功
- ESP_ERR_INVALID_STATE(如果计时器未运行)
参量
- timer:使用esp_timer_create创建的计时器句柄
esp_err_t esp_timer_delete(esp_timer_handle_t timer )
删除esp_timer实例。
删除前必须停止计时器。一次到期的单次计时器无需停止。
返回
- ESP_OK成功
- ESP_ERR_INVALID_STATE,如果计时器正在运行
参量
- timer:使用esp_timer_create分配的计时器句柄
int64_t esp_timer_get_time( void )
功能:
自启动以来获取时间(以微秒为单位)。
返回
自从调用esp_timer_init以来的微秒数(这通常在应用程序启动期间的早期发生)。
3、代码demo:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_timer.h"
static const char *TAG = "myTimer";
esp_timer_handle_t periodic_timer_handle = NULL; //周期性的定时器句柄
esp_timer_handle_t onece_timer_handle = NULL; //单次定时器句柄
void periodic_timer_callback(void* arg)
{
for(int i=0;i<10;i++)
{
printf("<<<<<<<<<<<<<<<<<<<<<<<<<< periodic_timer_callback = %d \n",i);
vTaskDelay(10 / portTICK_PERIOD_MS);
}
esp_timer_stop(periodic_timer_handle); //停止定时器
esp_timer_delete(periodic_timer_handle); //删除定时器
}
void onece_timer_callback(void* arg)
{
printf("============================= onece_timer_callback \n");
vTaskDelay(500 / portTICK_PERIOD_MS);
}
void app_main()
{
uint32_t num = 0;
esp_timer_init(); //定时器初始化+
while (1)
{
// 数值自加
num++;
ESP_LOGI(TAG,"---> num = %d",num);
// 判断是否达到触发条件
if (num == 10) {
// 创建定时器
//esp_timer_handle_t timer_handle = NULL;
/*
* typedef struct {
esp_timer_cb_t callback; //!< Function to call when timer expires
void* arg; //!< Argument to pass to the callback
esp_timer_dispatch_t dispatch_method; //!< Call the callback from task or from ISR
const char* name; //!< Timer name, used in esp_timer_dump function
bool skip_unhandled_events; //!< Skip unhandled events for periodic timers
} esp_timer_create_args_t;+
*/
const esp_timer_create_args_t periodic_timer_args = {
.callback = &periodic_timer_callback,
.arg = NULL,
.name = "my_periodic_timer"
};
esp_timer_create(&periodic_timer_args, &periodic_timer_handle);
// 启动定时器
const TickType_t delay_ms = 1000 / portTICK_PERIOD_MS;
esp_timer_start_periodic(periodic_timer_handle, delay_ms * 1000); //周期性的定时器,即定时器会以固定的时间间隔重复触发回调函数
}
//判断是否达到触发条件
if(num == 15)
{
const esp_timer_create_args_t once_timer_args = {
.callback = &onece_timer_callback,
.arg = NULL,
.name = "my_onece_timer"
};
esp_timer_create(&once_timer_args, &onece_timer_handle);
// 启动定时器
const TickType_t delay_ms = 1000 / portTICK_PERIOD_MS;
esp_timer_start_once(onece_timer_handle, delay_ms * 1000); //启动一个一次性的定时器,即定时器只会触发一次回调函数,然后自动停止
}
if (num > 20) {
// 定时器触发后退出循环
break;
}
vTaskDelay(500 / portTICK_PERIOD_MS); // 等待一段时间
}
ESP_LOGI(TAG,"app is out");
}