主要内容

Simulink 中的 CAN 报文接收行为

R2026b

此示例使用多个建模场景说明如何观察 CAN Receive 和 CAN Unpack 模块的报文处理行为。此示例说明两种情形,使用和不使用 CAN Receive 模块的函数触发 f() 端口。该模型的输出指示在每种情形下为下游处理而解包的 CAN 报文的数量。该示例使用 MathWorks® 虚拟 CAN 通道将来自 MATLAB® 的 CAN 报文发送到 Simulink® 模型。这些建模实践和行为也适用于使用 Vehicle Network Toolbox™ CAN FD 模块的 CAN FD 协议。

探索示例模型

该示例模型包含一个为 Mathworks 虚拟通道配置的 CAN Receive 模块,每 500 毫秒采样一次。接收到的 CAN 报文以两种方式解包:

  • 由函数调用子系统内的一个 CAN Unpack 模块,该模块由 CAN Receive 模块的函数触发 f() 端口触发。

  • 由直接连接到 CAN Msg 输出端口的一个 CAN Unpack 模块解包。

在这两种情形下,都放置示波器来观察接收的信号。此外,来自 CAN Unpack 模块的输出端口的信号值会导出到 MATLAB 工作区,并用于结果绘图。

open CanReceiveModel
ans = logical
   1

为传输准备 CAN 报文

为了演示模型的运行,从 MATLAB 发送 CAN 报文。报文从提供的 MAT 文件中加载。在此示例中,会创建一个 canChannel 以稍后传输数据。要发送的报文以 100 毫秒为周期定时,包含的信号数据呈线性递增。

load canMessages.mat
txCh = canChannel("MathWorks","Virtual 1", 1);

执行模型并从 MATLAB 回放 CAN 报文

指定有限的仿真时间并运行模型。

simTime = 10;
set_param("CanReceiveModel","StopTime",num2str(simTime))
set_param("CanReceiveModel","SimulationCommand","start")
Warning: The 'Classic' option for configuration parameter <a href="matlab:configset.internal.open('CanReceiveModel','UnderspecifiedInitializationDetection');">Underspecified initialization detection</a> will be removed in a future release. Consider setting the option to 'Simplified' for model '<a href="matlab:open_system ('CanReceiveModel')">CanReceiveModel</a>'. Please consult <a href="matlab:helpview('simulink','ConvertClassicSimplifiedInitializationMode');">documentation</a> to convert your model from 'Classic' to 'Simplified'.

暂停脚本执行,直到模型识别为完全启动。

while strcmp(get_param("CanReceiveModel","SimulationStatus"),"stopped")
end

启动 CAN 通道并执行加载的 CAN 报文的replay。

start(txCh);
replay(txCh, canMessages);

当回放发生时,模型中的 CAN Receive 模块正在接收和处理报文。您可以在位于函数调用子系统内部和外部的示波器内实时查看接收到的信号值。等到模型完成仿真后再继续。

浏览接收到的数据处理结果

模型中提供的示波器显示在解包从函数调用子系统内部和外部接收的报文时这些报文的信号值。以下视图显示模型完成仿真后的示波器。请注意这些差异:

  • 在函数调用子系统内部:在每个采样时间接收 4-6 个信号值递增的报文。因此,来自回放的所有 CAN 报文单独接收,触发到子系统,并在每个采样时间由子系统内的 CAN Unpack 模块处理。

  • 在函数调用子系统外部:在每个采样时间接收一个信号值跳跃的报文。因此,在每个采样时间只有来自回放的最后一个 CAN 报文提供给 CAN Unpack 模块并由其处理。不处理其他中间报文。

signal_in.png signal_out.png

plot.png

使用从 CAN Unpack 模块的输出端口导出的模型信号值,在图中比较两种情形。用于绘制结果的函数包含在此示例中,并配置为在模型的 Stop Function 回调中执行,这样它就会在模型停止仿真时执行。

CAN 报文传输每 100 毫秒周期性进行一次,而 CAN Receive 模块以 500 毫秒为周期进行采样。因此,在每个采样中有 4-6 个 CAN 报文。从这些波形可以得出以下结论:

情形 1:使用函数触发(在函数调用子系统内部)解包 CAN 报文会将每个采样中收到的所有报文解包。

  • 在每个采样时间观察到多个信号值。

  • 信号的线性递增值表示每个采样时间内的所有报文都被解包。

  • 这种方式不会隐藏任何数据,因为每个收到的报文都会触发函数调用子系统,并且在其中完成解包。

情形 2:不使用函数触发(在函数调用子系统外部)解包 CAN 报文会只解包每个采样中的最后一个报文。

  • 在每个采样时间仅观察到一个信号值。

  • 因此,在每个采样时间只解包一个 CAN 报文。

  • 在每个采样时间,仅解包采样中的最后一个报文。

  • 除最后一个报文外的所有其他报文在每个采样中都会隐藏。

综上所述,CAN Receive 模块的函数触发端口用于解包在每个采样时间接收的所有报文。如果不使用它,则在每个采样时间内仅解包最后一个报文。请根据系统要求和数据处理需要选择模型行为。