在 CAN 通信中使用相对和绝对时间戳
此示例说明如何使用 CAN 通道的 InitialTimestamp 属性来处理 CAN 报文的相对和绝对时间戳。它使用以环回配置形式连接的 MathWorks® 虚拟 CAN 通道。此示例说明 CAN 网络的工作流,但所展示的概念也适用于 CAN FD 网络。
打开 DBC 文件
打开 DBC 文件以访问数据库定义。
db = canDatabase("VehicleInfo.dbc")db =
Database with properties:
Name: 'VehicleInfo'
Path: '/tmp/Bdoc25b_2988451_1444762/tp467e30fd/vnt-ex13648766/VehicleInfo.dbc'
UTF8_File: '/tmp/Bdoc25b_2988451_1444762/tp467e30fd/vnt-ex13648766/VehicleInfo.dbc'
Nodes: {}
NodeInfo: [0×0 struct]
Messages: {'WheelSpeeds'}
MessageInfo: [1×1 struct]
Attributes: {'BusType'}
AttributeInfo: [1×1 struct]
UserData: []
创建 CAN 通道
创建可用于传输和接收报文的 CAN 通道。
txCh = canChannel("MathWorks", "Virtual 1", 1)
txCh =
Channel with properties:
Device Information
DeviceVendor: 'MathWorks'
Device: 'Virtual 1'
DeviceChannelIndex: 1
DeviceSerialNumber: 0
ProtocolMode: 'CAN'
Status Information
Running: 0
MessagesAvailable: 0
MessagesReceived: 0
MessagesTransmitted: 0
InitializationAccess: 1
InitialTimestamp: [0×0 datetime]
FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'
Channel Information
BusStatus: 'N/A'
SilentMode: 0
TransceiverName: 'N/A'
TransceiverState: 'N/A'
ReceiveErrorCount: 0
TransmitErrorCount: 0
BusSpeed: 500000
SJW: []
TSEG1: []
TSEG2: []
NumOfSamples: []
Other Information
Database: []
UserData: []
rxCh = canChannel("MathWorks", "Virtual 1", 2)
rxCh =
Channel with properties:
Device Information
DeviceVendor: 'MathWorks'
Device: 'Virtual 1'
DeviceChannelIndex: 2
DeviceSerialNumber: 0
ProtocolMode: 'CAN'
Status Information
Running: 0
MessagesAvailable: 0
MessagesReceived: 0
MessagesTransmitted: 0
InitializationAccess: 1
InitialTimestamp: [0×0 datetime]
FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'
Channel Information
BusStatus: 'N/A'
SilentMode: 0
TransceiverName: 'N/A'
TransceiverState: 'N/A'
ReceiveErrorCount: 0
TransmitErrorCount: 0
BusSpeed: 500000
SJW: []
TSEG1: []
TSEG2: []
NumOfSamples: []
Other Information
Database: []
UserData: []
将数据库直接连接到接收通道,以便自动将数据库定义应用于传入的报文。
rxCh.Database = db;
创建 CAN 报文
通过指定要应用数据库定义的数据库和报文名称 WheelSpeeds 来创建新 CAN 报文。
msg = canMessage(db, "WheelSpeeds")msg =
Message with properties:
Message Identification
ProtocolMode: 'CAN'
ID: 1200
Extended: 0
Name: 'WheelSpeeds'
Data Details
Timestamp: 0
Data: [0 0 0 0 0 0 0 0]
Signals: [1×1 struct]
Length: 8
Protocol Flags
Error: 0
Remote: 0
Other Information
Database: [1×1 can.Database]
UserData: []
启动 CAN 通道
启动通道以开始使用它们进行传输和接收。
start(rxCh) start(txCh)
传输 CAN 报文
transmit 函数将报文发送到网络上。使用 pause 增加传输操作之间的延迟。每次传输前更新 LF_WSpeed 信号值。
msg.Signals.LF_WSpeed = 10; transmit(txCh, msg) pause(1); msg.Signals.LF_WSpeed = 20; transmit(txCh, msg) pause(2); msg.Signals.LF_WSpeed = 30; transmit(txCh, msg) pause(3); msg.Signals.LF_WSpeed = 40; transmit(txCh, msg) pause(1); msg.Signals.LF_WSpeed = 50; transmit(txCh, msg)
接收 CAN 报文
receive 函数接收在网络上出现的 CAN 报文。
stop(rxCh) stop(txCh) msgRx = receive(rxCh, Inf, "OutputFormat", "timetable")
msgRx=5×8 timetable
Time ID Extended Name Data Length Signals Error Remote
____________ ____ ________ _______________ ______________________ ______ ____________ _____ ______
0.044166 sec 1200 false {'WheelSpeeds'} {[42 248 0 0 0 0 0 0]} 8 {1×1 struct} false false
1.0594 sec 1200 false {'WheelSpeeds'} {[46 224 0 0 0 0 0 0]} 8 {1×1 struct} false false
3.0736 sec 1200 false {'WheelSpeeds'} {[50 200 0 0 0 0 0 0]} 8 {1×1 struct} false false
6.0884 sec 1200 false {'WheelSpeeds'} {[54 176 0 0 0 0 0 0]} 8 {1×1 struct} false false
7.1199 sec 1200 false {'WheelSpeeds'} {[58 152 0 0 0 0 0 0]} 8 {1×1 struct} false false
检查信号数据
使用 canSignalTimetable 将接收到的报文中的信号数据重新打包为一个信号时间表。请注意,时间戳值表示从 CAN 通道启动以来经过的时间。
signalTimetable = canSignalTimetable(msgRx)
signalTimetable=5×4 timetable
Time LR_WSpeed RR_WSpeed RF_WSpeed LF_WSpeed
____________ _________ _________ _________ _________
0.044166 sec -100 -100 -100 10
1.0594 sec -100 -100 -100 20
3.0736 sec -100 -100 -100 30
6.0884 sec -100 -100 -100 40
7.1199 sec -100 -100 -100 50
plot(signalTimetable.Time, signalTimetable.LF_WSpeed, "x") title("Signal Data with Relative Time", "FontWeight", "bold") xlabel("Relative Timestamp") ylabel("Signal Value") ylim([0 60])

检查 InitialTimestamp 属性
查看 CAN 接收通道的 InitialTimestamp 属性。它是 datetime 值,表示通道启动的绝对时间。
rxCh.InitialTimestamp
ans = datetime
09-Aug-2025 12:19:08
使用绝对时间戳分析数据
结合每条报文的相对时间戳和 InitialTimestamp 属性,获得每条报文的绝对时间戳。将绝对时间戳以时间向量形式设置回报文时间表中。
msgRx.Time = msgRx.Time + rxCh.InitialTimestamp
msgRx=5×8 timetable
Time ID Extended Name Data Length Signals Error Remote
____________________ ____ ________ _______________ ______________________ ______ ____________ _____ ______
09-Aug-2025 12:19:08 1200 false {'WheelSpeeds'} {[42 248 0 0 0 0 0 0]} 8 {1×1 struct} false false
09-Aug-2025 12:19:09 1200 false {'WheelSpeeds'} {[46 224 0 0 0 0 0 0]} 8 {1×1 struct} false false
09-Aug-2025 12:19:11 1200 false {'WheelSpeeds'} {[50 200 0 0 0 0 0 0]} 8 {1×1 struct} false false
09-Aug-2025 12:19:14 1200 false {'WheelSpeeds'} {[54 176 0 0 0 0 0 0]} 8 {1×1 struct} false false
09-Aug-2025 12:19:15 1200 false {'WheelSpeeds'} {[58 152 0 0 0 0 0 0]} 8 {1×1 struct} false false
基于更新后的报文时间表创建的信号时间表现在也具有绝对时间戳。
signalTimetable = canSignalTimetable(msgRx)
signalTimetable=5×4 timetable
Time LR_WSpeed RR_WSpeed RF_WSpeed LF_WSpeed
____________________ _________ _________ _________ _________
09-Aug-2025 12:19:08 -100 -100 -100 10
09-Aug-2025 12:19:09 -100 -100 -100 20
09-Aug-2025 12:19:11 -100 -100 -100 30
09-Aug-2025 12:19:14 -100 -100 -100 40
09-Aug-2025 12:19:15 -100 -100 -100 50
figure plot(signalTimetable.Time, signalTimetable.LF_WSpeed, "x") title("Signal Data with Absolute Time", "FontWeight", "bold") xlabel("Absolute Timestamp") ylabel("Signal Value") ylim([0 60])

关闭通道和 DBC 文件
通过从工作区中清除 DBC 文件的变量,关闭对通道和 DBC 文件的访问。
clear rxCh txCh clear db