传输和接收 can 报文
发现已安装的硬件
在本示例中,您将使用 发现系统 can 设备,然后使用 创建两个 can 通道。稍后,您将编辑第一个通道的属性并使用 创建一条报文,然后使用 从第一个通道传输该报文,并使用 在另一个通道上接收该报文。
获取有关系统上 can 硬件设备的信息。
info = canchannellist
info = 14×6 table vendor device channel devicemodel protocolmode serialnumber _____________ _______________________ _______ _____________________ _____________ ____________ "mathworks" "virtual 1" 1 "virtual" "can, can fd" "0" "mathworks" "virtual 1" 2 "virtual" "can, can fd" "0" "vector" "vn1610 1" 1 "vn1610" "can, can fd" "18959" "vector" "vn1610 1" 2 "vn1610" "can, can fd" "18959" "vector" "virtual 1" 1 "virtual" "can, can fd" "0" "vector" "virtual 1" 2 "virtual" "can, can fd" "0" "peak-system" "pcan-usb pro" 1 "pcan-usb pro" "can, can fd" "0" "peak-system" "pcan-usb pro" 2 "pcan-usb pro" "can, can fd" "0" "kvaser" "usbcan professional 1" 1 "usbcan professional" "can" "10680" "kvaser" "usbcan professional 1" 1 "usbcan professional" "can" "10680" "kvaser" "virtual 1" 1 "virtual" "can, can fd" "0" "kvaser" "virtual 1" 2 "virtual" "can, can fd" "0" "ni" "9862 can/hs (can1)" 1 "9862" "can, can fd" "17f5094" "ni" "9862 can/hs (can2)" 1 "9862" "can, can fd" "17f50b2"
注意
要针对硬件 can 设备修改此示例,请在两个通道之间建立环回连接。
创建 can 通道
创建两个 mathworks 虚拟 can 通道。
canch1 = canchannel('mathworks','virtual 1',1) canch2 = canchannel('mathworks','virtual 1',2)
canch1 = 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: [] canch2 = 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: []
对于每个通道,请注意其初始 running
值为 0
(已停止),其总线速度为 500000
。
注意
您不能使用同一变量连续创建多个通道。在使用同一变量构造新 can 通道之前,请清除任何通道。
您不能创建 can 通道对象数组。您创建的每个对象都必须赋给它自己的标量变量。
配置通道属性
您可以通过配置 can 通道的属性值来设置其行为。对于本练习,请使用 函数将通道 1 的总线速度更改为 250000。
提示
在启动通道之前配置属性值。
将两个通道的总线速度都更改为
250000
,然后查看通道的busspeed
属性以验证设置。configbusspeed(canch1,250000) canch1.busspeed
ans = 250000
您还可以在通道显示中查看更新后的总线速度。
canch1
canch1 = 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: 250000 sjw: [] tseg1: [] tseg2: [] numofsamples: [] other information database: [] userdata: []
以类似的方式,更改第二个通道的总线速度。
configbusspeed(canch2,250000)
启动通道
配置其属性后,启动两个通道。然后查看第一个通道的更新后的状态信息。
start(canch1) start(canch2) canch1
canch1 = channel with properties: device information devicevendor: 'mathworks' device: 'virtual 1' devicechannelindex: 1 deviceserialnumber: 0 protocolmode: 'can' status information running: 1 messagesavailable: 0 messagesreceived: 0 messagestransmitted: 0 initializationaccess: 1 initialtimestamp: 23-may-2019 15:43:40 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: 250000 sjw: [] tseg1: [] tseg2: [] numofsamples: [] other information database: [] userdata: []
请注意,通道的 running 属性值现在为 1
(true)。
创建报文
根据需要设置所有属性值并且通道处于运行状态后,即可在 can 总线上传输和接收报文。对于本练习,请使用 canch1
传输报文,使用 canch2
接收报文。要传输报文,请创建一个报文对象并将必要的数据打包到报文。
构建具有标准类型 id (500) 且数据长度为 8 个字节的 can 报文。
messageout = canmessage(500,false,8)
messageout = message with properties: message identification protocolmode: 'can' id: 500 extended: 0 name: '' data details timestamp: 0 data: [0 0 0 0 0 0 0 0] signals: [] length: 8 protocol flags error: 0 remote: 0 other information database: [] userdata: []
该报文的一些属性指示如下:
error
- 逻辑值0
(false),因为该报文不是错误。remote
- 逻辑值0
(false),因为该报文不是远程帧。id
- 您指定的 id。extended
- 逻辑值0
(false),因为您未指定扩展 id。data
- 由 0 组成的 uint8 数组,其大小由数据长度指定。
请参阅 函数以了解有关其输入参数的详细信息。
打包报文
创建报文后,将必要的数据打包到报文。
使用 函数用以下输入参数对报文进行打包:
data
值为 25,开始位为 0,信号大小为 16,字节顺序使用 little-endian 格式。查看报文data
属性以验证设置。pack(messageout,25,0,16,'littleendian') messageout.data
ans = 1×8 uint8 row vector 25 0 0 0 0 0 0 0
从打包更改的唯一报文属性是 data
。请参阅 函数以了解有关其输入参数的详细信息。
传输报文
现在您可以传输打包的报文。使用 函数,提供通道 canch1
和报文作为输入参数。
transmit(canch1,messageout) canch1
canch1 = channel with properties: device information devicevendor: 'mathworks' device: 'virtual 1' devicechannelindex: 1 deviceserialnumber: 0 protocolmode: 'can' status information running: 1 messagesavailable: 1 messagesreceived: 0 messagestransmitted: 1 initializationaccess: 1 initialtimestamp: 23-may-2019 15:43:40 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: 250000 sjw: [] tseg1: [] tseg2: [] numofsamples: [] other information database: [] userdata: []
matlab® 显示更新后的通道。在 status information 部分中,每传输一条报文时,messagestransmitted
值都会递增 1。要接收的报文可供总线上的所有设备使用,因此即使对于传输通道,它也会显示在 messagesavailable
属性中。
请参阅 函数以了解有关其输入参数的详细信息。
接收报文
使用 函数接收 canch2
上的可用报文。
要查看可在此通道上接收的报文,请键入:
canch2
canch2 = channel with properties: device information devicevendor: 'mathworks' device: 'virtual 1' devicechannelindex: 2 deviceserialnumber: 0 protocolmode: 'can' status information running: 1 messagesavailable: 1 messagesreceived: 0 messagestransmitted: 0 initializationaccess: 1 initialtimestamp: 23-may-2019 15:43:40 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: 250000 sjw: [] tseg1: [] tseg2: [] numofsamples: [] other information database: [] userdata: []
通道状态信息指示
messagesavailable
为 1。在
canch2
上接收一条报文,并将其分配给messagein
。messagein = receive(canch2,1)
messagein = message with properties: message identification protocolmode: 'can' id: 500 extended: 0 name: '' data details timestamp: 0.0312 data: [25 0 0 0 0 0 0 0] signals: [] length: 8 protocol flags error: 0 remote: 0 other information database: [] userdata: []
请注意收到的报文的
data
属性。该属性匹配从canch1
传输的数据。请参阅 函数以了解有关其输入参数的详细信息。
要检查通道是否收到报文,请查看通道显示。
canch2
canch2 = channel with properties: device information devicevendor: 'mathworks' device: 'virtual 1' devicechannelindex: 2 deviceserialnumber: 0 protocolmode: 'can' status information running: 1 messagesavailable: 0 messagesreceived: 1 messagestransmitted: 0 initializationaccess: 1 initialtimestamp: 23-may-2019 15:43:40 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: 250000 sjw: [] tseg1: [] tseg2: [] numofsamples: [] other information database: [] userdata: []
通道状态信息指示
messagesreceived
为 1,messagesavailable
为 0。
解包报文
在您的通道收到报文后,指定如何解包报文并解释报文中的数据。使用 指定用于解包报文的参数;这些参数应该对应于用于打包的参数。
value = unpack(messagein,0,16,'littleendian','int16')
value = int16 25
请参阅 函数以了解有关其输入参数的详细信息。
保存并加载 can 通道
在 can 通信会话期间,您可以随时使用 函数将 can 通道对象保存到一个文件中。
要将 canch1
保存到 matlab 文件 mycanch.mat
,请键入:
save mycanch.mat canch1
如果已在 matlab 文件中保存 can 通道,则可以使用 函数将该通道加载到 matlab 中。例如,要从先前创建的 mycanch.mat
重新加载通道,请键入:
load mycanch.mat
加载的 can 通道对象会重新连接到指定的硬件,并将其自身重新配置为保存通道时的设定。
断开通道连接并进行清理
断开已配置的通道连接
当您不再需要与 can 总线通信时,请使用 函数断开与您配置的 can 通道的连接。
停止第一个通道。
stop(canch1)
检查通道状态。
canch1
. . . status information running: 0 messagesavailable: 1 messagesreceived: 0 messagestransmitted: 1
停止第二个通道。
stop(canch2)
检查通道状态。
canch2
. . . status information running: 0 messagesavailable: 0 messagesreceived: 1 messagestransmitted: 0
清理 matlab 工作区
如果不再需要这些对象和变量,请使用 命令从 matlab 工作区中删除它们。
清除每个通道。
clear canch1 clear canch2
清除 can 报文。
clear messageout clear messagein
清除解包的值。
clear value