原创 13. ESP32开发之定时器中断

2025-6-17 16:39 2297 0 1 分类: MCU/ 嵌入式 文集: ESP32
  • 概述
  • 相关API函数
  • 举例:定时发送一个事件
  • 总结

概述

ESP32有一组外设--定时器组。它可以选择不同的时钟源和分配系数。该定时器应用灵活,超时报警可以自动更新计数值。

相关API函数

  1. 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;

  1. 2.创建定时器句柄
esp_err_tgptimer_new_timer(
constgptimer_config_t*config,//填充完成的gptimer_config_t变量
gptimer_handle_t*ret_timer//返回的定时器句柄,所以在调用之前先要定义一个gptimer_handle_t变量,用于返回定时器句柄
)

  1. 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//用户自定义参数
                                  )

  1. 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 (1<<0)
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);

总结

  1. 一定要注意,在回调函数中不能使用ESP_LOGI或printf等打印函数,否则系统会崩溃。

作者: 二月半, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-1862109.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

eeNick 2025-6-18 09:00

感谢分享,奖励60个E币,已到账
相关推荐阅读
二月半 2025-06-12 14:32
【拆解】一款远程控制开关
七年前买了个远程控制开关,想想那个时候应该物联网才兴起的时候吧。如今因为控制麻烦且经常出现连接掉线问题,于是给淘汰了。这个设备我是拿来控制吊灯,特别麻烦的是,当晚上关灯后,会有一点灯点亮着,掉线的时候...
二月半 2025-06-12 10:11
ESP32开发之GPIO中断
电路图GPIO的中断类型相关API函数应用举例总结电路图在ESP32中内部有完整的控制电路,比如上下拉以及滤波器等,所以我们这里可以直接用一个微动开关连接到地。GPIO的中断类型GPIO_INTR_D...
二月半 2025-06-09 22:37
ESP32开发之WS2812B控制
WS2812B数据手册重点摘录硬件电路Remote Control Transceive(RMT)概念RMT的相关API函数一段简单的控制WS2812B的应用举例总结WS2812B数据手册重点摘录WS...
二月半 2025-06-04 09:07
10. ESP32开发之LED闪烁和呼吸的实现
硬件电路介绍GPIO输出模式GPIO配置过程闪烁灯的源码LED PWM的控制器(LEDC)概述LEDC配置过程及现象整体流程硬件电路介绍电路图如下:只要有硬件基础的应该都知道上图中,当GPIO4的输出...
二月半 2025-06-02 21:24
【Milk-V Duo 开发板】+初用体验
许久未在面包板社区申请板卡评测了。这一次偶然最近的这款Milk-V Duo开发板正在评测。首次看到如此简单切功能强大的嵌入式平台:· 支持linux、rtos· 可接一路Camera,做人脸检测、目标...
我要评论
1
0
关闭 站长推荐上一条 /3 下一条