在 can 通信中使用 dbc 文件 -凯发k8网页登录
以下示例说明如何使用存储在 dbc 文件中的信息创建、接收和处理报文。此示例说明 can 网络的工作流,但所展示的概念也适用于 can fd 网络。
打开 dbc 文件
使用 打开文件 demovnt_candbfiles.dbc
。
db = candatabase("demovnt_candbfiles.dbc")
db = database with properties: name: 'demovnt_candbfiles' path: 'c:\users\michellw\onedrive - mathworks\documents\matlab\examples\vnt-ex80654288\demovnt_candbfiles.dbc' nodes: {} nodeinfo: [0×0 struct] messages: {5×1 cell} messageinfo: [5×1 struct] attributes: {} attributeinfo: [0×0 struct] userdata: []
请检查 messages
属性,以查看此文件中定义的所有报文的名称。
db.messages
ans = 5×1 cell
{'doorcontrolmsg' }
{'enginemsg' }
{'sunroofcontrolmsg'}
{'transmissionmsg' }
{'windowcontrolmsg' }
查看报文信息
使用 查看报文 enginemsg
的信息,包括标识符、数据长度和信号列表。
messageinfo(db, "enginemsg")
ans = struct with fields:
name: 'enginemsg'
protocolmode: 'can'
comment: ''
id: 100
extended: 0
j1939: []
length: 8
dlc: 8
brs: 0
signals: {2×1 cell}
signalinfo: [2×1 struct]
txnodes: {0×1 cell}
attributes: {}
attributeinfo: [0×0 struct]
您还可以一次查询所有报文的信息。
messageinfo(db)
ans=5×1 struct array with fields:
name
protocolmode
comment
id
extended
j1939
length
dlc
brs
signals
signalinfo
txnodes
attributes
attributeinfo
查看信号信息
使用 查看报文 enginemsg
中信号 enginerpm
的信息,包括用于将原始信号转换为物理值的类型、字节顺序、大小和缩放值。
signalinfo(db, "enginemsg", "enginerpm")
ans = struct with fields:
name: 'enginerpm'
comment: ''
startbit: 0
signalsize: 32
byteorder: 'littleendian'
signed: 0
valuetype: 'integer'
class: 'uint32'
factor: 0.1000
offset: 250
minimum: 250
maximum: 9500
units: 'rpm'
valuetable: [0×1 struct]
multiplexor: 0
multiplexed: 0
multiplexmode: 0
rxnodes: {0×1 cell}
attributes: {}
attributeinfo: [0×0 struct]
您还可以一次查询报文 enginemsg
中所有信号的信息。
signalinfo(db, "enginemsg")
ans=2×1 struct array with fields:
name
comment
startbit
signalsize
byteorder
signed
valuetype
class
factor
offset
minimum
maximum
units
valuetable
multiplexor
multiplexed
multiplexmode
rxnodes
attributes
attributeinfo
⋮
使用数据库定义创建报文
通过指定要应用数据库定义的数据库和报文名称 enginemsg
来创建新报文。此报文中的 can 信号除以原始数据字节表示外,还以工程单位来表示。
msgengineinfo = canmessage(db, "enginemsg")
msgengineinfo = message with properties: message identification protocolmode: 'can' id: 100 extended: 0 name: 'enginemsg' 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: []
查看信号信息
使用 signals
属性查看此报文的信号值。您可以直接对这些信号进行写入和读取,以打包和解包报文中的数据。
msgengineinfo.signals
ans = struct with fields:
vehiclespeed: 0
enginerpm: 250
更改信号信息
直接写入信号 enginerpm
以更改其值。
msgengineinfo.signals.enginerpm = 5500.25
msgengineinfo = message with properties: message identification protocolmode: 'can' id: 100 extended: 0 name: 'enginemsg' data details timestamp: 0 data: [23 205 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: []
读回当前信号值,注意 enginerpm
已用写入的值更新。
msgengineinfo.signals
ans = struct with fields:
vehiclespeed: 0
enginerpm: 5.5003e 03
当值直接写入信号时,它会转换、缩放,并使用数据库定义打包到报文数据中。请注意在向 vehiclespeed
信号写入新值后,data
属性中的值变化。
msgengineinfo.signals.vehiclespeed = 70.81
msgengineinfo = message with properties: message identification protocolmode: 'can' id: 100 extended: 0 name: 'enginemsg' data details timestamp: 0 data: [23 205 0 0 71 0 0 0] signals: [1×1 struct] length: 8 protocol flags error: 0 remote: 0 other information database: [1×1 can.database] userdata: []
msgengineinfo.signals
ans = struct with fields:
vehiclespeed: 71
enginerpm: 5.5003e 03
接收具有数据库信息的报文
将数据库连接到 can 通道,该通道接收报文以自动将数据库定义应用于传入报文。数据库仅解码已定义的报文。所有其他报文都以其原始形式接收。
rxch = canchannel("mathworks", "virtual 1", 2); rxch.database = db
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: [1×1 can.database] userdata: []
接收报文
启动通道,生成一些报文流,然后通过物理报文解码来接收报文。
start(rxch); generatemsgsdb(); rxmsg = receive(rxch, inf, "outputformat", "timetable");
查看接收到的报文的前几行。
head(rxmsg)
ans=8×8 timetable
time id extended name data length signals error remote
___________ ___ ________ _____________________ ________________________ ______ ____________ _____ ______
0.13103 sec 100 false {'enginemsg' } {[ 0 0 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.13103 sec 200 false {'transmissionmsg' } {[ 0 0 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.13104 sec 400 false {'doorcontrolmsg' } {[ 0 0 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.13104 sec 600 false {'windowcontrolmsg' } {[ 0 0 0 0]} 4 {1×1 struct} false false
0.13105 sec 800 false {'sunroofcontrolmsg'} {[ 0 0]} 2 {1×1 struct} false false
0.15598 sec 100 false {'enginemsg' } {[ 0 0 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.18 sec 100 false {'enginemsg' } {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
0.18001 sec 200 false {'transmissionmsg' } {[ 4 0 0 0 0 0 0 0]} 8 {1×1 struct} false false
停止接收通道并将其从工作区中清除。
stop(rxch);
clear rxch
检查收到的报文
检查收到的报文以查看应用的数据库解码。
rxmsg(10, :)
ans=1×8 timetable
time id extended name data length signals error remote
___________ ___ ________ _____________ ________________________ ______ ____________ _____ ______
0.22994 sec 100 false {'enginemsg'} {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
rxmsg.signals{10}
ans = struct with fields:
vehiclespeed: 50
enginerpm: 3.5696e 03
提取指定报文的所有实例
提取报文 enginemsg
的所有实例。
allmsgengine = rxmsg(strcmpi("enginemsg", rxmsg.name), :);
查看此特定报文的前几个实例。
head(allmsgengine)
ans=8×8 timetable
time id extended name data length signals error remote
___________ ___ ________ _____________ ________________________ ______ ____________ _____ ______
0.13103 sec 100 false {'enginemsg'} {[ 0 0 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.15598 sec 100 false {'enginemsg'} {[ 0 0 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.18 sec 100 false {'enginemsg'} {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
0.20597 sec 100 false {'enginemsg'} {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
0.22994 sec 100 false {'enginemsg'} {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
0.25695 sec 100 false {'enginemsg'} {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
0.27995 sec 100 false {'enginemsg'} {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
0.30597 sec 100 false {'enginemsg'} {[172 129 0 0 50 0 0 0]} 8 {1×1 struct} false false
绘制物理信号值
使用 将报文 enginemsg
中的信号数据重新打包为一个信号时间表。
signaltimetable = cansignaltimetable(rxmsg, "enginemsg");
查看信号时间表的前几行。
head(signaltimetable)
ans=8×2 timetable
time vehiclespeed enginerpm
___________ ____________ _________
0.13103 sec 0 250
0.15598 sec 0 250
0.18 sec 50 3569.6
0.20597 sec 50 3569.6
0.22994 sec 50 3569.6
0.25695 sec 50 3569.6
0.27995 sec 50 3569.6
0.30597 sec 50 3569.6
绘制信号 vehiclespeed
随时间变化的值。
plot(signaltimetable.time, signaltimetable.vehiclespeed) title("vehicle speed from enginemsg", "fontweight", "bold") xlabel("timestamp") ylabel("vehicle speed")
关闭 dbc 文件
通过从工作区中清除 dbc 文件的变量,关闭对该 dbc 文件的访问。
clear db