3. CAPL实现周期报文发送与信号更新

CAPL实现周期报文发送与信号更新 学习卡片

任务拆解与报文定义

本例在已导入 DBC 的 CANoe 工程中,用 CAPL 节点周期发送一条发动机转速报文,并让转速信号按固定步长递增。先明确报文与信号参数,再写 CAPL 代码,最后在 Trace 窗口验证。

对象取值说明
报文名称EngineSpeed_MsgDBC 中已定义的发送报文
报文 ID0x180标准帧,DLC = 8
发送周期100 ms用 setTimer 循环触发
信号名称EngineSpeed起始位 0,长度 16 bit,小端
信号因子/偏移0.25 rpm / 0物理值 = 原始值 × 0.25
更新步长+250 rpm每个周期递增一次
有效范围0 ~ 8000 rpm超出后回绕到 0

CAPL 实现

在 Simulation Setup 中新建一个 CAPL 节点,把下面的代码写入该节点的 .can 文件。代码用 100 ms 定时器驱动发送,每次触发时先更新 EngineSpeed 物理值,再调用 output() 发出报文。

/* EngineSpeedSender.can
 * 周期发送 EngineSpeed_Msg,转速按 +250 rpm 步长更新
 */
variables
{
  msTimer tSend;              // 100 ms 周期定时器
  float   gSpeed = 0.0;       // 当前转速物理值,单位 rpm
  const float kStep  = 250.0; // 每周期步长
  const float kMax   = 8000.0;// 上限,超出回绕
}

on start
{
  gSpeed = 0.0;
  setTimer(tSend, 100);       // 启动第一个周期
  write("EngineSpeedSender started, period = 100 ms");
}

on timer tSend
{
  // 1) 更新信号物理值
  gSpeed = gSpeed + kStep;
  if (gSpeed > kMax)
  {
    gSpeed = 0.0;             // 回绕,便于观察周期性变化
  }

  // 2) 写入报文信号(DBC 自动完成物理值到原始值换算)
  EngineSpeed_Msg.EngineSpeed = gSpeed;

  // 3) 发送报文
  output(EngineSpeed_Msg);

  // 4) 重新装载定时器,形成周期
  setTimer(tSend, 100);
}

on stopMeasurement
{
  cancelTimer(tSend);
  write("EngineSpeedSender stopped at speed = %f rpm", gSpeed);
}
若 DBC 中信号名或报文名不同,只需替换 EngineSpeed_Msg.EngineSpeed 这一处;其余逻辑与周期、步长无关,可保持不变。

信号更新与发送时序

下图给出一个发送周期内的处理顺序:定时器到期 → 转速累加并判断回绕 → 写入信号 → 发出报文 → 重装定时器。Trace 窗口中每个 100 ms 应出现一帧 ID 为 0x180 的报文,其 EngineSpeed 物理值按 250 rpm 递增。

msTimer tSend 每 100 ms 到期 gSpeed += 250 若 > 8000 则回绕 0 写入信号 EngineSpeed_Msg.EngineSpeed output() 发出 0x180 setTimer(tSend, 100) 重新装载,形成周期 Trace 窗口预期(ID 0x180,周期 100 ms) 0 ms 100 ms 200 ms 300 ms 400 ms 500 ms 0x180 0 rpm 0x180 250 rpm 0x180 500 rpm 0x180 750 rpm 0x180 1000 rpm 0x180 1250 rpm +250 rpm / 100 ms

验证与判读

  1. 启动 Measurement,在 Trace 窗口按 ID 过滤 0x180,确认报文以约 100 ms 间隔连续出现。
  2. 展开报文的信号列,观察 EngineSpeed 物理值:应从 0 开始,每帧增加 250 rpm,即 0、250、500、750……
  3. 当数值超过 8000 rpm 后应回绕到 0,说明回绕分支生效。
  4. 若报文不出现,检查 CAPL 节点是否已加入 Simulation Setup 并处于激活状态;若周期明显偏离 100 ms,检查是否在 on timer 中遗漏了 setTimer 重装。
CAPL 中 output() 发送的是 DBC 中该报文的发送方向;若 DBC 把该报文定义为接收报文,需在数据库属性中改为发送,否则节点不会真正发出帧。