目录
查看函数文档
常用函数及示例
发送CAN报文函数 output
获取Signal值和MessageID
在Write窗口打印数据
获取Signal的值
修改已有信号的值并发送
信号触发事件
定时事件
完整的示例代码
查看方法:在CAPL编辑界面中找到CAPL函数助手,查找到相应的函数,在函数简介的下方小窗口内的右上角点开。这里以output()函数为例,演示如何查看函数文档。
在弹出的窗口中,可以看到函数的详细介细,包括入参,出参,示例等。
简介:output()函数用于往CAN总线上发送CAN报文,入参为message结构体,发送前需要定义所有相关的参数,比如报文ID,报文dlc,data中各个有效字节的内容等等。
//键盘事件:按下对应的键触发
on key 'a'
{
message 0x401 msg1; //报文id和名称
msg1.dlc = 8; //设置有效载何长度
msg1.byte(0) = 0x02; //字节0的内容
msg1.byte(1) = 0x02; //字节1的内容
msg1.byte(2) = 0x03; //字节2的内容
msg1.byte(3) = 0x04; //字节3的内容
msg1.byte(4) = 0x01; //字节4的内容
msg1.byte(5) = 0x01; //字节5的内容
msg1.byte(6) = 0x01; //字节6的内容
msg1.byte(7) = 0x01; //字节7的内容
output(msg1); //发送报文到总线上
write("键盘事件..."); //在CANoe的屏幕上打印
}
函数getSignal()和getMessageID(),可以获取获取Signal值和MessageID
includes
{
}
variables
{
int signalValue; //信号值
dword MessageID; //报文ID
}
//报文事件:收到指定报文触发
on message 0x3E9
{
signalValue = getSignal(Key_region_Signal); //获取指定信号的值
write("收到信号Key_region_Signal值为:%hx\n",signalValue);
MessageID = getMessageID("PEPS_Region_on"); //获取指定报文的ID
write("收到报文ID值为:%hx\n",MessageID);
}
使用write()函数可以在CANoe的Write窗口中打印需要显示的数据。这个函数可以理解为C语言的print()函数,打印格式也是一样的。
通过$+信号名称即可以获取信号当前的值
//获取当前Signal的值
//通过$+信号名称即可以获取信号当前的值
on key 'b'
{
//访法1:直接访问
sig = $Key_region_Signal;
write("收到信号值为:%hx\n",sig);
//方法2:前面加Mesage(主要用于区别总线中同名的信号)
sig = $PEPS_Region_on::Key_region_Signal;
write("收到信号值为:%hx\n",sig);
}
直接在事件中定义一个报文,通过报文属性的方式修改报文中信号的值。
//修改DBC中信号的值并发送
//注:这种方法只适用于DBC文件中已定义的信号
on key 'c'{
message BCM_Message msg_bcm;
msg_bcm.bcm_Signal_of =11; //改对应信号的值
output(msg_bcm);
write("c");
}
CAPL中,信号触发事件有两种触发方式,分别为on signal和on signal_update两种触发方式。区别如下:
on signal 监测到信号变化则触发
on signal_update 监测到信号即触发
如何理解呢?举个例子,有一个信号bcm_Signal_of,当ECU启动后总线上发送次序如下的信号
bcm_Signal_of = 1
bcm_Signal_of = 0
bcm_Signal_of = 0
bcm_Signal_of = 1
bcm_Signal_of = 1
两分事件分别触发的情况如下:
on signal 触发 on signal_update触发
on signal 触发 on signal_update触发
on signal 不触发 on signal_update触发
on signal 触发 on signal_update触发
on signal 不触发 on signal_update触发
由上面可以看出,on signal事件是只要信号值发生改变时都会触发包括信号从无到有的那一次,也即只第一次发送也会触发,因为这种情况下相当天信号从0变为1。on signal_update则可以理解为,只要总线监测到有这个信号就会触发,不论这个信号的值是否改变。
在使用CAPL时,有时候需要执行一些定时任务,比如其个报文20秒后执行,或者在CAPL启动1小时后自动退出程序等。这个时候就需要用到定时事件。
定时事件需要使用on timer事件,同时需要配置定时器msTimer,这个定时器单位为ms。还需要配合触发定时器的事件,on key和on start事件。
/*@!Encoding:936*/
includes
{
}
variables
{
msTimer Timer1; //定时器
}
//定时事件:需要配合setTimer()函数使用。
on key 's'{
//设置定时器时间,单位为毫秒
setTimer(Timer1,1000);
}
on timer Timer1
{
write("定时事件");
setTimer(Timer1,1000); //再次设置,可以实现循环
}
需要注意的是 setTimer()函数设置成功后,on timer只会执行一次,执行完成后即会失效。如果需要周期性的执行同一个事件,则需要在执行完业务代码后再调用setTimer()一次,让程序进入下一个执行周期。上面的示例通过按键s事件触发,如果不想要这种方式,可以通过on start事件触发,可以实现程序启动即触发定时器。
另外,如果需要实现周期性执行,还可以通过setTimerCyclic()函数进行设置。函数的和参如下
void setTimerCyclic(msTimer t, long firstDuration, long period); |
传入一个msTimer,从firstDuration开始每隔period时间间隔后执行。
/*@!Encoding:936*/
includes
{
}
variables
{
msTimer Timer1; //定时器
}
//定时事件:配合setTimerCyclic()函数使用。
on key 's'{
//设置定时器时间,单位为毫秒
//第一次在1000ms后执行,后面每次间隔2000ms执行
setTimerCyclic(Timer1,1000,2000);
}
on timer Timer1
{
write("定时事件");
}
上面的示例则可以更简洁的完成一些周期性的操作。建议一次性执行的任务选择setTimer()函数,周期性执行的任务选择setTimerCyclic()。
/*@!Encoding:936*/
includes
{
}
variables
{
int signalValue; //信号值
dword MessageID; //报文ID
dword msgName ;
int sig;
int i;
msTimer Timer1; //定时器
}
//键盘事件:按下对应的键触发
on key 'a'
{
message 0x401 msg1; //报文id和名称
msg1.dlc = 8; //设置有效载何长度
msg1.byte(0) = 0x02; //字节0的内容
msg1.byte(1) = 0x02; //字节1的内容
msg1.byte(2) = 0x03; //字节2的内容
msg1.byte(3) = 0x04; //字节3的内容
msg1.byte(4) = 0x01; //字节4的内容
msg1.byte(5) = 0x01; //字节5的内容
msg1.byte(6) = 0x01; //字节6的内容
msg1.byte(7) = 0x01; //字节7的内容
output(msg1); //发送报文到总线上
write("键盘事件..."); //在CANoe的屏幕上打印
}
//报文事件:收到指定报文触发
on message 0x3E1
{
signalValue = getSignal(Key_region_Signal); //获取指定信号的值
write("收到信号Key_region_Signal值为:%hx\n",signalValue);
MessageID = getMessageID("PEPS_Region_on"); //获取指定报文的ID
write("收到报文ID值为:%hx\n",MessageID);
}
//获取当前Signal的值
//通过$+信号名称即可以获取信号当前的值
on key 'b'
{
//访法1:直接访问
sig = $Key_region_Signal;
write("收到信号值为:%hx\n",sig);
//方法2:前面加Mesage(主要用于区别总线中同名的信号)
sig = $PEPS_Region_on::Key_region_Signal;
write("收到信号值为:%hx\n",sig);
}
//修改DBC中信号的值并发送
//注:这种方法只适用于DBC文件中已定义的信号
on key 'c'{
message BCM_Message msg_bcm;
msg_bcm.bcm_Signal_of =11; //改对应信号的值
output(msg_bcm);
write("c");
}
//信号值发生改时触发
on signal bcm_Signal_of
{
write("信号值发生改变");
}
on signal_update bcm_Signal_of{
write("信号值发送时触发");
}
//定时事件:需要配合setTimer()函数使用。
on key 's'{
//设置定时器时间,单位为毫秒
//第一次在1000ms后执行,后面每次间隔2000ms执行
setTimerCyclic(Timer1,1000,2000);
}
on timer Timer1
{
write("定时事件");
}