tag 标签: gptimer

相关博文
  • 热度 1
    2025-6-17 16:39
    14209 次阅读|
    1 个评论
    概述 相关API函数 举例:定时发送一个事件 总结 概述 ESP32有一组外设--定时器组。它可以选择不同的时钟源和分配系数。该定时器应用灵活,超时报警可以自动更新计数值。 相关API函数 1.定时器配置结构体 typedefstruct { gptimer_clock_source_tclk_src; /* 定时器时钟源,在clk_tree_defs.h中有个枚举soc_periph_gptimer_clk_src_t */ gptimer_count_direction_tdirection; /*计数方向 ,定义在timer_typers.h的枚举gptimer_count_direction_t中*/ uint32_tresolution_hz; /*频率分辨率,单位HZ,每个滴答步长是1/ resolution_hz秒*/ intintr_priority; /*定时器中断优先级,如果设置0,将分配优先级较低的中断*/ struct { uint32_tintr_shared: 1 ; /*设置是否与其他外设共享此定时器终端号*/ } flags; } gptimer_config_t ; 2.创建定时器句柄 esp_err_tgptimer_new_timer ( constgptimer_config_t *config, //填充完成的gptimer_config_t变量 gptimer_handle_t *ret_timer //返回的定时器句柄,所以在调用之前先要定义一个gptimer_handle_t变量,用于返回定时器句柄 ) 3.设置报警并触发一个事件 配置警报动作 esp_err_tgptimer_set_alarm_action ( gptimer_handle_ttimer, //上一步返回的定时器句柄 constgptimer_alarm_config_t *config //警报的相关配置 ) typedefstruct { uint64_talarm_count; /*警报的目标计数值 */ uint64_treload_count; /*只有当auto_reload_on_alarm设置为ture,才会有影响,重载计数值 */ struct { uint32_tauto_reload_on_alarm: 1 ; /*当警报发生时,重载按硬件开始 */ } flags; } gptimer_alarm_config_t ; 注册事件回调函数 esp_err_tgptimer_register_event_callbacks ( gptimer_handle_ttimer, //返回的定时器句柄 constgptimer_event_callbacks_t *cbs, //事件回调函数 void *user_data //传递给回调函数的参数 ) //回调函数的函数原型,在gptimer_event_callbacks_t结构体里定义 typedefbool (* gptimer_alarm_cb_t )(gptimer_handle_ttimer, //定时器句柄 constgptimer_alarm_event_data_t *edata, //传递报警事件的相关数据 void *user_ctx //用户自定义参数 ) 4.使能定时器 esp_err_tgptimer_enable(gptimer_handle_ttimer) 5.启动定时器 esp_err_tgptimer_start(gptimer_handle_ttimer) 举例:定时发送一个事件 /** * Copyright (C) 2024-2034 HalfMoon2. * All rights reserved. * * @file Filename without the absolute path * @brief Brief description * @author HalfMoon2 * @date 2025-06-13 * @version v0.1 * * @revision history: * 2025-06-13 - Initial version. */ # include stdio.h # include driver/gptimer.h # include freertos/FreeRTOS.h # include freertos/task.h # include esp_err.h # include esp_log.h ​ # define event_bit0 (10) EventGroupHandle_teventGroup= NULL ; ​ boolgptimer_alarm_cb (gptimer_handle_ttimer, constgptimer_alarm_event_data_t *edata, void *user_ctx) { BaseType_tpxHigherPriorityTaskWoken; xEventGroupSetBitsFromISR (eventGroup,event_bit0,pxHigherPriorityTaskWoken); returnfalse; } ​ voidevent_task ( void *pvParam) { while ( 1 ){ if ( xEventGroupWaitBits (eventGroup,event_bit0,pdTRUE,pdFALSE,portMAX_DELAY)== 1 ){ ESP_LOGI ( "gptimer" , "alarm success!!!" ); } } } ​ staticvoidgptimer_init () { gptimer_handle_tgptimer= NULL ; gptimer_config_ttimer_config={ .clk_src=GPTIMER_CLK_SRC_DEFAULT, .direction=GPTIMER_COUNT_UP, .intr_priority= 0 , .resolution_hz= 1 * 1000 * 1000 , //分辨率为1M,一次滴答1us .flags.intr_shared= false }; //创建定时器句柄 ESP_ERROR_CHECK ( gptimer_new_timer (timer_config, gptimer)); ​ //设置警报动作,目标计数值,是否自动重载等 gptimer_alarm_config_talarm_config={ .alarm_count= 1000000 , //一次滴答1us,这里刚好1s .reload_count= 0 , .flags.auto_reload_on_alarm= true }; ESP_ERROR_CHECK ( gptimer_set_alarm_action (gptimer, alarm_config)); ​ //注册警报事件 gptimer_event_callbacks_tcbs={ .on_alarm=gptimer_alarm_cb }; ESP_ERROR_CHECK ( gptimer_register_event_callbacks (gptimer,cbs, NULL )); ​ //使能定时器 ESP_ERROR_CHECK ( gptimer_enable (gptimer)); ​ //开启定时器 ESP_ERROR_CHECK ( gptimer_start (gptimer)); } ​ voidapp_main ( void ) { //创建一个事件组 eventGroup= xEventGroupCreate (); gptimer_init (); xTaskCreatePinnedToCore (event_task, "event_task" , 2048 , NULL , 3 , NULL , 1 ); } ​ 从打印可以看出,刚好1秒触发一次警报。 gptimer还支持动态更新计数值,可在回调函数中增加如下代码 gptimer_alarm_config_talarm_config= { .alarm_count=edata-alarm_value +1000000 , // 下一次警报在当前警报的基础上加 1s }; // 更新警报值 gptimer_set_alarm_action (timer, alarm_config); 总结 一定要注意,在回调函数中不能使用ESP_LOGI或printf等打印函数,否则系统会崩溃。