计时器
每个系统的 tile 都有一个参考时钟。在XMOS设备上,参考时钟通常被定义为100MHz。在xC中,计时器如图14所示,为程序提供了访问这个参考时钟的功能。
图14: 计时器
参考时钟有一个关联的32位计时器。请注意,每个 tile 上的时钟当前计数值并不相同,但如果所有的 tile 都在同一块PCB上,则时钟通常是同步的。
在xC程序的任何地方都可以声明一个计时器变量:
timer t;
要获取计时器的当前值,使用 :> 操作符:
uint32_t time;
t :> time ; // 这会读取当前的计时器值到变量 'time ' 中。
借助此功能,程序可以例如测量经过的时间:
uint32_t start_time , end_time;
t :> start_time ;
// 这里做一些事情
t :> end_time ;
printf("经过的计时器刻度数:%u" , end_time - start_time);
记住32位计时器的范围。在100MHz的参考时钟下,你只能有意义地测量最多232-1次ticks(约42秒)。
当计时器达到某个值时,计时器可能会引发事件。这些事件 可以在选择语句中进行反应。类似这种情况的语法为:
case timer when timerafter(value) :> [var|void]:
例如,以下选择将基于计时器进行事件处理:
uint32_t x;
timer t;
...
select {
case t when timerafter(x) :>void:
// 处理计时器事件
...
break;
}
如果计时器大于x保持的值,此事件将触发。在此例中,在 :> 符号之后是void。这意味着忽略了事件发生时计时器的实际值。或者,我们可以将值写入一个新的变量:
case t when timerafter (x) :> int y:
对计时事件的反应能力使程序可以周期性地执行操作。例如,以下循环具有一个案例,该案例每1ms执行一些代码:
timer t;
uint32_t time ;
const uint32_t period = 100000; // 100000计时器刻度 = 1 ms
// 获取初始计时器值
t :> time ;
while (1) {
select {
case t when timerafter ( time ) :> void :
// 执行周期性任务
...
time += period ;
break ;
}
}
这种形式的周期性事件处理在与同一选择结构中的其他事件处理程序组合时特别有用。在定义可组合函数(见可组合函数)时也很有用,它可以在同一个逻辑核心上运行周期性任务和其他任务。