当前位置: 首页 > news >正文

ESP32-C3实现定时器的启停(Arduino IDE)

1概述

ESP32-C3微控制器有多个定时器,这些定时器可用于各种用途,包括计时、生成PWM信号、测量输入信号的频率等。以下是ESP32-C3上可用的定时器资源:

  1. 两个硬件定时器

    • 定时器0:这是一个通用定时器,通常用于操作系统的任务调度。
    • 定时器1:同样是一个通用定时器,也可以用于其他目的。
  2. 八个LED控制定时器

    • 这些定时器专门用于LED控制,例如,它们可以用来生成PWM信号来控制LED的亮度。
  3. 两个I2S DMA定时器

    • 这些定时器用于I2S(Inter-IC Sound)接口的DMA(Direct Memory Access)操作。
  4. 一个RMT(Remote Control)定时器

    • RMT定时器用于生成和接收红外遥控信号。

这些定时器资源在ESP32-C3上的分配和功能可能会根据具体的应用和ESP-IDF(Espressif IoT Development Framework)的版本有所不同。硬件定时器(定时器0和定时器1)通常用于最关键的计时任务,而其他定时器则可用于特定外设的控制。

2实现定时器的启停(1秒)

#include <Arduino.h>hw_timer_t *timer = NULL;
volatile int seconds = 0;
volatile bool printFlag = false;  // 添加一个标志来指示是否需要打印// 定时器中断服务例程
void IRAM_ATTR tim1Interrupt() {seconds++;  // 每次中断增加秒数printFlag = true;  // 设置打印标志
}void setup() {Serial.begin(115200);timer = timerBegin(0, 80, true);  // 初始化定时器timerAttachInterrupt(timer, &tim1Interrupt, true);  // 绑定中断函数timerAlarmWrite(timer, 1000000, true);  // 设置报警值为 1 秒timerAlarmEnable(timer);  // 启用定时器中断
}void loop() {if (printFlag) {Serial.print("Seconds passed: ");Serial.println(seconds);printFlag = false;  // 重置打印标志}
}

3注意串口不能放在定时器中断内部

,放进去会产生内存溢出

  1. 串行缓冲区溢出:如果在 Serial.print 或 Serial.println 调用之间有太多的数据要发送,而串行通信速度跟不上,串行缓冲区可能会溢出,导致数据丢失或混乱。

  2. 中断处理和串行通信冲突:由于 Serial.print 和 Serial.println 不是原子操作,如果在它们执行过程中发生中断,可能会导致输出不完整或混乱。

  3. 其他代码或库的干扰:如果在您的程序中还有其他代码或库使用串行端口进行通信,它们可能会与您的打印语句冲突。

4重点解释

  1. timerBegin(0, 80, true);

    • timerBegin 函数用于初始化定时器,并返回一个定时器句柄。
    • 第一个参数 0 指定要使用的定时器组。ESP32-C3 有两个定时器组,每个组有两个定时器。这里选择定时器组0。
    • 第二个参数 80 是预分频器的值。定时器的时钟源通常是 APB(Advanced Peripheral Bus)时钟,预分频器用于降低时钟频率。预分频器值设置为80,意味着定时器的时钟频率是 APB 时钟的 1/80。
    • 第三个参数 true 表示定时器是向上计数的,即从0开始,每次计数增加,直到达到设定的报警值。
  2. timerAttachInterrupt(timer, &tim1Interrupt, true);

    • timerAttachInterrupt 函数用于将中断服务例程(ISR)与定时器中断关联起来。
    • 第一个参数 timer 是由 timerBegin 返回的定时器句柄。
    • 第二个参数 &tim1Interrupt 是指向中断服务例程的指针。当定时器达到报警值时,将调用此函数。
    • 第三个参数 true 表示在中断服务例程执行期间,定时器中断应该被禁用。这是为了避免在中断服务例程执行期间再次进入中断。
  3. timerAlarmWrite(timer, 1000000, true);

    • timerAlarmWrite 函数用于设置定时器的报警值,即定时器达到该值时触发中断。
    • 第一个参数 timer 是定时器句柄。
    • 第二个参数 1000000 是定时器的报警值,单位是定时器时钟周期的个数。由于定时器时钟频率是 APB 时钟的 1/80,因此 1000000 个周期大约等于 1 秒(假设 APB 时钟频率为 80MHz)。
    • 第三个参数 true 表示报警值设置后,定时器会自动重载并重新开始计数,从而实现周期性中断。
  4. timerAlarmEnable(timer);

    • timerAlarmEnable 函数用于启用定时器中断。
    • 参数 timer 是定时器句柄。
    • 一旦启用,定时器开始计数,当达到设定的报警值时,将调用之前关联的中断服务例程。

时间计算

以下是计算步骤:

  1. 确定 APB 时钟频率: ESP32-C3 的 APB 时钟频率默认为 80 MHz(即每秒 80,000,000 周)。

  2. 应用预分频器: 您设置的预分频器值为 80,这意味着定时器时钟频率是 APB 时钟频率的 1/80。

    定时器时钟频率 = APB 时钟频率 / 预分频器值
    定时器时钟频率 = 80 MHz / 80 = 1 MHz (即每秒 1,000,000 周)
    
  3. 计算定时器计数周期: 您设置的报警值为 1,000,000,这是定时器达到后触发中断的计数值。

    计时时间 = 报警值 / 定时器时钟频率
    计时时间 = 1,000,000 / 1,000,000 = 1 秒

 

1分钟

#include <Arduino.h>hw_timer_t *timer = NULL;
volatile int minutes = 0;
volatile bool printFlag = false;  // 添加一个标志来指示是否需要打印// 定时器中断服务例程
void IRAM_ATTR tim1Interrupt() {minutes++;  // 每次中断增加分钟数printFlag = true;  // 设置打印标志
}void setup() {Serial.begin(115200);timer = timerBegin(0, 80, true);  // 初始化定时器timerAttachInterrupt(timer, &tim1Interrupt, true);  // 绑定中断函数timerAlarmWrite(timer, 60000000, true);  // 设置报警值为 60 秒(即 1 分钟)timerAlarmEnable(timer);  // 启用定时器中断
}void loop() {if (printFlag) {Serial.print("Minutes passed: ");Serial.println(minutes);printFlag = false;  // 重置打印标志}
}

30分钟 

#include <Arduino.h>hw_timer_t *timer = NULL;
volatile int minutes = 0;
volatile bool printFlag = false;  // 添加一个标志来指示是否需要打印// 定时器中断服务例程
void IRAM_ATTR tim1Interrupt() {minutes += 30;  // 每次中断增加30分钟数printFlag = true;  // 设置打印标志
}void setup() {Serial.begin(115200);timer = timerBegin(0, 80, true);  // 初始化定时器timerAttachInterrupt(timer, &tim1Interrupt, true);  // 绑定中断函数timerAlarmWrite(timer, 1800000000, true);  // 设置报警值为 1800 秒(即 30 分钟)timerAlarmEnable(timer);  // 启用定时器中断
}void loop() {if (printFlag) {Serial.print("Minutes passed: ");Serial.println(minutes);printFlag = false;  // 重置打印标志}
}

相关文章:

ESP32-C3实现定时器的启停(Arduino IDE)

1概述 ESP32-C3微控制器有多个定时器&#xff0c;这些定时器可用于各种用途&#xff0c;包括计时、生成PWM信号、测量输入信号的频率等。以下是ESP32-C3上可用的定时器资源&#xff1a; 两个硬件定时器&#xff1a; 定时器0&#xff1a;这是一个通用定时器&#xff0c;通常用于…...

centos升级g++使其支持c++17

centos升级g使其支持c17 升级g的原因现象原因 升级g方法更新镜像源yum升级g版本 总结 升级g的原因 现象 编译最新版本的jsoncpp报一下错误 jsontest.h:87:37: error: ‘hexfloat’ is not a member of ‘std’oss << std::setprecision(16) << std::hexfloat &l…...

Pytest日志收集器配置

前言 在pytest框架中&#xff0c;日志记录&#xff08;logging&#xff09;是一个强大的功能&#xff0c;它允许我们在测试期间记录信息、警告、错误等&#xff0c;从而帮助调试和监控测试进度。 pytest与Python标准库中的logging模块完美集成&#xff0c;因此你可以很容易地在…...

Morris算法(大数据作业)

我只能说&#xff0c;概率证明真的好难啊&#xff01;(&#xff1b;′⌒) 这也证明我的概率论真的学的很差劲&#xff0c;有时间一定要补补/(ㄒoㄒ)/~~ 算法不难证明难&#xff01; 当一个数足够大时&#xff0c;能不能用更少的空间来近似表示这个整数n&#xff0c;于是&…...

TCP/IP协议 【三次握手】过程简要描述

当建立TCP连接时&#xff0c;三次握手的作用简要描述如下&#xff1a; 第一次握手&#xff08;客户端向服务器发送SYN包&#xff09;&#xff1a;客户端发送SYN包给服务器&#xff0c;确认服务器是否在线并等待响应。 第二次握手&#xff08;服务器向客户端发送SYNACK包&…...

docker 数据管理,数据持久化详解 二 数据卷容器

数据卷和数据卷容器核心区别 持久性对比 数据卷&#xff1a;当您直接在启动容器时指定了一个数据卷&#xff08;例如&#xff0c;使用docker run -v /data&#xff09;&#xff0c;这个数据卷会自动创建&#xff0c;并且其内容会在容器停止或删除后继续存在。您可以随时通过Do…...

Logrotate:Linux系统日志轮转和管理的实用指南

Logrotate是Linux系统中用于自动化管理日志文件的强大工具&#xff0c;它能够高效、安全地轮转、压缩和清理日志文件&#xff0c;从而有效控制日志文件大小&#xff0c;节省磁盘空间&#xff0c;并显著提升系统可维护性和安全性。本文档将提供Logrotate的实用指南&#xff0c;涵…...

八股面试3(自用)

基本数据类型和引用数据类型区别 java中数据类型分为基本数据类型和引用数据类型 8大基本数据类型 1.整数&#xff1a;int&#xff0c;long&#xff0c;short&#xff0c;byte 2.浮点类型&#xff1a;float&#xff0c;double 3.字符类型&#xff1a;char 4.布尔类型&…...

【微服务】springboot3 集成 Flink CDC 1.17 实现mysql数据同步

目录 一、前言 二、常用的数据同步解决方案 2.1 为什么需要数据同步 2.2 常用的数据同步方案 2.2.1 Debezium 2.2.2 DataX 2.2.3 Canal 2.2.4 Sqoop 2.2.5 Kettle 2.2.6 Flink CDC 三、Flink CDC介绍 3.1 Flink CDC 概述 3.1.1 Flink CDC 工作原理 3.2 Flink CDC…...

【Android】浅析OkHttp(1)

【Android】浅析OkHttp&#xff08;1&#xff09; OkHttp 是一个高效、轻量级的 HTTP 客户端库&#xff0c;主要用于 Android 和 Java 应用开发。它不仅支持同步和异步的 HTTP 请求&#xff0c;还支持许多高级功能&#xff0c;如连接池、透明的 GZIP 压缩、响应缓存、WebSocke…...

Generate-on-Graph

目录 摘要1 引言2 相关工作4 不完整知识图谱问答&#xff08;IKGQA&#xff09;4.1 任务介绍4.2 数据集构建 5 Generate-on-Graph (GoG) 摘要 为了解决大型语言模型&#xff08;LLMs&#xff09;在知识不足和幻觉问题上的困扰&#xff0c;众多研究探索了将LLMs与知识图谱&…...

学习笔记——交换——STP(生成树)简介

一、技术背景 1、生成树技术背景 交换机单线路组网&#xff0c;存在单点故障(上左图)&#xff0c;上行线路及设备都不具备冗余性&#xff0c;一旦链路或上行设备发生故障&#xff0c;业务将会中断。 为了使得网络更加健壮、更具有冗余性&#xff0c;将拓扑修改为(上右图)接入…...

【Linux从入门到精通一】操作系统概述与Linux初识

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…...

Git 深度解析 —— 从基础到进阶

目录 1. Git 基础概念 1.1 版本控制 (Version Control) 1.2 分布式版本控制 (Distributed Version Control) 1.3 核心概念 1.4 Git 工作流程 2. Git 常用命令 2.1 初始化仓库 2.2 添加文件 2.3 提交修改 2.4 查看状态 2.5 查看历史记录 2.6 切换分支 2.7 创建分支…...

PCIE-变量总结

1.changed_speed_recovery&#xff1a; 表示链路双方已经将链路速率协商为更高的速率。 在configuration.complete状态下此变量会reset成0&#xff1b; 当前状态在recovery.rcvrlock状态&#xff1a; 在经过24ms的timeout之后&#xff0c;任何一个已经configured的lane&…...

【iOS】AFNetworing初步学习

文章目录 前言OC的网络请求步骤单例封装网络请求使用AFNetworking进行网络请求 前言 在暑假&#xff0c;学习了一些简单的网络请求的内容&#xff0c;本周学习了AFNetworking的基本使用&#xff0c;通过本篇博客进行一个简单的介绍。 OC的网络请求步骤 简单的网络请求主要有…...

【数据结构】堆的创建

Heap.h #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<assert.h>//创建堆结构体 typedef int HPDateType; typedef struct Heap {HPDateType* a;int size;int capacity; }HP;//堆的初始化 void HPInit(HP* php);//堆的销毁 voi…...

Linux下Git操作

一、基本命令 1、创建 git 目录&#xff08;工作区&#xff09; mkdir gitcode 2、创建本地仓库&#xff0c;生成 .git 隐藏目录 git init 3、设置配置项 git config user.name "xxx" git config user.email "....." 4、查看配置项 git config -l …...

缺失d3dx9_42.dll如何修复,d3dx9_42.dll故障的6种修复方法分享

在电脑使用过程中&#xff0c;许多游戏玩家和软件用户可能都遇到过d3dx9_42.dll丢失的问题。这个问题会导致游戏或软件无法正常运行&#xff0c;给用户带来诸多不便。本文将详细解读d3dx9_42.dll丢失的原因、影响及解决方案&#xff0c;帮助大家顺利解决这个问题。 一、d3dx9_4…...

深入理解Android WebView的加载流程与事件回调

文章目录 一、WebView 加载流程时序图二、WebView 加载流程回调函数说明三、AwContents3.1 主要功能和职责3.2 架构和实现3.3 使用场景 四、利用WebView回调函数检测白屏4.1 使用onPageStarted和onPageFinished检测加载时间4.2 利用onReceivedError和onReceivedHttpError检测加…...

马斯克最新对话:AI 毁灭人类的概率有 20%,但它将创造一个没有钱的“全民高收入”时代

“我宁愿看到结局&#xff0c;也不愿无聊老去。”编译 | 王启隆来源 | youtu.be/N5KCm_55xeQ出品丨AI 科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;在此前结束的 2026 Abundance Summit 上&#xff0c;X奖基金会创始人彼得戴曼迪斯&#xff08;Peter Diamandis&…...

WPF MES 产线执行系统:AGV与立库协同控制的核心实现

ERP MES 两套系统源代码 WPF AGV C# WPF开发。 A&#xff0c;WPF MES 上位机产线执行系统。 1&#xff0c; 完整纯源代码&#xff1b; 2&#xff0c; AGV自动调度&#xff1b; 3&#xff0c; SQLSERVER数据库。 带附加文件。 4&#xff0c; WPF各种技术应用。 5&#xff0c; 数…...

HJ165 小红的优惠券

题目题解(36)讨论(31)排行 入门 通过率&#xff1a;49.28% 时间限制&#xff1a;1秒 空间限制&#xff1a;256M 知识点贪心 校招时部分企业笔试将禁止编程题跳出页面&#xff0c;为提前适应&#xff0c;练习时请使用在线自测&#xff0c;而非本地IDE。 描述 小红的购物车…...

Flutter 状态管理:Provider, Bloc, GetX 对比

Flutter作为跨平台开发框架&#xff0c;其状态管理一直是开发者关注的核心问题。不同的状态管理方案各有优劣&#xff0c;如何选择适合项目的方案成为关键。本文将对比三种主流方案——Provider、Bloc和GetX&#xff0c;从学习成本、代码结构、性能表现等维度展开分析&#xff…...

2025届毕业生推荐的降重复率神器解析与推荐

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 如果要降低AIGC检测率&#xff0c;那就得着重从文本特征方面着手。首先&#xff0c;词汇多样…...

典型的TCP客户端单次事务处理VI 通过已建立的TCP连接,发送一段数据(命令/字符串),等待设备响应后读取指定字节数的返回数据

这个VI程序框图详细解析&#xff08;LabVIEW TCP通信事务VI&#xff09;这是一个典型的TCP客户端单次事务处理VI&#xff08;常命名为“TCP Send & Receive.vi”或“TCP通信子VI”&#xff09;。 它的核心功能是&#xff1a;通过已建立的TCP连接&#xff0c;发送一段数据&a…...

别再傻傻分不清了!微信支付H5、JSAPI、Native三种模式到底怎么选?附服务商模式实战代码

微信支付三大模式深度解析&#xff1a;从技术选型到服务商实战 每次面对微信支付的H5、JSAPI和Native三种模式&#xff0c;不少开发者都会陷入选择困难症。去年我们团队在为一个连锁零售品牌做线上商城升级时&#xff0c;就因为在模式选择上判断失误&#xff0c;导致小程序支付…...

UniApp安卓端MQTT连接踩坑记:mqtt.js 3.0版本与原生插件到底怎么选?

UniApp安卓端MQTT方案深度对比&#xff1a;从协议适配到性能优化的实战指南 去年接手一个智能家居控制项目时&#xff0c;我曾在mqtt.js和原生插件之间反复横跳。那个凌晨三点还在调试WSS协议的夜晚让我明白——技术选型从来不是非黑即白的选择题。本文将用真实项目经验&#…...

【Matter】Ubuntu 22.04下chip-tool编译实战:避坑指南与代理配置详解

1. Ubuntu 22.04环境准备与基础配置 在开始编译Matter的chip-tool之前&#xff0c;我们需要先准备好Ubuntu 22.04的开发环境。这个环节虽然基础&#xff0c;但往往决定了后续编译过程的顺利程度。我曾在多个项目中验证过&#xff0c;一个干净的Ubuntu 22.04系统是最稳定的编译环…...

Whisper.cpp 跨平台编译与语音识别实战指南

1. Whisper.cpp 是什么&#xff1f;能做什么&#xff1f; 第一次接触 Whisper.cpp 是在一个语音转文字的需求场景中。当时需要处理大量会议录音&#xff0c;但发现主流的语音识别工具要么需要联网&#xff0c;要么对硬件要求极高。直到发现了这个基于 C 实现的轻量级解决方案&a…...