CAPL 编程系列教程的第十七期内容,主要讲解 CAPL 中的一个特殊且重要的数据类型/机制:定时器 (Timer)
CAPL 编程系列教程 - 第十七期:定时器 (Timer)
一、 课程回顾与本期目标
- 回顾: 前面学习了 CAPL 的基础数据类型、复合数据类型(数组、结构、枚举)、运算符、分支和循环结构、函数定义与调用。
- 本期目标: 学习 CAPL 中的定时器,理解如何使用定时器实现延迟执行或周期性执行代码块。
二、 定时器 (Timer) 的基本概念
- 作用: 用于在指定的时间间隔后执行某段代码,或者按照设定的周期重复执行某段代码
。这在需要模拟周期性行为(如周期发送报文)或在特定延迟后执行动作的场景中非常关键 。 - 数据类型: CAPL 提供两种定时器类型
: timer: 秒级定时器,时间单位是秒。msTimer: 毫秒级定时器 (millisecond timer),时间单位是毫秒。
- 事件驱动关联: 定时器变量本身不直接赋值,而是与一个事件处理代码块 (
on timer) 相关联,该代码块定义了定时器到期(触发)时需要执行的操作。
三、 定时器的声明与事件处理
- 声明定时器变量:
- 必须在全局变量区
variables { ... }内声明。不能在局部代码块(如 on key或函数内部)声明。 - 语法:
timer TimerName1;或msTimer TimerName2;。 - 示例:
Code snippet
variables { timer timer1; // 声明一个秒级定时器变量 timer1 msTimer timer2; // 声明一个毫秒级定时器变量 timer2 } - 声明后,CAPL Browser 可能会有绿色下划线提示,表明尚未定义对应的
on timer事件处理块。
- 必须在全局变量区
- 定义
on timer事件处理块:- 必须为每个声明的定时器变量定义一个对应的
on timer事件处理块。 - 语法:
Code snippet
on timer TimerName { // TimerName 必须与 variables 中声明的定时器变量名一致 // 定时器到期(触发)时执行的代码 } - 作用: 定义当名为
TimerName的定时器到期被触发时,需要执行的具体操作(如发送报文、修改变量、调用函数等)。 - 示例:
Code snippet
on timer timer1 { write("timer1 定时器触发了!"); } on timer timer2 { write("timer2 定时器触发了!"); }
- 必须为每个声明的定时器变量定义一个对应的
四、 启动和控制定时器
-
启动单次定时器 (
setTimer):- 作用: 设置一个定时器,在指定的时间之后触发一次其对应的
on timer事件。 - 语法:
setTimer(TimerName, DelayTime);。 TimerName: 要启动的定时器变量名。DelayTime: 延迟的时间。如果TimerName是timer类型,单位是秒;如果是msTimer类型,单位是毫秒。 - 示例:
Code snippet
on key 'a' { setTimer(timer1, 2); // 2 秒后触发 timer1 一次 setTimer(timer2, 4000); // 4000 毫秒 (4秒) 后触发 timer2 一次 }
- 作用: 设置一个定时器,在指定的时间之后触发一次其对应的
-
实现周期性定时器 (使用
setTimer):- 思路: 在定时器的
on timer事件处理块内部,执行完所需操作后,再次调用setTimer为其自身设置下一次触发。 - 示例:
Code snippet
on timer timer1 { write("timer1 定时器触发了!(每 2 秒一次)"); setTimer(timer1, 2); // 再次设置 2 秒后触发 } on timer timer2 { write("timer2 定时器触发了!(每 5 秒一次)"); setTimer(timer2, 5000); // 再次设置 5000 毫秒后触发 } on key 'a' { setTimer(timer1, 2); // 首次启动 setTimer(timer2, 5000); // 首次启动 } - 这种方式对
timer和msTimer都适用。
- 思路: 在定时器的
-
启动周期性毫秒定时器 (
setTimerCyclic):- 作用: 专门用于启动毫秒级 (
msTimer) 定时器,使其按照指定的周期自动重复触发。 - 语法:
setTimerCyclic(msTimerName, CycleTime);或setTimerCyclic(msTimerName, FirstDelay, CycleTime);。 msTimerName: 必须是msTimer类型的定时器变量名。不能用于timer类型的变量。 CycleTime: 重复触发的周期,单位是毫秒。 FirstDelay(可选): 第一次触发前的延迟时间,单位是毫秒。如果省略,则第一次触发也在CycleTime之后;如果为 0,则几乎立即触发第一次。 - 优点: 比在
on timer中手动重置setTimer更简洁方便。 - 示例:
Code snippet
variables { msTimer timer4; } on timer timer4 { write("timer4 定时器触发!(周期 4 秒)"); } on key 'a' { // 几乎立即触发第一次,然后每 4000ms (4秒) 触发一次 setTimerCyclic(timer4, 0, 4000); }
- 作用: 专门用于启动毫秒级 (
-
取消/停止定时器 (
cancelTimer):- 作用: 停止一个已经启动(无论是用
setTimer还是setTimerCyclic启动)的定时器,使其不再触发。 - 语法:
cancelTimer(TimerName);。 TimerName: 要停止的定时器变量名。- 调用时机: 可以在任何需要停止定时器的地方调用,例如:
- 在另一个事件(如
on key 'b')中手动停止。 - 在定时器自身的
on timer事件中,当满足某个条件时(如达到执行次数)停止。 - 在另一个定时器的
on timer事件中停止其他定时器。
- 在另一个事件(如
- 示例:
Code snippet
on key 'b' { cancelTimer(timer1); // 按 B 键停止 timer1 write("timer1 定时器取消了"); } variables { int timer2Count = 0; } on timer timer2 { write("timer2 定时器触发!"); timer2Count++; if (timer2Count >= 5) { // 触发 5 次后停止 cancelTimer(timer2); write("timer2 定时器已取消 (达到次数)"); } else { setTimer(timer2, 5000); // 继续下一次 (如果用 setTimer 启动) } }
- 作用: 停止一个已经启动(无论是用
五、 总结与后续
- 本期学习了 CAPL 中定时器
timer(秒级) 和msTimer(毫秒级) 的使用方法。 - 重点掌握了定时器的声明 (在
variables区)、on timer事件处理、启动 (setTimer,setTimerCyclic) 和停止 (cancelTimer)。 - 理解了如何使用定时器实现延迟执行和周期性执行。
- 定时器是实现时间相关逻辑(如周期发送、超时处理)的基础。
- 下一期将讲解 CAPL 中非常核心的概念:
message(报文) 类型变量。