CANOE入门:CAPL语言常用事件和函数

您所在的位置:网站首页 浦东发生改变的时间和事件 CANOE入门:CAPL语言常用事件和函数

CANOE入门:CAPL语言常用事件和函数

2024-07-13 08:25| 来源: 网络整理| 查看: 265

目录

查看函数文档

常用函数及示例

 发送CAN报文函数 output 

获取Signal值和MessageID

在Write窗口打印数据

获取Signal的值

修改已有信号的值并发送

信号触发事件

定时事件

完整的示例代码

查看函数文档

查看方法:在CAPL编辑界面中找到CAPL函数助手,查找到相应的函数,在函数简介的下方小窗口内的右上角点开。这里以output()函数为例,演示如何查看函数文档。

 在弹出的窗口中,可以看到函数的详细介细,包括入参,出参,示例等。

常用函数及示例  发送CAN报文函数 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的屏幕上打印 } 获取Signal值和MessageID

函数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窗口打印数据

使用write()函数可以在CANoe的Write窗口中打印需要显示的数据。这个函数可以理解为C语言的print()函数,打印格式也是一样的。

获取Signal的值

通过$+信号名称即可以获取信号当前的值

//获取当前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("定时事件"); }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3