ESP32-S3定时器组Timer Group0/1的使用

ESP32-S3定时器组Timer Group0/1的使用


一、版本说明

c 复制代码
  - Python版本: Python 3.12.3
  - ninja版本 : ninja version 1.11.1
  - CMake版本 : cmake version 3.28.3
  - 芯片型号  : ESP32-S3
  - IDF版本   : ESP-IDF v5.4.1-dirty
  - Git版本   : git version 2.43.0

二、模组说明

c 复制代码
  - 模组ESP32-S3-WROOM-1-N16R8
  - 内置8MB Octal SPI PSRAM
  - 内置芯片ESP32-S3R8
  - 外置16MB Flash

三、定时器组Timer Group0/1

  • ESP32-S3包含两个定时器组,即定时器组0和定时器组 1。每个定时器组有两个通用定时器和一个主系统看门狗定时器。所有通用定时器均基于16位预分频器和54位可自动重新加载向上/向下计数器
  • 定时器组的包含时钟选择器、一个16位整数预分频器、一个时基计数器和一个用于产生警报的比较器
  • 定时器必须关闭,才能更改16位预分频器。在定时器使能时更改16位预分频器会造成不可预知的结果
  • 定时器可配置为在当前值与报警值相同时触发报警。报警会产生中断,(可选择)让定时器的当前值自动重新加载

四、常用函数

c 复制代码
/* 定时器注册回调 */
esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer_event_callbacks_t *cbs, void *user_data)

/* 定时器设置报警动作 */
esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_config_t *config)

/* 获取定时器分辨率 */
esp_err_t gptimer_get_resolution(gptimer_handle_t timer, uint32_t *out_resolution)

/* 获取定时器当前计数值 */
esp_err_t gptimer_get_raw_count(gptimer_handle_t timer, unsigned long long *value)

/* 设置定时器计数值 */
esp_err_t gptimer_set_raw_count(gptimer_handle_t timer, unsigned long long value)

/* 定时器初始化 */
esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *ret_timer)

/* 定时器删除 */
esp_err_t gptimer_del_timer(gptimer_handle_t timer)

/* 使能定时器 */
esp_err_t gptimer_enable(gptimer_handle_t timer)

/* 失能定时器 */
esp_err_t gptimer_disable(gptimer_handle_t timer)

/* 启动定时器 */
esp_err_t gptimer_start(gptimer_handle_t timer)

/* 停止定时器 */
esp_err_t gptimer_stop(gptimer_handle_t timer)

五、例程源码

c 复制代码
#include "gptimer.h"

#include "driver/gptimer.h"
#include "esp_attr.h"
#include "esp_log.h"


static const char * TAG = "GPTimer";
gptimer_handle_t gptimer_period_handle = NULL;


static bool IRAM_ATTR gptimer_once_isr_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
{
    if (timer == gptimer_period_handle)
    {
        // 尽量不中打印日志
        ESP_EARLY_LOGE(TAG, "Count:%lld  Alarm:%lld", edata->count_value, edata->alarm_value);
    }

    return false;
}


/************************************************************************************************************************
 * 【说明】
 * 1. 自动分配硬件定时器,无硬件定时器会初始化失败gptimer_new_timer
 * 2. 当auto_reload_on_alarm使能,定时器中断后会自动重载reload_count值
 * 3. 当auto_reload_on_alarm失能,定时器中断重设置下次报警值可实现2中效果
 * 4. gptimer_handle_tz中的任何成员都是私有的用户无法访问
 * 
 * 
 * 【注意】
 * 1. 中断不能打印日志,否则会卡死
*************************************************************************************************************************/
void gptimer_init(void)
{
    /* 周期定时器 */
    gptimer_config_t gptimer_period_config = {
        .clk_src       = GPTIMER_CLK_SRC_APB, //时钟
        .direction     = GPTIMER_COUNT_UP,    //向上计数
        .resolution_hz = 1000000,             //频率
    };
    ESP_ERROR_CHECK(gptimer_new_timer(&gptimer_period_config, &gptimer_period_handle));

    const gptimer_event_callbacks_t gptimer_once_callback = {
        .on_alarm = gptimer_once_isr_callback, //中断回调
    };
    ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer_period_handle, &gptimer_once_callback, NULL));


    const gptimer_alarm_config_t gptimer_period_alarm_config = {
        .reload_count = 1000, //重载值
        .alarm_count  = 1000000, //报警值
        .flags.auto_reload_on_alarm = true, //使能自动重载
    };
    ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer_period_handle, &gptimer_period_alarm_config)); //设置报警动作
    ESP_ERROR_CHECK(gptimer_enable(gptimer_period_handle)); //使能定时器
    ESP_ERROR_CHECK(gptimer_start(gptimer_period_handle)); //启动定时器

    unsigned long long count = 0;
    gptimer_get_raw_count(gptimer_period_handle, &count); //获取计数值
    ESP_LOGI(TAG, "Timer count value:%llu", count);
}

六、主函数

c 复制代码
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_chip_info.h"
#include "esp_psram.h"
#include "esp_flash.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "esp_log.h"


#include "sys_timer.h"
#include "sys_clock.h"
#include "pwm_fade.h"
#include "gptimer.h"
#include "Ledc.h"


static const char * TAG = "xMain";
void app_main(void)
{
    esp_err_t ret;
    uint32_t flash_size;
    esp_chip_info_t chip_info; 

    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    esp_flash_get_size(NULL, &flash_size);
    esp_chip_info(&chip_info);
    printf("内核CPU数量%d\n",chip_info.cores); 
    printf("FLASH Size:%ld MB Flash\r\n",flash_size / (1024 * 1024));
    printf("PSRAM Size:%d Bytes\r\n", esp_psram_get_size());

    // system_clock_info();
    // ledc_init();
    // pwm_fade_init();
    // sys_timer_init();
    gptimer_init();

    while(1)
    {
        vTaskDelay(500);
        ESP_LOGI(TAG, "Count......", esp_timer_get_time());
    }
}

七、CMakeLists.txt文件

  • components/BSP/CMakeLists.txt
c 复制代码
set(src_dirs 
            Clock
            PWM
            FadePWM
            SysTimer
            GpTimer)

set(include_dirs 
                Clock
                PWM
                FadePWM
                SysTimer
                GpTimer)

set(requires    driver 
                nvs_flash 
                esp_psram 
                spi_flash
                esp_timer)

# idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})
idf_component_register(SRC_DIRS ${src_dirs}
                       INCLUDE_DIRS ${include_dirs}
                       REQUIRES ${requires})
component_compile_options(-ffast-math -O3 -Wno-error=format -Wno-format)

八、运行结果

c 复制代码
I (195) octal_psram: BurstType    : 0x01 (Hybrid Wrap)
I (199) octal_psram: BurstLen     : 0x01 (32 Byte)
I (204) octal_psram: Readlatency  : 0x02 (10 cycles@Fixed)
I (209) octal_psram: DriveStrength: 0x00 (1/1)
I (214) MSPI Timing: PSRAM timing tuning index: 5
I (218) esp_psram: Found 8MB PSRAM device
I (222) esp_psram: Speed: 80MHz
I (225) cpu_start: Multicore app
I (660) esp_psram: SPI SRAM memory test OK
I (669) cpu_start: Pro cpu start user code
I (669) cpu_start: cpu freq: 240000000 Hz
I (669) app_init: Application information:
I (669) app_init: Project name:     main
I (672) app_init: App version:      1
I (676) app_init: Compile time:     Apr  2 2026 17:48:00
I (681) app_init: ELF file SHA256:  7f49b57e7...
I (685) app_init: ESP-IDF:          v5.4.1-dirty
I (690) efuse_init: Min chip rev:     v0.0
I (693) efuse_init: Max chip rev:     v0.99 
I (697) efuse_init: Chip rev:         v0.2
I (701) heap_init: Initializing. RAM available for dynamic allocation:
I (708) heap_init: At 3FC97970 len 00051DA0 (327 KiB): RAM
I (713) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
I (718) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (723) heap_init: At 600FE11C len 00001ECC (7 KiB): RTCRAM
I (728) esp_psram: Adding pool of 8192K of PSRAM memory to heap allocator
I (735) spi_flash: detected chip: generic
I (739) spi_flash: flash io: qio
I (742) sleep_gpio: Configure to isolate all GPIO pins in sleep state
I (748) sleep_gpio: Enable automatic switching of GPIO sleep configuration
I (755) main_task: Started on CPU0
I (779) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
I (779) main_task: Calling app_main()
内核CPU数量2
FLASH Size:16 MB Flash
PSRAM Size:8388608 Bytes
I (791) GPTimer: Timer count value:10
I (1292) xMain: Count......562868
E (1791) GPTimer: Count:1001  Alarm:1000000
I (1792) xMain: Count......1062868
I (2292) xMain: Count......1562868
E (2790) GPTimer: Count:1001  Alarm:1000000
I (2792) xMain: Count......2062868
I (3292) xMain: Count......2562868
E (3789) GPTimer: Count:1001  Alarm:1000000
I (3792) xMain: Count......3062868
I (4292) xMain: Count......3562868
E (4788) GPTimer: Count:1001  Alarm:1000000
I (4792) xMain: Count......4062868
I (5292) xMain: Count......4562868
E (5787) GPTimer: Count:1001  Alarm:1000000
I (5792) xMain: Count......5062868
I (6292) xMain: Count......5562868
E (6786) GPTimer: Count:1001  Alarm:1000000
相关推荐
我叫洋洋2 小时前
[STM32 和 PWM 输出 结合 proteus 仿真]
stm32·嵌入式硬件·proteus
我不是程序猿儿2 小时前
【嵌入式】第2讲:USB CDC 从“插上电脑”到“出现 COM 口”,枚举过程到底发生了什么
服务器·stm32·单片机·嵌入式硬件·电脑·负载均衡
2301_805962932 小时前
树莓派学习1-I2C配置与设备状态检测
嵌入式硬件·学习
学嵌入式的小杨同学10 小时前
STM32 进阶封神之路(三十三):W25Q64 任意长度写入深度实战 —— 从页限制到工业级通用读写(附完整代码 + 避坑指南)
stm32·单片机·嵌入式硬件·架构·硬件架构·嵌入式·flash
Hello_Embed12 小时前
嵌入式上位机开发入门(三):TCP 编程 —— Server 端实现
笔记·单片机·网络协议·tcp/ip·嵌入式
Hello World . .15 小时前
ARM裸机学习6——UART
arm开发·单片机·嵌入式硬件
XiYang-DING15 小时前
【LeetCode】链表 + 快慢指针找中间 | 2095. 删除链表的中间节点
算法·leetcode·链表
Zarek枫煜15 小时前
[特殊字符] C3语言:传承C之高效,突破C之局限
c语言·开发语言·c++·单片机·嵌入式硬件·物联网·算法
Lugas Luo15 小时前
SATA 硬盘识别延时:协议层与内核机制分析
linux·嵌入式硬件