【CAPL】发送固定数的帧后恢复原状态
发送固定数的帧的使用场景
-
后视镜折叠功能
- 持续发送折叠信号的话,电机堵转容易烧掉,因此仅发送有限帧数据
- 举例,仅发送3帧数据后恢复原值
CANoe工程设置
需求分析
- 仅发送3帧数据后恢复原值
- 3帧数据:循环3次,并重复发送动作
- 恢复原值:循环结束后,发送的数据值恢复为原来的值
- 需要触发:设置一个trigger变量,并关联到开关控件
DBC设置
- 明确收发节点和触发数据的所在信号
- 本工程:switch节点发,light节点收,trigger位于报文0x123的bit1
创建系统变量trigger
- 选中space-new
- 设置属性值:name,初始值、最值等
- 在系统变量界面apply后才能使用
panel设置
- 添加开关控件
- 关联到系统变量trigger
CAPL设置
- 报文0x123的帧率:200ms循环帧
- 分析:发送3帧,需要循环;如下图的触发可能会不太方便
- 监控报文0x123:监控系统变量trigger的值
- 设置计数器i=0;
- 当trigger==1时:将报文下的信号switch赋值为1
- 进行三次循环
- 循环结束后,将trigger赋值为0
- 当trigger==0时:将信号switch赋值为0,计数器归零
- 代码示例:
//light.can //奇怪的是,在其他代码全部注释,MyMSG不设为循环帧的情况下,仍然可以实现发3帧1 on message MyMSG//改为on signal_update `switch 也可实现 //注意:on signal `switch 不行 { int i = 0; if(@sysvar::MyNameSpace::trigger == 1){ write("active!!"); i++; if(i<3){ write("count less than 3:%d",i); //@sysvar::MyNameSpace::trigger = 1; $`switch=1; }else{ write("count done: %d",i); @sysvar::MyNameSpace::trigger = 0; } }else if(@sysvar::MyNameSpace::trigger == 0){ write("inactive..."); $`switch = 0; i = 0; } }
运行效果
- 开关按下,发3帧,开关自动恢复为关闭,发送是数据恢复为0
调试
调试:报文MyMSG是否为循环帧
- DBC中MyMSG改为非cycle,cycletime改为0后,trace无更新,panel开关无反应
- 注意:报文attribute每次修改后,应用-确定,不生效,需要在DBC界面保存后才生效!!
调试:添加timeNow()的报文200ms循环帧
- 代码示例:
on message MSG_LS { int i = 0; if(@sysvar::MyNameSpace::trigger == 1){ write("active!!"); i++; if(i<3){ write("count less than 3:%d, timenow = %d",i,timeNow()); //@sysvar::MyNameSpace::trigger = 1; $`switch=234; }else{ write("count done: %d, timenow = %d",i,timeNow()); @sysvar::MyNameSpace::trigger = 0; } }else if(@sysvar::MyNameSpace::trigger == 0){ write("inactive...timenow = %d",timeNow()); $`switch = 0; i = 0; } }
- 运行结果:i 的更新均为200ms间隔,没有提前跳出
问题
1.报文是否是循环帧,与trace持续发送的关系
- 不管设置报文MyMSG为循环帧还是默认未定义帧,trace中都会一直不停地发报文
- trace中为什么没有output都会一直不停地发呢?
-
DONE:DBC中报文属性更新,apply之后,仍需在DBC保存才能生效!!
2.代码中用if就实现了循环,执行顺序?为什么会?
-
CAPL中的局部变量:静态地被创建,并且可以再次进入程序时保留上一次的值
- 因此这里的int i虽然是局部变量,但是有种全局变量的属性,可以用if扭曲地实现循环
- 因此这里的int i虽然是局部变量,但是有种全局变量的属性,可以用if扭曲地实现循环