CAPL中定时器有两种,秒级和毫秒级,它们只是单位的不同,下文中以毫秒级定时器为例做简单介绍
假设需要实现这样一个功能:当发送完0x100,在1000ms后发送一帧0x200的报文
1. 定时器声明
使用定时器前需要先声明,这个跟声明变量是一个道理,格式:关键字 定时器名称;
毫秒定时器的关键字是msTimer,秒级定时器的关键字是Timer
variables
{
msTimer myTimer; //声明一个毫秒定时器
message 0x100 msg1; //声明待测报文0x100
message 0x200 msg2; //声明待测报文0x200
}
2. 定时器功能,这个跟使用函数实现某一功能类似,定时器要实现某个功能需要通过定时器事件完成,格式:on timer 定时器名称{定时器功能代码}
on timer myTimer{
int i;
msg2.DLC=8;
for(i=0; i<8; i++){
msg2.byte(i)=0x00;
}
output(msg2); //向总线上发送一帧待测报文0x200
}
3. 定时器设置,这个就是定时器的使用,格式之一:setTimer(定时器名称, 时间间隔); 即在时间间隔后实现定时器中定义的功能
export testfunction output_msg() {
int i;
msg1.DLC=8;
for(i=0; i<8; i++){
msg1.byte(i)=0x00;
}
output(msg1); //向总线上发送报文0x100
setTimer(myTimer, 1000); //在1000ms(因为定义的是毫秒定时器,所以1000的单位是ms)后发送0x200
}
在CANoe里运行结果如下,可以看出0x100和0x200间隔1000ms:
上述代码中只使用了一次定时器,那么多次使用定时器要如何做呢,以1000ms周期发送0x200这条报文为例,有两种方法:
1. 嵌套,即在定时器事件里面加上定时器设置,这样一设置定时器会触发一次事件,触发事件时,又会执行定时器设置,然后就继续触发事件......这样循环下去就可以周期使用定时器了
variables
{
msTimer myTimer; //声明一个毫秒定时器
message 0x200 msg2; //声明待测报文0x200
}
on timer myTimer{
int i;
msg2.DLC=8;
for(i=0; i<8; i++){
msg2.byte(i)=0x00;
}
output(msg2); //向总线上发送一帧待测报文0x200
setTimer(myTimer, 1000);
}
export testfunction output_msg() {
setTimer(myTimer, 1000); //在1000ms后发送0x200
}
需注意,这样执行下去代码似乎陷入了死循环,那么如何停止定时器,就需要用到cancelTimer函数,格式:cancelTimer(定时器名称);
export testfunction stop_msg() {
cancelTimer(myTimer); //停止定时器myTimer
}
2. setTimerCyclic(), 设置周期定时器,格式之一:setTimerCyclic(定时器名称, 时间间隔);
variables
{
msTimer myTimer; //声明一个毫秒定时器
message 0x200 msg2; //声明待测报文0x200
}
on timer myTimer{
int i;
msg2.DLC=8;
for(i=0; i<8; i++){
msg2.byte(i)=0x00;
}
output(msg2); //向总线上发送一帧待测报文0x200
}
export testfunction output_msg() {
setTimerCyclic(myTimer, 1000); //在1000ms后以1000ms周期发送0x200
}
这个方法如果要停止,也需要用到cancelTimer函数
注意,只有定时间隔时间到了,才会执行定时器事件中实现的功能,这个就是说,如果settimer下面有其他代码会直接执行,而不会等到间隔时间结束再执行下面代码
variables
{
msTimer myTimer; //声明一个毫秒定时器
message 0x100 msg1; //声明待测报文0x100
message 0x200 msg2; //声明待测报文0x200
}
on timer myTimer{
int i;
msg2.DLC=8;
for(i=0; i<8; i++){
msg2.byte(i)=0x00;
}
output(msg2); //向总线上发送一帧待测报文0x200
}
export testfunction output_msg() {
int i;
setTimer(myTimer, 1000); //在1000ms后发送0x200
msg1.DLC=8;
for(i=0; i<8; i++){
msg1.byte(i)=0x00;
}
output(msg1); //向总线上发送一帧待测报文0x100
}
可以看到,代码里发送msg1 在settimer后面,但执行时,先发送0x100,等待1000ms后再发送0x200
以上如有问题,请指出,谢谢~