当前位置: 首页 > news >正文

CAPL编程系列_02

1_CAPL 中的运算符

 在CAPL(CANoe/CANalyzer Programming Language)中,运算符用于执行各种运算操作,类似于其他编程语言。CAPL中的运算符可以分为以下几类:

1. 算术运算符

算术运算符
+

加法运算符

-

减法运算符
*乘法运算符
/除法运算符
%求余运算符
int a = 10, b = 5;
int sum = a + b;      // sum = 15
int diff = a - b;     // diff = 5
int prod = a * b;     // prod = 50
int quotient = a / b; // quotient = 2
int remainder = a % b; // remainder = 0

2. 赋值运算符

赋值运算符
=

赋值

+=加法赋值
-=减法赋值
*=乘法赋值
/=除法赋值
%=取余赋值
int a = 5;
a += 10; // a = a + 10 => a = 15
a -= 3;  // a = a - 3  => a = 12
a *= 2;  // a = a * 2  => a = 24
a /= 4;  // a = a / 4  => a = 6
a %= 4;  // a = a % 4  => a = 2

3. 自增和自减运算符

自增和自减运算符
++自增(前置或后置)
--自减(前置或后置)
int a = 5;
a++;  // a = 6 (后置自增)
++a;  // a = 7 (前置自增)int b = 10;
b--;  // b = 9 (后置自减)
--b;  // b = 8 (前置自减)

4. 类型转换运算符

(type):类型转换

double a = 5.7;
int b = (int)a;  // b = 5

5. 关系运算符

==等于
!=不等于
>

大于

<小于
>=大于等于
<=小于等于

6.逻辑运算符

逻辑非
&&逻辑与
||逻辑或

7.位运算符

&按位与两个操作数对应位都为1时,结果位才为1,否则为0
|按位或两个操作数对应位有一个是1,结果位就为1,否则为0
^按位异或相同位的两个操作数不同,结果为1,相同则为0
~按位取反对操作数的每一个位取反,即将0变为1,将1变为0
<<左移将操作数的二进制位向左移动指定的位数,右侧空出的位用0填充
>>右移将操作数的二进制位向右移动指定的位数,左侧空出的位由符号位填充




2_CAPL 中的分支结构

1.if

三种 i f 分支语句

简单 if 语句(单分支)
if-else 语句(双分支)
if-else if 语句(多分支)
//简单  if 语句(单分支)if(条件)
{条件成立执行的语句
}// 任意一个表达式都可以做“条件”
// 判定规则:非 0 即 “真”
// 0,                     0.0,‘\0' 都表示“假”//示例//单分支
on key "a" 
{int score = 92;if (score >= 90)
{
write (“奖励1000元”);
}write(“程序结束了~~~”)}
if-else 语句 (双分支)if(条件)
{条件成立执行的语句
}
else
{条件不成立执行的语句
}

 

if-else if 语句 (多分支)if(条件1)
{条件1成立执行的语句
}
else if (条件2)
{前面条件不成立,但条件2成立执行的语句
}
else if (条件N)
{前面条件不成立,但条件N成立执行的语句
}
else
{所有条件都不成立时执行的语句
}

条件判断的三元运算符

条件 表达式一 表达式二
on key "e" 
{int score = 52;char result;//三元运算表达式result = score >= 60 ? 'Y' :  'N';write ("result 为 %c", result);
}//输出:result 为 N

2.switch

switch(表达式)
{case 值1:语句;break;case 值2:语句;break;case 值N:语句;break;default:语句;
}

注意点:

> case 后的值必须是整型的常量或常量表达式

> 分支中的break可以缺省,如果缺省,该分支语句执行后会贯穿到下一个分支

3.while 和 do-while 语句

while
//while 语句while (条件表达式)
{循环主体语句1;循环主体语句2;循环主体语句N;
}

注意点:

>条件表达式可以是一个任意的表达式

>注意正确设计循环的执行流程,防止出现死循环

     do-while

//do-while 语句do
{循环主体语句1;循环主体语句2;循环主体语句N;
} while (条件表达式) ;

注意点:

>先执行,后判断

>至少执行一次循环主体

on key 'd'
{//输出1到100之间所有能被 7 整除或以 7 结尾的数字int i = 1;while (i <= 100){if (i % 7 == 0 || i % 10 == 7){ write("i: % d",i);}i++;}}


循环过程中的流程控制关键字:

>break       : 跳出整个循环

on key 'f'
{//判断一个数字是否是质数int n = 13;int i = 2;while ( i < n ){if (n % i == 0){write ("%d不是质数,它能为%d整除",n,i);break;}i++;}if (i == n){write("%d是质数",n);}}

>continue  :继续下一次循环

4.for 语句

on key 'b'
{//判断一个数字是否是质数(素数)int num = 13;int i;for(i = 2; i < num; i++){if(num % i == 0){ write("%d 不是质数,能被 %d 整除",num,i);break;}}if(i == num){write("%d是质数",num);}
}

注意点:

>初始化,条件,更新三个部分均可省略,但如果省略了条件,则默认为“真”

>与C语言的for不同,不支持逗号运算符




3_CAPL 中的函数定义

返回值类型  函数名(形参列表)


   函数主体语句

   return 返回值;

}

注意点:
> 函数如果没有返回值,返回值的占位符为 void,且void可以省略.

> 函数可以重载(函数名相同、返回值相同,但形参不同).

on key 'a'
{float r;r = power (2.5,3); //调用函数write("2.5的3次方为: %.4f " ,r ) ;write("4的4次方为:%d",(int)power(4,4));  //调用函数
}// 定义求a的b次方的函数
float power(float a,int b)
{float p;int i;p = 1;   //乘积for(i = 0; i < b; i++){p = p * a;  //将当前乘积 p 跟 a 相乘的结果,再赋值给乘积 p}return p;
}




4_CAPL 中的定时器

variables
{timer tmr1;  //声明一个定时器变量
}//当定时器被触发时需要执行的代码
on timer tmr1
{write("发送报文等等工作.......");
}on key 'a'
{//设置定时器在多少秒后执行setTimer(tmr1,2);
}

注意点:
> 有“秒定时器”和“毫米定时器”两种 timer、 msTimer

> 定时器变量只能声明在 variables 作用域

> 必须为定时器变量定义对应的“处理代码块” 【 on timer 定时器变量 】

> 启动定时器的函数 --  setTimer

> 结束定时器的函数 --  cancelTimer

>msTimer 有一个直接用于周期性使用的函数:setTimerCyclic(变量名,毫秒数);




5_CAPL 中的报文发送

> 声明 message 类型的“报文”变量

      message 0x1A5 msg1;

      message EngineState msg2;

> 给报文变量赋值

      声明报文变量的同时,赋初值

      声明变量后,再进行赋值

> 调用内置函数output,发送报文

》注意:

write是往canoe工具上的输出面板,输出一些文字信息

output是内置函数,是往总线上输出报文

on key 'a '
{//多种声明变量的方法//1.声明了一个ID为0x1A5的报文变量message 0x1A5 msg1;//2.声明了一个ID为0x2B6的报文变量,并且赋予初始值message 0x2B6 msg2 = { dlc=4, byte(0) = 0x2D,byte(1)=0x3F };//3.声明了一个ID为0x3c7的报文变量(和 msg1 对比)message 0x2B6 msg2 = { dlc=4, byte(0) = 0x2D,byte(1)=0x3F };//msg1的变量赋值msg1.dlc = 8;   //给报文变量的dlc赋值msg1.byte(0) = 0xC7;   //给报文数据域中的Byte0的这个字节赋值msgl.byte(1) = 0x95;   //给报文数据域中的Byte1的这个字节赋值msgl.byte(2) = 0x3F;   //给报文数据域中的Byte2的这个字节赋值msgl.byte(3) = 0x6B;   //给报文数据域中的Byte3的这个字节赋值//msg3的变量赋值msg3.dlc = 8;msg3.word(0) = ox95C7;  //给报文数据域中的Byte0和Byte1的这个字节赋值(两个字节倒序)msg3.word(2) = ox6B3F;  //word占两个字节,所以要跳两个output(msg1);   //发送报文msg1output(msg2);   //发送报文msg2output(msg3);   //发送报文msg3
}

  //只需填写转速,后台会自动生成DATA的值
on key 'a'
{//创建一个指定报文名的报文变量//如果这个报文在 dbc 中存在,不用指定dlcmessage EngineState msg1;//给该报文的 EngineSpeed 和 OnOff 这两个信号赋值//语法:【报文变量.信号名】msg1.EngineSpeed = 3000;  //赋值为 3000 rpmmsg1.OnOff = 1;  //赋值引擎开关状态为On ( 值为 1 )//发送报文msg1output(msg1);
}

 定时器周期性发送

//定义一个定时器事件,当触发定时器,就给msg2.EngineSpeed(引擎转速)进行赋值
variables    //全局变量里去定义一个毫秒定时器
{int currEngspd = 0 ;  // 当前的引擎转速值message EngineState msg2 ;  // 创建报文msTimer tmrSendMsg2;  // 定义一个毫秒定时器用于发送报文
}on timer tmrSendMsg2  //定义一个Msg2定时事件
{// 将当前转速值赋值给报文msg2的引擎转速信号EngineSpeed msg2.EngineSpeed = currEngspd; currEngspd += 10;  // 每次增长10rmpoutput(msg2);
}on key 'b'
{setTimerCyclic(tmrSendMsg2,100)
}




6_CAPL 中的事件

                                                  时间驱动的概念
接收到报文事件处理的程序
用户输入事件处理的程序
定时器到时事件处理的程序
时间
事件含义
on preStart在总线“测量开始之前”触发
on start在总线“测量开始时”触发
on preStop在总线“测量将结束时”触发
on stopMeasurement在总线“测试结束后”触发
事件含义
on key 指定键当指定键按下时触发
on timer 定时器当“定时器计时到时”时触发
事件含义
on message 指定报文当接收到指定报文时触发
事件含义
on signal 指定信号当监测到指定信号值变化时触发
on signal_update 指定信号当监测到指定信号值更新时触发
事件含义
on sysVar 系统变量当监测到系统变量变化时触发
on sysVar_update 系统变量当监测到系统变量更新时触发
重点关注加粗字体的使用

  1. on sysvar 和 on sysvar_update 事件
on sysvar  系统变量名
{write("系统变量的值变化了: %d",@this);
}on sysvar_update 系统变量名
{write("系统变量的值更新了:%d",@this);
}
  • 可以使用 @系统变量名 来获取或设置系统变量的值
  • 还可以调用 sysGetVariableXxx( ) 函数来获取系统变量的值
  • 还可以调用 sysSetVariableXxx( ) 函数来设置系统变量的值
  • 在系统变量事件处理程序中,还可以使用 @this 来获取变量的值

on key 'a'
{//改变系统变量TurnLeftIndicator,赋值一个0到9的随机数 @Control::TurnLeftIndicator = random(10) > 7 ? 1 : 0;//sysSetVariableInt("Control","TurnLeftIndicator",random(10) > 4 ? 1 : 0 );
}//当系统变量Control::TurnLeftIndicator的值发生变化时,执行的代码
on sysvar Control::TurnLeftIndicator
{write("TurnLeftIndicator变量的值发生变化了:%d %d %d',@this, @Control::TurnLeftIndicator,sysGetVariableInt("Control","TurnLeftIndicator'));
}//当系统变量Control::TurnLeftIndicator的值发生更新时,执行的代码
on sysvar_update Control::TurnLeftIndicator
{write("TurnLeftIndicator变量的值发生更新了: %d %d %d", @this,@Control::TurnLeftIndicator,sysGetVariableInt("Control","TurnLeftIndicator'));
}

以上是关于CAPL语言中一些简单的总结。


希望对你有所帮助,谢谢观看。

相关文章:

  • 探索大语言模型(LLM):循环神经网络的深度解析与实战(RNN、LSTM 与 GRU)
  • linux 4.14内核jffs2文件系统不自动释放空间的bug
  • 6.数据手册解读—运算放大器(二)
  • 6.5 GitHub监控系统实战:双通道采集+动态调度打造高效运维体系
  • RAG知识库中引入MCP
  • Django ORM 定义模型
  • 题解:CF886E Maximum Element
  • 数字化转型下的农田安防新布局,视频监控汇聚系统EasyCVR打造农田可视化综合管理方案
  • 发现“横”字手写有难度,对比两个“横”字
  • 【信息系统项目管理师】高分论文:论信息系统项目的沟通管理(网管改造工程)
  • b站PC网页版视频播放页油猴小插件制作
  • 钧瓷收藏防坑指南:如何科学评估与理性收藏
  • Flink介绍——实时计算核心论文之Kafka论文详解
  • MCP认证难题破解
  • 文件上传Ⅰ
  • pgsql中使用jsonb的mybatis-plus和jps的配置
  • 微信小程序调用yolo目标检测模型
  • 仿腾讯会议项目开发——网络嵌入
  • AWS Elastic Beanstalk的部署Python Flask后端服务(Hello,World)
  • Hadoop的三大结构及其作用?
  • 航天科技集团质量技术部部长严泽想升任集团副总经理
  • 见微知沪|最大力度消费补贴,最大程度满足人们对美好生活的向往
  • 大家聊中国式现代化|彭羽:为国家试制度探新路,推进高水平对外开放
  • 俄罗斯戏剧《大师与玛格丽特》来沪,剧长8小时一天内演完
  • 甘肃省政府原副省长赵金云严重职务违法被开除公职
  • 欧盟就中欧有关世贸争端案件提起上诉仲裁,商务部回应