资料介绍
描述
这一切是关于什么的?
你可以拖延,但时间不会。本杰明·富兰克林
时间的唯一原因是一切都不会一下子发生。艾尔伯特爱因斯坦
我们所要做的就是决定如何处理给我们的时间。JRR托尔金
我不能说比这些伟大的人更好!
在我们的草图中管理时间是我们需要经常做的事情,通过明智地使用计时器,我们能够有效地设计、管理和处理时间驱动的事件。
本文提供了一种在您的草图中使用任意数量的计时器的技术(方法),每个计时器都是独立的、非阻塞的,并且它们都可以同时运行。该技术易于理解,易于实现,不使用 delay() 函数,也不需要最终用户实现定时器中断服务程序 (ISR)。
为什么计时器有用?
很多时候我们需要定期做一些事情,例如每 1/100 秒读取一次传感器,跟踪和处理超时,每 1/2 秒处理一次心跳,等等。在这种情况下,我们需要使用一个或多个计时器来确保我们可以做所有我们需要做的事情。这就是本文提供的技术 (ez_timers) 非常有用的地方。
在这篇文章中,一个草图定义了您在草图中实现 ez_timers 提供的技术所需的所有数据和功能,您可以在此基础上进行草图设计、决策控制和流程。
为了展示该技术的简单性和强大功能,提供了一个基于多个 LED(八个)的示例,每个 LED 由各自的定时器控制,以不同的时间间隔打开和关闭它们。正如将要看到的,该技术以直接和简洁的方式实现。它很容易扩展到很多很多用途。
ez_timers 设计
在我们开始看示例草图之前,让我们看一下 ez_timers 技术和代码的组成部分。
ez_timers 有两个部分:
1. 其数据结构和数据要求,以及
2. 一些终端用户可访问的简单功能。
让我们来看看其中的每一个:
一、数据结构和数据要求
#define max_timers 8
#define elapsed true
#define not_elapsed !elapsed
#define active true
#define not_active !active // double defined for user preference
#define inactive not_active // double defined for user preference
uint8_t timer; // general variable for use dealing with timers
// timer control struct(ure)
struct timer_control {
bool timer_status; // records status of a timer - active or not active
uint32_t start_time;// records the millis time when a timer is started
} timers[max_timers];// declare an entry for each timer - 0:(max_timers-1)
我们首先注意到的是宏' max_timers
'。在“开箱即用”(OOTB)草图中,它设置为 8,因此草图将在编译时将自身配置为 8 个计时器。然后这些将可从 0 到 7 引用。使用此宏定义您希望在草图中配置多少个计时器。
接下来,我们将看到 ez_timer 函数使用的许多宏,最终用户代码也可以/应该使用这些宏来测试特定条件的状态。不过,在这一点上,我只观察到其中两个宏可以相同地使用,具体取决于最终用户的偏好。它们是 ' not_active
' 和 ' inactive
' - 它们是同一个东西。当我们讨论 ez_functions 时,更多关于使用这些宏的上下文。
下一个声明只是一个无符号字节,timer
可以在整个草图中用作工作变量来引用任何计时器(最多 255 个),例如,在 for 循环等中。
ez_timers 的核心是数据结构(ure)' timer_control
'。这定义了两个数据项/类型,它们是 ' timer_status
' ( bool
) 和 ' start_time
' ( uint32_t
- 无符号 32 位整数)。每个配置的计时器在此结构中都有自己的条目,从 0 到 (' max_timers
' -1)。' timer_control
' 数据类型 struct(ure) 然后被声明为 ' timers
'。此数据结构(ure)使用' timers
'引用,例如' timers[2].timer_status
'、' timers[timer].start_time
'等。
2.ez_timerFunctions
只有三个 ez_timer 函数:
//
// set the given timer active and note start time in milliseconds
//
void start_timer(uint8_t timer) {
if (timer < max_timers) {
// valid timer
timers[timer].timer_status = active; // mark this timer as active
timers[timer].start_time = millis(); // record time this timer is started
}
}
//
// cancel (stop) the given timer
//
void stop_timer(uint8_t timer) {
if (timer < max_timers) {
// valid timer
timers[timer].timer_status = inactive; // mark this timer as inactive
}
}
//
// Function determines if the time has elapsed for given timer, if active.
// The elapsed_time parameter is in milliseconds.
//
bool timer_elapsed(uint8_t timer, uint32_t elapsed_time) {
if (timer < max_timers) {
// valid timer
if (timers[timer].timer_status == active) {
// timer is active so check elapsed time
if (millis() - timers[timer].start_time >= elapsed_time) {
// this timer has elapsed
timers[timer].timer_status = inactive; // mark this timer no longer active
return elapsed;
}
}
}
return not_elapsed;
}
让我们更详细地看一下这些函数:
1. ' ' - 将给定的计时器设置为活动并以毫秒为单位记录开始时间。唯一的参数是要启动的定时器编号:0 到(' '-1)。start_timer
max_timers
2. ' ' - 将给定的计时器标记为非活动/非活动。唯一的参数是要停止的定时器编号:0 到 (' '-1)。stop_timer
max_timers
3. ' ' - 应尽可能定期调用此函数,以检查给定的计时器是否已过,如果已过,应遵循哪些操作。该函数返回两个值之一 -如果计时器已完成,则返回“ ”,否则返回“ ”。请注意,如果计时器未激活,此函数还将返回值 ' '(与 ' ' 相同)。timer_elapsed
elasped
not_elapsed
not_elapsed
not_active
该函数有两个参数,第一个是要检查的计时器编号:0 到 (' max_timers
'-1),第二个是要检查的经过时间(以毫秒为单位)。例如:
if (timer_elasped(5, 10000) == elapsed){...} else{...}
检查计时器 5 以查看自启动以来是否已过 10 秒。
该函数最适合用于遍历所有已配置计时器(0 到 (' max_timers
' -1))的 for 循环。还要注意的是,一旦给定的计时器已经过去,如果它是连续发生的需求,则需要立即重新启动。
一个例子
已经向 OOTB 提供了 ez_timers 草图,并提供了如何使用它的示例。该示例配置了八个 LED 并为每个 LED 使用一个计时器,以不同的时间间隔使它们闪烁。为了定义和控制 LED,还使用了 struct(ure) 数据类型,该数据类型很容易根据最终用户的需求进行修改(减少或增加 LED 的数量或改变闪光率)。
提供的示例是一种简单的方法,可以处理 LED 以提供定时光效果。但是,对于处理经过的计时器结果的更通用的方法,switch-case 构造会特别好用,例如:
...
for (timer = 0;time < max_timers; timer++){
if (timer_elasped(timer, 10000) == elapsed){
switch (timer){
case 0: // timer 0
// restart this timer and process the event
start_timer(timer);
...
break;
case 1: // timer 1
// do not restart this timer, just process the event
...
break;
case 2: // timer 2
...etc
break;
...
}
}
}
...
在上面的示例代码中,已经创建了许多从 0、1、2、...、(- max_timers
1) 引用的计时器,每个经过的计时器事件都由相应的案例段处理。
最后
ez_timers 技术可以提供一种易于实现的方法,用于在您的草图中运行多个计时器。但是,如果您需要一个更全面、更复杂的计时器解决方案,它不仅可以容纳经过时间的计时器,还可以容纳实时计时器,那么请查看同一作者的REM_SYS (见下文),它给出了一个更工业化和完全异步的解决方案。
REM_SYS 支持经过时间和实时计时器(提醒)。可以将所有计时器类型定义为一次性事件、重复发生而没有结束或重复发生直到达到/经过给定时间。不仅如此,对于每种类型,可以定义子类型以帮助决策控制,还可以为每个定义的计时器(提醒)提供用户定义参数的“有效负载”,这些参数在达到计时器事件时返回(经过或实时)。REM_SYS 甚至可以在 UNO 微控制器上运行,并且可以配置有或没有实时时钟。
延伸阅读
您可能还会发现同一作者的这些贡献有趣且有用:
- 为您的草图添加心跳- 包括一种可见的方式来查看您的代码在您的微控制器上运行,而无需任何额外的组件或接线!
- 一个灵活、可扩展的库 (ez_SIPO8_lib) - 支持实现多个串行输入/串行输出 IC、74HC595,无论是单独还是在级联组中,最多 255 个 IC(2040 个输出引脚)
- 通用开关库 (ez_switch_lib) ,适用于大多数开关类型和接线方案,包含新颖的功能
- 了解和使用按钮开关,基本知识- 按钮开关,一个简单但通常很棘手的工具包。本教程提供了实现简单按钮开关的来龙去脉,可以灵活地探索电路设计的差异、不同的读取方法和去抖动。
- 中断驱动按钮开关- 一种将按钮开关与外部中断联系起来的方法和示例。
- 拨动开关- 如何可靠地读取拨动式开关。
- Buttons & Lights Game - 使用按钮开关和 LED 带来一点乐趣。
- External Interrupts,一个通用框架——一个支持并发异步多个中断的框架。配置多个不同特性的外部中断,并添加代码提供中断后异步处理。
- REM_SYS, A Programmatic Timed Reminder Alerting ,一个用于已用和实时异步定时警报的编程框架。定义任意数量的计时器(提醒)警报(亚秒到小时)并异步处理。
- 厨房计时器开源设计 0次下载
- 魔方计时器开源分享 1次下载
- GymGeneral运动间歇计时器开源分享 0次下载
- 工业计时器警报开源分享 0次下载
- 游戏回合时间计时器开源分享 0次下载
- 简单的健身计时器开源分享 0次下载
- 自动皂液器与计时器开源 0次下载
- 带继电器的Arduino倒数计时器开源分享 0次下载
- RFID竞赛计时器开源分享 2次下载
- 红绿灯计时器开源分享 4次下载
- 电子计时器pcb图下载 9次下载
- 数电模电知识之短跑计时器系统方案设计 10次下载
- 时钟计时器设计与制作 42次下载
- 数字计时器Multisim设计 0次下载
- 时钟计时器元件清单 28次下载
- 使用定时器和数码管实现简易秒计时器 558次阅读
- 使用51单片机开发板制作60秒时钟计时器 1429次阅读
- 如何使用7段显示器和分立元件构建一个飙车计时器电路 821次阅读
- 构建一个计时器电路的教程 1843次阅读
- 在系统重新启动期间禁用看门狗计时器 1465次阅读
- 自动数字计时器是如何工作的? 3602次阅读
- 基于51单片机的计时器设计 1.4w次阅读
- 利用Excel制作秒表计时器 1w次阅读
- 如何用AT89C2051单片机自制一个倒计时器 9167次阅读
- 51单片机时钟计时器学习板的基本原理解析 4528次阅读
- 三菱plc计时器编程实例 2.9w次阅读
- 74Ls192构成倒计时器_基于74LS192的30秒倒计时设计详解 8w次阅读
- 基于VHDL的电子计时器的设计方法详解 2.2w次阅读
- 24秒倒计时电路的简单制作 6.8w次阅读
- 门球比赛计时器电路图 2953次阅读
下载排行
本周
- 1储能电源市场分析
- 7.99 MB | 8次下载 | 免费
- 2储能电源市场分析报告
- 2.61 MB | 6次下载 | 免费
- 3磁环电感定制时应该注意什么
- 0.32 MB | 2次下载 | 免费
- 4labview文档教程资料(一)
- 24.29 MB | 2次下载 | 免费
- 5轻触三功能+常按 SOS 功能手筒LED驱动ICSD3302数据手册
- 0.60 MB | 1次下载 | 2 积分
- 6英集芯IP5353 QFN32 规格书pdf
- 2.70 MB | 1次下载 | 免费
- 7NCV78763R1DAGEVB子板数据手册
- 533.41 KB | 次下载 | 免费
- 8500mA,高效 MicroSiP™ 降压转换器TPS8269xSIP数据表
- 918.92KB | 次下载 | 免费
本月
- 1ES9038PRO解码芯片的电路原理图介绍
- 0.25 MB | 35次下载 | 5 积分
- 2STM32国内外发展现状
- 1.15 MB | 13次下载 | 免费
- 3传感芯片选型指南
- 3.60 MB | 11次下载 | 免费
- 4ATmega8芯片中文手册
- 2.45 MB | 8次下载 | 1 积分
- 5储能电源市场分析
- 7.99 MB | 8次下载 | 免费
- 6TDK电容器产品指南
- 11.88 MB | 7次下载 | 1 积分
- 72A多电池高效开关充电器AN_SY6912A中文资料规格书
- 1.43 MB | 7次下载 | 免费
- 8储能电源市场分析报告
- 2.61 MB | 6次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935086次下载 | 免费
- 2开源硬件-PMP21529.1-4 开关降压/升压双向直流/直流转换器 PCB layout 设计
- 1.48MB | 420050次下载 | 免费
- 3Altium DXP2002下载入口
- 未知 | 233068次下载 | 免费
- 4电路仿真软件multisim 10.0免费下载
- 340992 | 191317次下载 | 免费
- 5十天学会AVR单片机与C语言视频教程 下载
- 158M | 183316次下载 | 免费
- 6labview8.5下载
- 未知 | 81567次下载 | 免费
- 7Keil工具MDK-Arm免费下载
- 0.02 MB | 73788次下载 | 免费
- 8NI LabVIEW中实现3D视觉的工具和技术
- 未知 | 70088次下载 | 免费
评论
查看更多