[车联网] CAN总线与DBC详解 | 您所在的位置:网站首页 › 汽车lsb是什么意思 › [车联网] CAN总线与DBC详解 |
0 序
1 CAN总线-概述
1.0 简介
CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种 ISO 国际标准化的、能够实现分布式实时控制的串行通信网络。 应用领域:其广泛应用于汽车、工业自动化/工业控制、机器人等现场控制领域中进行数据传输。 发展历程 1986年,德国Bosch公司为解决现代汽车中众多的控制与测试仪器之间的数据交换而开发的一种串行数据通信协议。 1993年11月,国际标准化组织ISO正式颁布了关于CAN总线的ISO11898标准。该标准成为国际上应用最广泛的现场总线之一。 企业支持情况:目前CAN得到了Motorola、Intel、 Philips 、Siemens、NEC等公司的支持。 传输介质:它使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。 核心特性:CAN协议的特性包括:完整性的串行数据通讯、提供实时支持、传输速率高达1Mb/s、同时具有11位的寻址以及检错能力。 此外,CAN协议还支持功能安全应用,具有高可靠性、抗干扰能力强、支持多节点等优点。 报文格式:CAN协议支持两种报文格式,标准格式为11位标识符,扩展格式为29位标识符,支持多种传输速率和数据长度,满足不同应用场景的需求。 1.1 优点 传输速度高。传输速度最高到1Mbps,通信距离最远到10km,无损位仲裁机制,多主结构。近些年来,CAN控制器价格越来越低。 低成本:ECUs通过单个CAN接口进行通信,布线成本低。 高集成:CAN总线系统允许在所有ECUs上进行集中错误诊断和配置。 可靠性:该系统对子系统的故障和电磁干扰具有很强的鲁棒性,是汽车控制系统的理想选择。 高效率:可以通过id对消息进行优先级排序,以便最高优先级的id不被中断。 灵活性:每个ECU包含一个用于CAN总线收发芯片,随意添加CAN总线节点。 CAN总线分层模型CAN-Bus规范定义了:物理层、数据链路层、应用层(CANopen、DeviceNet等)。 应用层可自行设计,支持多主通信模式。 CAN总线协议也涵盖了 ISO 规定的 OSI 基本参照模型中的传输层、数据链路层及物理层。 CAN协议经过ISO标准化后有2个标准: ISO11898标准、IS011519-2标准。两种标准对于数据链路层的定义相同,但物理层不同。 CAN 1.0/2.0 : (2套标准的主要区别) ISO11898 是针对通信速率为125Kbps~1Mbps的高速(总线)通信标准(闭环); IS011519-2是针对通信速率为125Kbps以下的低速(总线)通信标准(开环);其中总线电平分为显性和隐性两种电平,显性表示逻辑0,隐性表示逻辑1,符合总线上执行线与功能。 由上图可以清楚的看到IS011899高速标准中,隐性时CAN_High和CAN_Low电位相同,电位差0V,表示逻辑1;显性时CAN_High电位高于CAN_Low电位,电位差为2.0V,表示逻辑0。 而低速IS011519-2标准中,显性时CAN_High电位低于CAN_Low电位,电位差为-1.5V,表示逻辑1;隐性时CAN_High电位高于CAN_Low电位,电位差为3.0V,表示逻辑0。 CAN FD:数据段速率已经可以提升到8Mbps(实际工程中常用2Mbps),有效负载带宽也提升到64 bytes。 CAN XL:数据段速率据说可以稳定达到10Mbps,有效负载带宽进一步拓展到2048 bytes。 Kbps:总线的通信速率,指的是位速率(比特率)。 比特率和波特率不是一回事:单位时间内,通信线路上传输的二进制位的数量,其基本单位是 bps 或者 b/s (bit per second)。 1.2 CAN总线网络简单的CAN总线网络 CAN总线网络主要挂在CAN_H和CAN_L,各个节点通过这两条线实现信号的串行差分传输. 为了避免信号的反射和干扰,还需要在CAN_H和CAN_L之间接上120欧姆的终端电阻。为什么是120Ω?因为电缆的特性阻抗为120Ω,为了模拟无限远的传输线。复杂的CAN总线网络 1.3 CAN收发器 CAN收发器的作用是负责逻辑电平和信号电平之间的转换。即:从CAN控制芯片输出逻辑电平到CAN收发器;然后,经过CAN收发器【内部转换】将逻辑电平转换为差分信号输出到CAN总线上,CAN总线上的节点都可以决定自己是否需要总线上的数据。 具体的引脚定义如下: 也就是说,CAN总线上的信号有两种不同的信号状态,分别是: 显性的(Dominant)逻辑0和隐形的(recessive)逻辑1,信号每一次传输完后不需要返回到逻辑0(显性)的电平。 下面以 标准格式来进行说明,先看下面标准格式的帧的图示: 每当发送器在要发送的比特流中检测到相同值的五个连续比特时,则:自动在实际发送的比特流中插入一个相反的比特位,这种方法被称为位填充。 DATA FRAME 或 REMOTE FRAME 的剩余位字段 CRC DELIMITER,ACK FIELD 和 END OF FRAME 是固定格式,不需要填充。 ERROR FRAME 和 OVERLOAD FRAME 也是固定格式,不通过位填充方法编码。 消息中的比特流根据不归零法(Non-Return-to-Zero,NRZ)进行编码。 这意味着在总比特时间内,生成的比特电平要么是“显性”要么是“隐性”。 下图为一个填充示意图: 当检测到错误时,节点可以发送主动错误标志。 主动错误标志由 6 个连续的比特位的显性电平组成,这违反了位填充规则。 位填充方案的一个副作用是,接收到的消息中的少量位错误可能会破坏解填充过程(接收器需要去除填充位),从而导致大量错误在解填充消息中传播。这降低了 CRC 针对原始错误提供的保护级别。 该协议的不足之处已经在 CAN FD 帧中得到了解决,具体方法是:通过使用固定填充比特和记录插入的填充比特数的计数器的组合。 帧长度在位填充之后,CAN 帧的大小将增大。填充位本身可以是五个连续相同位中的第一个。 因此,在最坏的情况下,每四个原始位有一个填充位。帧大小可以使用如下公式表示: ![]() 只要总线空闲,总线上任何节点都可以发送报文,如果有两个或两个以上的节点开始传送报文,那么就会存在总线访问冲突的可能。但是CAN使用了标识符的逐位仲裁方法可以解决这个问题。 CAN总线控制器在发送数据的同时监控总线电平: 如果电平不同,则:停止发送并做其他处理。 如果该位位于仲裁段,则:退出总线竞争; 如果位于其他段,则:产生错误事件。假设节点A、B和C都发送相同格式、相同类型的帧,如标准格式数据帧,它们竞争总线的过程是:
帧ID越小,优先级越高。 由于数据帧的RTR位为显性电平,远程帧为隐性电平。所以,帧格式和帧ID相同的情况下,数据帧优先于远程帧;由于标准帧的IDE位为显性电平,扩展帧的IDE位为隐形电平,对于前11位ID相同的标准帧和扩展帧,标准帧优先级比扩展帧高。逻辑1 表示正电压下的信号,逻辑 0 表示负电压下的信号。 然而,在 NRZ 方法中,从逻辑 0 到逻辑 1 的转换(反之亦然),直接跨越零电压电平,而在 RZ 方法中,转换暂时停留在零电压电平上。如下图所示: NRZ 意味着逻辑值 1 (光脉冲)的一个位在位周期的边界上改变它的值(从有光到无光、或反之亦然)。 相反,RZ 表示光脉冲比比特周期窄。在光信号中,逻辑 1 导通大约三分之一的位周期并且关闭大约三分之二。 逻辑 0 在比特周期的三分之二时间内保持关闭状态。 单极信号、双极信号、多级信号双极信号(bipolar signal) 是一个三电压级的信号,通常在正电压和负电压之间摇摆。双极信号可以是 RZ 或 NRZ。在数字双极信号中,正电压和负电压交替出现。这导致输电线路上的零直流分量。 单极信号(unipolar signal) 是一种两级信号,通常在零级和正级之间波动。 单极信号被认为是一种开关信号,可以应用于电信号或光学信号。在电力传输中,假设统计上有相同数量的1和0,那么直流分量可能达到峰值正电压的一半。对于长距离传输,这种直流分量是不可取的。在光学传输中,单极信号也称为开关键控。 因此,即使原始的 4 位代码是 0000,它也被转换为 5 位非全零代码。 此方法避免在任何代码中都包含所有零。 它也可以设计成连续模式避免某些字符串。 4B/5B 意味着转换后的初始 1 Gb/s 比特率由于增加了比特而增加到 1.25 Gb/s。 也就是说,有 25% 的开销带宽损失。 类似地,8B/10B 代码将 8 位转换成 256 个预定的 10 位代码之一。 带宽损失也是25%。 2 CAN DBC协议文件 2.1 CAN 总线拓扑图通常是将接收到的16进制码流数据翻译成数值、字符串格式的数据,根据 dbc 文件中定义的规则来进行解析。 其中BS_为关键字,用于定义CAN网络的波特率; [ ]内容表示为可选部分,可以省略,但关键字BS_:必须存在,省略则会出错。 其中BU_为关键字,表示网络节点,格式中的Nodename1、Nodename2表示定义的网络节点名字,由用户自己定义;但需保证节点命名的唯一性。 计算方法:信号的物理值 = 原始值*因子 + 偏移量 (6)Min|Max表示该信号的最小值和最大值,即指定了该信号值的范围;这两个值为double类型; (7)Unit表示该信号的物理单位,为字符串类型; (8)Receiver表示该信号的接收节点;若该信号没有指定的接收节点,则必须设置为” Vector__XXX”。字节内始终采用 msb(大端位序),即:信号高有效位在字节内的高位, 信号低有效位在字节内的低位。 关于CAN报文,用Motorola,还是Intel格式,只在信号数据跨字节解析时,才有区别。单个字节数据没有区别。 LSB/MSB、lsb/msb位序和字节序都有大端和小端,共有四种: LSB:Least significant byte(CAN某个信号的最低字节/byte) MSB:Most significant byte(CAN某个信号的最⾼字节/byte) lsb:Least significant bit(CAN某个信号中某个字节的最低有效位/bit) msb:Most significant bit(CAN某个信号中某个字节的最⾼有效位/bit) 扩展解释: msb与lsb是存在于二进制BIT中的计算机名词,msb代表一组二进制中最高位(一般为符号位),lsb代表二进制中的最低位。如:一个1字节的二进制数:(msb)100000000(lsb) 也可能是一个4字节的整型数据:(msb)100000000 100000000 100000000 100000000(lsb) 无论这组二进制数据多大,有多少位,最高位都是msb,最低位就是lsb。 一般这两个名词多用在通讯上,msb用来校验这组数据是否为负数,为1则负;lsb用来校验奇偶,为1则偶数 案例:假设一个一字节的数0x9A转换成2进制为“1001 1010”,那么lsb与msb则应该是这样分布的: MSB存放在低字节单元,反映到矩阵图中就是以起始位为原点,自下而上填充。Motorola格式,MSB在LSB上面。 一个数值的最高字节(MSB)存储在内存的最低地址处,而最低字节(LSB)存储在内存的最高地址处。这种存储方式类似于人类阅读和书写数字的方式,即从左到右,高位在前 MSB存放在高字节单元,反映到矩阵图中就是以起始位为原点,自上而下填充。Intel格式,MSB在LSB下面。
高字节存放在高地址,低字节存放在低地址
没有跨字节是看不出来这两种有啥区别的。来看个跨字节的例子: 当然这里只是为了解释这两个的区别,才把一个报文中的两个信号设置成不同的格式,实际项目中一般不会出现这种情况 案例案例
信号的高位(msb)放在该字节的高位,信号的低位(lsb)放在该字节的低位。 当信号在多个字节内实现(信号跨字节)时,Intel模式和Motorola模式的信号字节顺序,明显不同: Intel模式:信号的高位(MSB)放在高字节的高位,信号的低位(LSB)放在低字节的低位; Motorola模式:信号的高位(MSB)放在低字节的高位,信号的低位(LSB)放在高字节的低位。 俗称: 小端模式 “低(低位字节)在前(低地址),高(高位字节)在后(高地址)”; 大端模式 “高(高位字节)在前(低地址),低(低位字节)在后(高地址)”。 不管是Intel模式,还是Motorola模式,起始位都该信号的低位(LSB)。 2.X Can 报文实际解析 案例1:(大端模式/Motorola/0) 使用can lin 串口工具抓取rawdata : 30 2E 71 00 00 00 00 00 00 00 00 25 49 15 00 00 00 01 10 00 00 00 00 00 00 00 00 00 00 00 0A 00 34 1D 07 41 D0 40 3C 3C 00 00 28 FF FF FF FF FF FF FF FE 00 00 00 00 00 00 00 00 00 00 00 00 00通过 dbc 文件找到报文的定义
解析第1个signal:SG_ I_CDCU_KL15State RawData:30 ------> 0011 0000 从第六位开始2个bit 7 6 5 4 3 2 1 0 0 0 1 1 0 0 0 01 ---> LOCAL_IG_ON Rawdata:3C ---------> 00111100 I_CDCU_SWITCH_Temp的定义从第 319 开始、8个bit,rawdata 中找到对应的字节是第40个字节3C 第40个字节的二进制排列 319bit 318bit 317bit 316bit 315bit 314bit 313bit 312bit 0 0 1 1 1 1 0 0根据公式计算出来对应的值:1*60-40=20;加上单位为20degC 1、如下是一个完整的、准确的Intel模式 CAN信号解析过程。 2、Intel模式信号:低位在右、高位在左;读取顺序:从右往左读。与之相对的是 摩托罗拉信号。 3、DBC的某个CAN帧的信号: BO_ 1443 BMS_moduleTemperature02: 8 BMS SG_ bms_moduleXTempSync02 : 0|4@1+ (1,0) [0|15] "" TBOX SG_ bms_moduleXTempSensor7 : 8|9@1+ (0.5,-40) [-40|210] "℃" TBOX SG_ bms_moduleXTempSensor8 : 17|9@1+ (0.5,-40) [-40|210] "℃" TBOX SG_ bms_moduleXTempSensor9 : 26|9@1+ (0.5,-40) [-40|210] "℃" TBOX SG_ bms_moduleXTempSensor10 : 35|9@1+ (0.5,-40) [-40|210] "℃" TBOX SG_ bms_moduleXTempSensor11 : 44|9@1+ (0.5,-40) [-40|210] "℃" TBOX SG_ bms_moduleXTempSensor12 : 53|9@1+ (0.5,-40) [-40|210] "℃" TBOX0x5A3 = 1443 rawdata : 0050D4408102050A 图片仅供参考,非实际CAN帧的准确瞬时截图 信号解析0050D4408102050A := 0000 0000 0101 0000 1101 0100 0100 0000 1000 0001 0000 0010 0000 0101 0000 1010 原始二进制 : 0111111101111111000000010000000100010000000100010000000000100001 01111111 : 7F 01111111 : 7F 00000001 : 01 00000001 : 01 00010000 : 10 00010001 : 11 00000000 : 00 00100001 : 21 以第1个信号(BCM_FLWINOpenDegree)为例,从第6位开始,读取7个字节。 使用解析方法2来处理原始CAN帧的二进制流 1000010000000000100010000000100010000000100000001111111011111110 10000100 00000000 10001000 00001000 10000000 10000000 11111110 11111110 解析结果 BCM_FLWINOpenDegree | signal bits : 1111111 , signalValue : 127, startBit : 0, bitLen : 7 | bigEndStartBit : 56 BCM_FRWINOpenDegree | signal bits : 1111111 , signalValue : 127, startBit : 8, bitLen : 7 | bigEndStartBit : 48 BCM_RLWINOpenDegree | signal bits : 1000000 , signalValue : 1, startBit : 16, bitLen : 7 | bigEndStartBit : 40 bcm_doorTopSwitchSts | signal bits : 01 , signalValue : 2, startBit : 35, bitLen : 2 | bigEndStartBit : 27 BCM_VSPReq | signal bits : 00 , signalValue : 0, startBit : 37, bitLen : 2 | bigEndStartBit : 29 BCM_FRWINReason | signal bits : 1000 , signalValue : 1, startBit : 44, bitLen : 4 | bigEndStartBit : 20 ... 案例4:(大端模式/Motorola/0) DBC文件 VERSION "" NS_ : NS_DESC_ CM_ BA_DEF_ BA_ VAL_ CAT_DEF_ CAT_ FILTER BA_DEF_DEF_ EV_DATA_ ENVVAR_DATA_ SGTYPE_ SGTYPE_VAL_ BA_DEF_SGTYPE_ BA_SGTYPE_ SIG_TYPE_REF_ VAL_TABLE_ SIG_GROUP_ SIG_VALTYPE_ SIGTYPE_VALTYPE_ BO_TX_BU_ BA_DEF_REL_ BA_REL_ BA_DEF_DEF_REL_ BU_SG_REL_ BU_EV_REL_ BU_BO_REL_ SG_MUL_VAL_ BS_: BU_: EOCM_F_FO Dummy_FO BO_ 1414 RVB_TVR_Debug2_FO: 7 EOCM_F_FO SG_ VBBrkCntlAccel : 45|12@0- (0.01,0) [-20.48|20.47] "m/s^2" Dummy_FO SG_ VBTOSObjID : 35|6@0+ (1,0) [0|63] "" Dummy_FO SG_ VBTOSTTC : 31|12@0+ (0.025,0) [0|102.375] "s" Dummy_FO SG_ VBTOSLatPstn : 11|11@0- (0.125,0) [-128|127.875] "m" Dummy_FO SG_ VBTOSLonPstn : 7|12@0- (0.125,0) [-256|255.875] "m" Dummy_FO 发送CAN报文根据上面的dbc文件,我们进行如下示例分析。向can0网卡发送数据 cansend can0 586#d465737400000000, ekuiper 输出以下结果: [ { "VBBrkCntlAccel": 0, "VBTOSLatPstn": 87.125, "VBTOSLonPstn": -87.25, "VBTOSObjID": 0, "VBTOSTTC": 46.400000000000009 } ]我们尝试通过对dbc数据库文件的理解进行分析,看看是否与ekuiper的计算结果一致。在分析前,我们需要了解几点内容: 1、位序。我们知道: 字节序是一个对象中的多个字节之间的顺序问题;比特序就是一个字节中的8个比特位(bit)之间的顺序问题。一般情况下系统的比特序和字节序是保持一致的。 比如:二进制数11010100,若比特序为大端msb,则:最高有效比特位在高位,最低有效比特位在低位,那么:它代表的值为0xd4; 若比特序为lsb,则:最高有效比特位在低位,最低有效比特位在高位,那么:它代表的值为0x2b。 CAN 总线协议中规定,位序都是大端模式,即 msb。注:Motorola格式有2种表达方式,一种是Motorola_LSB,另一种是Motorola_MSB。Motorola_LSB的起始位是从低字节开始的,而Motorola_MSB的起始位是从高字节开始的。 dbc文件默认表示Motorola_MSB表达方式;而CANdb++则是Motorola_LSB。 3、信号传输,都是以补码的形式传输 分析: 586#d465737400000000表示报文ID为0x586=1414,与RVB_TVR_Debug2_FO报文匹配。其中d465737400000000则为该报文的数据部分。 因为CAN总线协议规定,位序都是大端模式,即可得到下面的layout图。其中蓝色背景为数据内容,因为RVB_TVR_Debug2_FO报文长度仅有7Byte。同理,可得到其它信号的layout如图。 要注意其箭头的增长方向,这样我们在提取该信号的值为: Intel = (byte0 >> 3) + (byte1 > 3)为低字节的值,(byte1 > 2) + (byte0 > 2)为低字节的值,(byte0 lsb方向描述一个信号,接下来看看小端是如何描述的 其中20bit是lsb,34bit为ms,所以小端格式下,DBC描述是从lsb->msb的方向描述一个信号 案例8:小端模式(Intel) DBC中的CAN帧定义 BO_ 1300 BMS_metric: 8 BMS_EV SG_ bms_SOC : 0|10@1+ (0.1,0) [0|100] "%" GW_R SG_ bms_SOH : 10|10@1+ (0.1,0) [0|100] "%" GW_R SG_ bms_SOE : 20|10@1+ (0.1,0) [0|100] "%" GW_R SG_ bms_SOCActual : 30|10@1+ (0.1,0) [0|100] "%" GW_R SG_ bms_maxChargeSOC : 40|7@1+ (1,0) [0|100] "" GW_R SG_ BMS_BatterFaultLightContro : 47|1@1+ (1,0) [0|1] "" GW_R SG_ BMS_BatteryTempLowLight : 50|1@1+ (1,0) [0|1] "" GW_R SG_ BMS_NavigChrgPostFB : 51|3@1+ (1,0) [0|7] "" GW_R SG_ bms_stEgyFlowSysDischRgn : 54|2@1+ (1,0) [0|3] "" GW_R SG_ bms_stEgyFlowOBCAndBatt : 56|2@1+ (1,0) [0|3] "" GW_R SG_ bms_BatteryWarmst : 61|3@1+ (1,0) [0|7] "" GW_R SG_ bms_chargeFormstatus : 58|3@1+ (1,0) [0|7] "" GW_R CAN帧 030000031e080348 信号计算结果(以bms_SOC信号为例)![]() 注:Motorola格式有2种表达方式,一种是Motorola_LSB,另一种是Motorola_MSB。Motorola_LSB的起始位是从低字节开始的,而Motorola_MSB的起始位是从高字节开始的。 CAN总线协议中规定,位序都是大端模式,即 msb first => 因此不需要区分; 但对字节序没有规定,就出现了两种情况:Motorola 和 Intel 格式。字节内始终采用 msb(大端位序),即:信号高有效位在字节内的高位, 信号低有效位在字节内的低位。 dbc文件默认表示Motorola_MSB字节序;而CANdb++则是Motorola_LSB。CANdb++默认是Motorola_LSB字节序 3 CAN-FD 总线协议 3.1 CAN 总线通信协议 ==> CAN FD 总线通信协议 CAN 总线通信也渐渐显现出来一些不足,主要有以下几方面: (1)最高数据传输速率限制为1 Mbit/s,车载领域实际使用速率最高为500 Kbit/s,无法满足越来越高的数据吞吐量需求; (2)每帧报文有效数据场为8 字节,仅占整帧报文信息不足50%; (3)性能上难以应对Flexray、Ethernet 等新型车载总线的威胁。市场对提升 CAN 总线性能的强烈需求使CAN-FD (Flexible Data rate)应运而生,CAN-FD发扬了CAN 的优点,并弥补了 CAN 的不足,其主要特性如下: (1)采用与 CAN 通信相同的事件触发模式,软件容易开发和移植; (2)最高数据传输速率达5Mbit/s,更好地满足要求高实时性、高数据传输速率的应用; (3)每帧报文的有效数据长为 64 字节,占整帧报文信息超过70%; (4)相比Flexray、Ethernet 等新兴总线的成本更低。 CAN与CAN-FD性能对比 | Frame Type | NO.Data Bytes | Arb.Bit-Rate | Opt.Bit-Rate | Avg.Bit-Rate | Frame Duration | 3.2 CAN-FD 的技术特点及应用领域 `CAN-FD· 通过改变帧结构和提高位速率等方法成功的把数据传输速率提高到了5Mbit/s,其基本原理如图所示。CAN-FD 传输的基本原理 与CAN一样,填充位插入到SOF和数据场的末尾之间。插入的填充位数值是经过格雷码计算转换后的值,并且用奇偶校验位保护(Stuff Count)。 在CRC校验场中,填充位被放置在固定的位位置,这称为固定填充位(Fixed Stuff Bit FSB)。固定填充位的值是上一位的反码。 CRC校验场的第一位 每间隔4位添加一个固定填充位 CAN FD还在安全性上有了提高。为了避免位填充对CRC的影响,CAN FD在CRC场中增加了stuff count记录填充位的个数对应8的模,并用Grey Code表示,还增加了奇偶校验位。FSB(fixed stuff-bit)固定为前一位的补码。 Stuff Count由以下两个元素组成: 格雷码计算:CRC区域之前的填充位数除以8,得到的余数(Stuff bit count modulo 8)进行格雷码计算得到的值(Bit0-2) 奇偶校验:通过格雷码计算后的值的奇偶校验(偶校验)每一个数据帧均由一标志序列界定,这个标志序列由7个“隐性”位组成。CAN FD的帧结尾与CAN相同。
协议解析参数设置:
数据包的ID号为0x010, RTR:false(数据帧), DLC:0x8(8个数据),Data:0x00~0x07,CRC为0x0C5E7(17位), ACK:应答。 圆形白点:逻辑数据。 方形白点:填充位。 "现在最新的已经是CAN-FD协议了,数据域直接扩展到64字节,也就是理论最高位速率直接从1M提升到了8M" CAN通信标准帧和扩展帧(全网最透彻解答) - CSDN CAN总线数据解析(Intel格式) - 博客园 Can解析 - dxl.life 【强烈推荐】 详解CAN总线:CAN协议分层结构及功能 - CSDN |
CopyRight 2018-2019 实验室设备网 版权所有 |