当前位置: 首页 > 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语言中一些简单的总结。


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

http://www.xdnf.cn/news/17947.html

相关文章:

  • windows dns远程添加A记录
  • Android 证书 是什么
  • Redis ③-Linux下载Redis
  • 长图分段打印方法
  • Linux:通过ssh实现端口转发
  • 2025接口测试趋势前瞻:核心策略、工具演进与实战场景解析
  • golang context源码
  • kkFileView安装及使用
  • 深入浅出 Multi-Head Attention:原理 + 例子 + PyTorch 实现
  • 数字信号处理技术架构与功能演进
  • 鸿蒙语言基础
  • 如何在直播App中集成美颜SDK?人脸美型功能从0到1实现指南
  • 基于 HT 数字孪生智慧交通可视化系统
  • 安卓App中调用升级接口并实现版本检查和升级功能的完整方案
  • IP检测工具“ipjiance”
  • MySQL锁详解
  • 2025年大数据实训室建设及大数据实训平台解决方案
  • Vmware esxi 查看硬盘健康状况
  • 【深度学习】张量计算:爱因斯坦求和约定|tensor系列03
  • 如何才能学会代数几何,代数几何的前置学科是什么
  • 使用Trae CN分析项目架构
  • 理解.NET Core中的配置Configuration
  • 时序逻辑电路——序列检测器
  • 【Contiki】Contiki process概述
  • 基于slimBOXtv 9.16 V2-晶晨S905L3A/ S905L3AB-Mod ATV-Android9.0-线刷通刷固件包
  • 铁氧体和纳米晶:车载定制电感的材料选择
  • 什么是Python单例模式
  • 解决方德桌面操作系统V5.0-G23没ll命令的问题
  • 以太网交换机介绍
  • Docker compose使用、容器迁移