【ESP32】ESP-IDF开发 | Timer硬件定时器+定时器闹钟例程

news2024/10/8 9:10:00

1. 简介

        ESP32内置4个64-bit通用定时器。每个定时器包含一个16-bit预分频器和一个64-bit可自动重新加载向上/向下计数器。ESP32的定时器分为2组,每组2个。定时器具有闹钟功能,闹钟事件会引发重新加载和触发中断。

        硬件定时器的时钟是由APB时钟提供的,APB时钟默认是80MHz;定时器时钟经过预分频器的分频后,才是定时器计数的频率。

2. API

2.1 创建定时器

esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *ret_timer);
  • config:定时器配置;
typedef struct {
    gptimer_clock_source_t clk_src;      /*!< GPTimer clock source */
    gptimer_count_direction_t direction; /*!< Count direction */
    uint32_t resolution_hz;              /*!< Counter resolution (working frequency) in Hz,
                                              hence, the step size of each count tick equals to (1 / resolution_hz) seconds */
    int intr_priority;                   /*!< GPTimer interrupt priority,
                                              if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */
    struct {
        uint32_t intr_shared: 1;         /*!< Set true, the timer interrupt number can be shared with other peripherals */
        uint32_t backup_before_sleep: 1; /*!< If set, the driver will backup/restore the GPTimer registers before/after entering/exist sleep mode.
                                              By this approach, the system can power off GPTimer's power domain.
                                              This can save power, but at the expense of more RAM being consumed */
    } flags;                             /*!< GPTimer config flags*/
} gptimer_config_t;

         clk_src:定时器时钟源;direction:定时器计数方向,向上或向下;resolution_hz:分辨率,即计数的频率;intr_priority:中断优先级,可选0-3,0为默认优先级。

  • ret_timer:定时器句柄。

2.2 删除定时器

esp_err_t gptimer_del_timer(gptimer_handle_t timer);
  • timer:定时器句柄。

2.3 注册中断回调

esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer_event_callbacks_t *cbs, void *user_data);
  • timer:定时器句柄;
  • cbs:中断回调;
  • user_data:传入回调函数的用户数据。

2.4 初始化闹钟

esp_err_t gptimer_set_alarm_action(gptimer_handle_t timer, const gptimer_alarm_config_t *config);
  • timer:定时器句柄;
  • config:配置项。
typedef struct {
    uint64_t alarm_count;  /*!< Alarm target count value */
    uint64_t reload_count; /*!< Alarm reload count value, effect only when `auto_reload_on_alarm` is set to true */
    struct {
        uint32_t auto_reload_on_alarm: 1; /*!< Reload the count value by hardware, immediately at the alarm event */
    } flags;                              /*!< Alarm config flags*/
} gptimer_alarm_config_t;

        alarm_count:闹钟触发值,触发频率 = 定时器频率 * 闹钟触发值;reload_count:重装载次数,为0表示一直重装载;auto_reload_on_alarm:使能闹钟重装载。

2.5 使能定时器

esp_err_t gptimer_enable(gptimer_handle_t timer);
  •  timer:定时器句柄。

2.6 启动定时器

esp_err_t gptimer_start(gptimer_handle_t timer);
  •  timer:定时器句柄。

3. 例程

        例程中实现一个定时器闹钟应用,间隔为1秒,每次闹钟触发就打印一条log。

#include "driver/gptimer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "esp_log.h"

#include <string.h>

#define TAG "app"

gptimer_handle_t gptimer = NULL;
SemaphoreHandle_t sem = NULL;

bool timer_timeout_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
{
    BaseType_t higherTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR(sem, &higherTaskWoken);
    return higherTaskWoken == pdTRUE;
}

void app_main()
{
    /* 初始化信号量 */
    sem = xSemaphoreCreateBinary();

    /* 初始化定时器 */
    gptimer_config_t timer_config = {
        .clk_src = GPTIMER_CLK_SRC_DEFAULT,  // 默认时钟,APB时钟
        .direction = GPTIMER_COUNT_UP,
        .resolution_hz = 1000000,  // 1MHz
        .intr_priority = 0,  // 默认中断优先级
    };
    ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));

    /* 注册回调 */
    gptimer_event_callbacks_t cbs = {
        .on_alarm = timer_timeout_cb,
    };
    ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, NULL));

    /* 初始化闹钟 */
    gptimer_alarm_config_t alarm_config = {
        .reload_count = 0,  // 不断重载
        .alarm_count = 1000000,
        .flags.auto_reload_on_alarm = true,
    };
    ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));

    /* 使能定时器和闹钟 */
    ESP_ERROR_CHECK(gptimer_enable(gptimer));
    ESP_ERROR_CHECK(gptimer_start(gptimer));

    while (1) {
        if (pdTRUE == xSemaphoreTake(sem, portMAX_DELAY)) {
            ESP_LOGI(TAG, "Timer timeout");
        }
    }
}

         初始化定时器参数,resolution_hz设置1000000,即计数频率为1MHz;向上计数。下面注册定时器中断回调函数,结构体里面只有一个on_alarm的回调;回调函数的第二个参数内容如下。

typedef struct {
    uint64_t count_value; /*!< Current count value */
    uint64_t alarm_value; /*!< Current alarm value */
} gptimer_alarm_event_data_t;

        主要就是当前定时器的寄存器值和闹钟寄存器的值,基本不会用到。回调函数返回是否需要切换操作系统上下文,如果在回调函数里面有信号量、互斥量这种操作就要注意;如果没有用到,返回假就行了。

        初始化闹钟,设置无限次重装载;触发值为1000000,即1秒触发一次。

        最后是一个死循环,在里面程序会不断等待信号量的到来,获取到信号量表示闹钟触发了一次,然后打印一句log。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2196009.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sqli-labs靶场第三关less-3

sqli-labs靶场第三关less-3 1、确定注入点 http://192.168.128.3/sq/Less-3/?id1 http://192.168.128.3/sq/Less-3/?id2 有不同回显&#xff0c;判断可能存在注入&#xff0c; 2、判断注入类型 输入 http://192.168.128.3/sq/Less-3/?id1 and 11 http://192.168.128.3/sq/L…

Linus Torvalds 要求内核开发人员编写更好的 Git 合并提交信息

昨天在宣布 Linux 6.12-rc2 内核时&#xff0c;Linus Torvalds 要求内核维护者在提交信息方面做得更好。Torvalds 尤其希望内核维护者在描述拉取请求中的变更时&#xff0c;能更好地使用积极、命令式的语气。 Linux创建者在6.12-rc2 公告中解释道&#xff1a; 总之&#xff0c…

Arduino UNO R3自学笔记21 之 Arduino基础篇学习总结

注意&#xff1a;学习和写作过程中&#xff0c;部分资料搜集于互联网&#xff0c;如有侵权请联系删除。 前言&#xff1a;目前将Arduino的大多数基础内容学习了&#xff0c;做个总结。 1.编程语言 学习单片机&#xff0c;在面向单片机编程时&#xff0c;语言是最基础的&#…

Docker exec bash -c 使用详解与 Python 封装示例

简介&#xff1a;docker exec 是 Docker 的一个实用命令&#xff0c;允许在正在运行的容器中执行命令。通过 bash -c 选项&#xff0c;可以执行复杂的命令串。 历史攻略&#xff1a; go&#xff1a;远程执行系统命令 Python&#xff1a;subprocess模块 Python-subprocess激…

代数结构基础 - 离散数学系列(八)

目录 1. 群&#xff08;Group&#xff09; 群的定义 群的示例 2. 环&#xff08;Ring&#xff09; 环的定义 环的示例 3. 域&#xff08;Field&#xff09; 域的定义 域的示例 域在密码学中的应用 4. 实际应用场景 1. 对称性与加密 2. 误差检测与纠正 3. 数据编码…

Maven介绍和使用

Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建Java项目的工具&#xff0c;它基于项目对象模型&#xff08;POM&#xff09;的概念&#xff0c;通过一小段描述信息来管理项目的构建。 依赖管理&#xff1a;方便快捷的管理项目依赖的资源包&#xff0c;避免…

消峰限流有哪几种方式?

消峰限流的方式 业务视角 验证码回答问题环节 技术视角 消息队列异步化用户请求 限流&#xff0c;对流量进行层层过滤 nginx 层限流&#xff0c; 一是控制速率 limit_req 漏桶算法 limit_req_zone $binary_remote_addr zonemylimit:10m rate2r/s; server { location / { lim…

Java面试题——第八篇(JVM)

1. JVM中有哪些垃圾回收算法 Java中的垃圾回收算法有以下几种 1. 标记-清除算法 工作原理&#xff1a;首先遍历堆中的对象&#xff0c;标记出所有存活的对象&#xff0c;接着清除未标记的对象。优点&#xff1a;实现简单&#xff0c;能够处理堆中的所有对象缺点&#xff1a;…

vue3 antd-design-vue3 日期组件语言不显示中文问题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、修改步骤 前言 随着ant-design-vue v3的推出&#xff0c;ant-design-vue官方把时间组件中的momentjs 替换成了dayjs&#xff0c;升级完后发现日期显示不正…

swift使用internvl2微调ocr文字检测(目标检测)

详细记录swfit微调interVL2-8B多模态大模型进行目标检测(附代码)-CSDN博客文章浏览阅读2k次,点赞45次,收藏14次。目标检测任务已经不是一个新鲜事了,但是多模态大模型作目标检测任务并不多见,本文详细记录swfit微调interVL2-8B多模态大模型进行目标检测的过程,旨在让更多…

Linux驱动开发(速记版)--单总线

第124章 单总线简介 124.1 单总线概述 单总线是一种串行通信协议&#xff0c;由Dallas Semiconductor开发&#xff0c;特点是用一根信号线实现双向数据传输和时钟同步&#xff0c;节省IO口且结构简单。 它广泛应用于传感器、存储器等。 硬件包括信号线、上拉电阻、设备和处理器…

代码随想录--字符串--重复的子字符串

题目 给定一个非空的字符串&#xff0c;判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母&#xff0c;并且长度不超过10000。 示例 1: 输入: "abab" 输出: True 解释: 可由子字符串 "ab" 重复两次构成。示例 2: 输入: "…

javaweb - 请求响应代码实现

简单参数 原始方式 在原始的web程序中&#xff0c;获取请求参数&#xff0c;需要通过HttpServletRequest对象手动获取。 RequestMapping("/simpleParam")public String simpleParam(HttpServletRequest request) {String name request.getParameter("name&…

基于Springboot+Vue的养老院管理系统的设计与实现 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

TMC2209堵转检测配置详细教程

按如下图将TMC2209和串口模块连接&#xff1a; 配置流程&#xff1a; 寄存器配置&#xff1a; 通用寄存器&#xff1a; 校验码见我之前文章&#xff1a;使用uart串口配置TMC2209模块_tmc2209 uart-CSDN博客 通用寄存器主要是配置第0和第1位&#xff0c;第1位要给1&#xff0…

python之详解列表

有序的可变容器&#xff0c;可以存储不同类型的元素。用中括号[]表示。 1、列表的查找访问 1.1、通过下标查找。 与字符串类似&#xff0c;列表也可通过 列表名[index] 的方式查找其中的元素。 索引的初始值为0&#xff0c;最大值为列表长度-1。 示例&#xff1a; list1 …

刷题 位运算 / 数学

面试经典 150 题 - 位运算 ⭐️⭐️67. 二进制求和 加法进位 class Solution { public:string addBinary(string a, string b) {int na a.size(), nb b.size();string ans;ans.reserve(max(na, nb) 1); // 预留空间&#xff0c;避免动态扩展时的性能损耗int carry 0;for …

platform bus平台总线详解

往期内容 驱动中的device和device_driver结构体-CSDN博客bus总线的相关结构体和注册逻辑-CSDN博客bus中设备驱动的probe触发逻辑和device、driver的添加逻辑-CSDN博客 前言 注&#xff1a;以下的代码皆摘自于linux 4.9.88版本的内核源码&#xff0c;不同版本可能有所出入。 之…

【EXCEL数据处理】保姆级教程 000016案例 EXCEL的vlookup函数。

【EXCEL数据处理】000016案例 vlookup函数。 前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】保姆级教…

【动态规划】斐波那契模型 dp

动态规划的步骤&#xff1a; 状态表示。所谓状态表示就是 dp 表里的值表示什么含义&#xff0c;那么状态表示怎么找呢&#xff1f; a. 题目要求 b. 经验&#xff08;以某一个位置为结尾 / 起点&#xff09; 题目要求 c. 分析问题的过程中发现重复子问题状态转移方程。dp[ i ] …