一、版本说明


  - 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



二、模组说明


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



三、系统定时器SysTimer

  • ESP32-S3芯片内置一组52位系统定时器。该定时器可用于生成操作系统所需的滴答定时中断,也可用作普通定时器生成周期或单次延时中断
  • 系统定时器内置两个计数器(UNIT0和UNIT1)以及三个比较器(COMP0、COMP1和COMP2)。比较器用于监控计数器的计数值是否达到报警值
  • 计数采用CNT_CLK时钟,两次计数周期的平均频率为16MHz
  • CNT_CLK 的时钟源为XTAL_CLK(40 MHz)

在这里插入图片描述

在这里插入图片描述



四、常用函数


/* 创建定时器对象 */
esp_err_t esp_timer_create(const esp_timer_create_args_t* args,esp_timer_handle_t* out_handle)

/* 启动周期定时器 */
esp_err_t IRAM_ATTR esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period_us)

/* 启动单次定时器 */
esp_err_t IRAM_ATTR esp_timer_start_once(esp_timer_handle_t timer, uint64_t timeout_us)

/* 获取定时器周期 */
esp_err_t IRAM_ATTR esp_timer_get_period(esp_timer_handle_t timer, uint64_t *period)

/* 检查定时器是否处于活动状态 */
bool IRAM_ATTR esp_timer_is_active(esp_timer_handle_t timer)

/* 停止已启动的定时器 */
esp_err_t IRAM_ATTR esp_timer_stop(esp_timer_handle_t timer)

/* 删除已创建的定时器对象,必须先停止定时器 */
esp_err_t esp_timer_delete(esp_timer_handle_t timer)

/* 获取当前系统高精度时间戳(单位:微秒) */
int64_t esp_timer_get_time(void)



五、例程源码


#include "sys_timer.h"

#include "esp_timer.h"
#include "esp_log.h"
#include <stdio.h>


static const char * TAG = "SysTick";
esp_timer_handle_t periodic_timer_handler = NULL; /* 周期定时器 */
esp_timer_handle_t single_timer_handler   = NULL; /* 单次定时器 */



/* 周期定时器回调 */
static void periodic_timer_callback(void * arg)
{
    esp_err_t err = 1;
    uint64_t period = 0;
    static uint32_t runCount = 1;


    /* 获取周期 */
    err = esp_timer_get_period(periodic_timer_handler, &period);
    if (err)
    {
        ESP_LOGW(TAG, "P-Timer get period error......%X", err);
    }

    ESP_LOGI(TAG, "[%03d] Periodic:%lld , Tick:%lld", runCount, period, esp_timer_get_time());

    /* 输出定时器信息 */
    if (!(runCount % 5))
    {
        printf("\r\n");
        esp_timer_dump(stdout);
        printf("\r\n");
    }

    if (runCount >= 20)
    {
        /* 停止定制器 */
        err = esp_timer_stop(periodic_timer_handler);
        if (err)
        {
            ESP_LOGW(TAG, "P-Timer stop error......%X", err);
        }

        /* 删除定时器,释放资源 */
        err = esp_timer_delete(periodic_timer_handler);
        periodic_timer_handler = NULL;
        if (err)
        {
            ESP_LOGW(TAG, "P-Timer delete error......%X", err);
        }

        ESP_LOGI(TAG, "Periodic timer stop......Tick:%lld\r\n", esp_timer_get_time());
        return;
    }

    runCount++;
}


/* 单次定时器回调 */
static void single_timer_callback(void * arg)
{
    esp_err_t err = 1;
    uint64_t period = 0;
    esp_timer_handle_t periodic_handler = (esp_timer_handle_t)arg;


    /* 检查定时器活动状态 */
    if (esp_timer_is_active(periodic_handler))
    {
        /* 停止定制器 */
        err = esp_timer_stop(periodic_handler);
        if (err)
        {
            ESP_LOGW(TAG, "S-Timer stop error......%X", err);
        }

        /* 改变周期并开启 */
        err = esp_timer_start_periodic(periodic_handler, 2000000); // 2s
        if (err)
        {
            ESP_LOGW(TAG, "S-Timer start error......%X", err);
        }

        /* 获取周期 */
        err = esp_timer_get_period(periodic_handler, &period);
        if (err)
        {
            ESP_LOGW(TAG, "S-Timer get period error......%X", err);
        }
    }

    ESP_LOGI(TAG, "Single-state:%X , Period-state:%X", esp_timer_is_active(single_timer_handler), esp_timer_is_active(periodic_handler));


    /* 删除定时器,释放资源 */
    err = esp_timer_delete(single_timer_handler);
    single_timer_handler = NULL;
    if (err)
    {
        ESP_LOGW(TAG, "S-Timer delete error......%X", err);
    }
    
    ESP_LOGI(TAG, "Single timer stop......Tick:%lld\r\n", esp_timer_get_time());
}



void sys_timer_init(void)
{
    /* 创建周期定时器 */
    const esp_timer_create_args_t periodic_timer_args = 
    {
        .callback = &periodic_timer_callback,
        .name     = "periodic",
    };
    ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer_handler));


    /* 创建单次定时器 */
    const esp_timer_create_args_t single_timer_args = 
    {
        .callback = &single_timer_callback,
        .name     = "single",
        .arg      = (void *)periodic_timer_handler,
    };
    ESP_ERROR_CHECK(esp_timer_create(&single_timer_args, &single_timer_handler));


    /* 启动定时器 */
    ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer_handler, 1000000)); //1s
    ESP_ERROR_CHECK(esp_timer_start_once(single_timer_handler, 5000000)); //5s
    ESP_LOGE(TAG, "Sys tick since boot %lld us", esp_timer_get_time());
    ESP_LOGW(TAG, "Sys tick since boot %lld us", esp_timer_get_time());
    ESP_LOGI(TAG, "Sys tick since boot %lld us\r\n", esp_timer_get_time());

}




六、主函数

#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 "sys_timer.h"
#include "sys_clock.h"
#include "pwm_fade.h"
#include "Ledc.h"



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();

    while(1)
    {
        vTaskDelay(100);
    }
}

在这里插入图片描述



七、CMakeLists.txt文件

  • 顶层CMakeLists.txt

# CMake最低版本
cmake_minimum_required(VERSION 3.16)

# 指定额外组件搜索目录
set(EXTRA_COMPONENT_DIRS components/Middlewares)

# 强制编译器彩色显示编译信息
add_compile_options(-fdiagnostics-color=always)

# 指定编译目标芯片
set(IDF_TARGET esp32s3)

# 日志输出命令
message(STATUS "Current IDF_PATH from environment: $ENV{IDF_PATH}")

# ESP-IDF核心构建脚本启动ESP-IDF构建系统
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# 定义工程名称
project(main)


  • main/CMakeLists.txt

idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS ".")

component_compile_options(-ffast-math -O3 -Wno-error=format -Wno-format)


  • components/BSP/CMakeLists.txt

set(src_dirs 
            Clock
            PWM
            FadePWM
            SysTimer)

set(include_dirs 
                Clock
                PWM
                FadePWM
                SysTimer)

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)

在这里插入图片描述



八、运行结果


I (687) app_init: ESP-IDF:          v5.4.1-dirty
I (691) efuse_init: Min chip rev:     v0.0
I (695) efuse_init: Max chip rev:     v0.99 
I (699) efuse_init: Chip rev:         v0.2
I (703) heap_init: Initializing. RAM available for dynamic allocation:
I (709) heap_init: At 3FC97BA0 len 00051B70 (326 KiB): RAM
I (714) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
I (720) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (725) heap_init: At 600FE11C len 00001ECC (7 KiB): RTCRAM
I (730) esp_psram: Adding pool of 8192K of PSRAM memory to heap allocator
I (737) spi_flash: detected chip: generic
I (740) spi_flash: flash io: qio
I (743) sleep_gpio: Configure to isolate all GPIO pins in sleep state
I (750) sleep_gpio: Enable automatic switching of GPIO sleep configuration
I (756) main_task: Started on CPU0
I (780) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
I (780) main_task: Calling app_main()
内核CPU数量2
FLASH Size:16 MB Flash
PSRAM Size:8388608 Bytes
E (792) SysTick: Sys tick since boot 62411 us
W (792) SysTick: Sys tick since boot 62577 us
I (795) SysTick: Sys tick since boot 65306 us

I (1792) SysTick: [001] Periodic:1000000 , Tick:1062429
I (2792) SysTick: [002] Periodic:1000000 , Tick:2062412
I (3792) SysTick: [003] Periodic:1000000 , Tick:3062412
I (4792) SysTick: [004] Periodic:1000000 , Tick:4062412
I (5792) SysTick: [005] Periodic:1000000 , Tick:5062412

Timer stats:
Name                  Period      Alarm       
timer@0x3fca5124      0           5062407     
timer@0x3fca5100      1000000     6062400     

I (5800) SysTick: Single-state:0 , Period-state:1
I (5805) SysTick: Single timer stop......Tick:5075000

I (7800) SysTick: [006] Periodic:2000000 , Tick:7070532
I (9800) SysTick: [007] Periodic:2000000 , Tick:9070532
I (11800) SysTick: [008] Periodic:2000000 , Tick:11070531
I (13800) SysTick: [009] Periodic:2000000 , Tick:13070531
I (15800) SysTick: [010] Periodic:2000000 , Tick:15070531

Timer stats:
Name                  Period      Alarm       
timer@0x3fca5100      2000000     17070519    

I (17800) SysTick: [011] Periodic:2000000 , Tick:17070533
I (19800) SysTick: [012] Periodic:2000000 , Tick:19070531
I (21800) SysTick: [013] Periodic:2000000 , Tick:21070533
I (23800) SysTick: [014] Periodic:2000000 , Tick:23070531
I (25800) SysTick: [015] Periodic:2000000 , Tick:25070531

Timer stats:
Name                  Period      Alarm       
timer@0x3fca5100      2000000     27070519    

I (27800) SysTick: [016] Periodic:2000000 , Tick:27070531
I (29800) SysTick: [017] Periodic:2000000 , Tick:29070531
I (31800) SysTick: [018] Periodic:2000000 , Tick:31070533
I (33800) SysTick: [019] Periodic:2000000 , Tick:33070531
I (35800) SysTick: [020] Periodic:2000000 , Tick:35070531

Timer stats:
Name                  Period      Alarm       
timer@0x3fca5100      2000000     37070519    

I (35804) SysTick: Periodic timer stop......Tick:35074652

在这里插入图片描述

在这里插入图片描述

更多推荐