关于CAN报文中ACK应答错误的检测原理

CAN协议里对ACK(应答场)有如下的描述:

应答场长度为2个位,包含应答间隙(ACK SLOT)和应答界定符(ACK DELIMITER)。在应答场里,发送站发送两个“隐性”位。当接收器正确地接收到有效的报文,接收器就会在应答间隙(ACK SLOT)期间(发送ACK信号)向发送器发送一“显性”的位以示应答。

应答间隙:所有接收到匹配CRC序列(CRC SEQUENCE)的站会在应答间隙(ACK SLOT)期间用一“显性”的位写入发送器的“隐性”位来作出回答。

ACK界定符:ACK界定符是ACK场的第二个位,并且是一个必须为“隐性”的位。因此,应答间隙(ACK SLOT)被两个“隐性”的位所包围,也就是CRC界定符(CRC DELIMITER)和ACK界定符(ACK DELIMITER)。

此主题相关图片如下:

 

  

 

在CAN协议的错误检测部分有这样的描述:

位错误:站单元在发送位的同时也对总线进行监视。如果所发送的位值与所监视的位值不相符合,则在此位时间里检测到一个位错误(BIT ERROR)。但是在仲裁场(ARBITRATION FIELD)的填充位流期间或ACK间隙(ACK SLOT)发送一“隐性”位的情况是例外的——此时,当监视到一“显性”位时,不会发出位错误(BIT ERROR)。

 

应答错误:只要在ACK间隙(ACK SLOT)期间所监视的位不为“显性”,则发送器会检测到一个应答错误(ACKNOWLEDGMENT ERROR)。

 

从协议所描述的内容来看,我们不难得出一个结论:CAN是一种基于广播的通讯方式,为了保证总线上的每一个节点(处于normal mode)都能正确的接收到报文,报文的发送者要求每一个接收节点在报文发送结束前,也就是ACK slot的时间内,作出应答,即要求接收的节点都在这个时间发送一个“显性”位。发送者在发送的同时,会监视总线上的数据,如果与发送的娄据不一致,则表示发送失败或自己失去仲裁,立即停止发送或转入接收模式。如果有一个节点在ACK SLOT的时间内发送“显性”位,则发送者认为此次发送报文成功;如果发送者检测到ACK SLOT为隐性位,则表示没有节点填充ACK SLOT,则发送者会检测到这个隐性位而知道发送失败,此条报文需要重发。所以,当总线上只有一个节点的时候,或是只有一个节点可以收发数据的时候,这个节点是发不出去数据的,因为它所发出的数据帧中的ACK SLOT没有另外一个节点来填充,将永远是隐性位,这个节点会一直重发数据直到发送成功或发送被取消。

(注:一:总线上只有一个节点而且它向外发送了数据。它确实不会收到任何ACK,它会变成“error passive”但是它不会变成BUS off。why?请参考CAN specificaton 2.0-partB-Fault_Confinement--rule3--exception1二:其它检测到CRC错误的节点不会马上发送错误帧,而是在ACK delimiter之后才发送。请参考CAN specificaton 2.0-partB-Error_Signalling)

 

ACK SLOT只有一个BIT,而接下去的ACK delimiter始终为隐性(我们可认为是1),当数据到达ACK SLOT的时候,所有的节点都会发送显性位(我们可以认为是0),而发送者在ACK这个时间里保持隐性位(即发送者在发送的时候ACK SLOT为1),这时发送者会检测总线上的ACK时间内的信号,如果是0,则表示正确,如果是1,表示有错误。如果当中有某一个节点在ACK SLOT填入隐性位,则总线上同样还是显性位电平,故只要总线上有一个节点正确接收到数据,则ACK SLOT就会被填入显性电平;那么,接收错误的节点如何来告知发送者此次发送不成功呢?这时候就要用到CAN的错误帧,当一个接收者收到错误的数据的时候(怎样判断的),它立即开始发送一个错误帧,则接下去总线上的信号就是这个错误帧,其它的节点和发送者也都会收到这个错误帧,那所有的节点都知道出错了,接收者会丢掉此次消息,而发送者会试图重发此次消息。这才是ACK SLOT真正的含义。

 

下面我们通过一个实例来看看CAN节点是如何进行ACK SLOT的动作的。我们抓取一个总线上面的信号波形,此波形已经是通过82C251解码过后的。

 

此主题相关图片如下:

         

抓取的波形,图中的四个通道分别表示两个节点的CANTX和CANRX,其中通道A,B表示NODE 1的CANTX和CANRX,通道C,D表示NODE 2的CANTX和CANRX。将其正对坐标中轴的部分展开,得到如下的图形,由上图我们清楚的看到,NODE 1的CANTX在接收到数据后立即响应,即向外发送数据,当数据发送完毕,到了ACK的时间内,见下图中黄色图标处,NODE 1的CANTX发送两个隐性位,而对于NODE 2,当发送者NODE 1的CANTX到了报文的ACK时间,NODE2也接收完数据,如果CRC校验通过,则NODE2的CANTX会相应的发送显性位,即通道C的红色图标处。如果总线上存在NODE 3和NODE 4或是更多NODE,则波形相同。图中的B和D都是CANRX,所以都有ACK的显性位出现。

此主题相关图片如下:




 

我们认为,发送者在发数据的时候,CANTX在发送数据,而CANRX同时也在接收数据,当发送者发送ACK为隐性时,接收到的ACK SLOT一定要是显性才会正确。那么,当有节点正确接收到了数据,在ACK SLOT填上显性位后,接收错误的节点这时候会如何呢?接收错误的节点就会马上发送错误帧,一般是发送连续的6个0或1,根据CAN的位填充原理,当有五个连续的0或1出现时,为了传送中的同步,必须插入一个反相位的BIT作为填充位,如果连续出现6个或以上的相同信号,则此次传送错误,数据将被丢弃。故当发送者收到这个错误帧后,便会知道发送出错,并试图重发数据。




 

抓取的波形,图中的四个通道分别表示两个节点的CANTX和CANRX,其中通道A,B表示NODE 1的CANTX和CANRX,通道C,D表示NODE 2的CANTX和CANRX。将其正对坐标中轴的部分展开,得到如下的图形,由上图我们清楚的看到,NODE 1的CANTX在接收到数据后立即响应,即向外发送数据,当数据发送完毕,到了ACK的时间内,见下图中黄色图标处,NODE 1的CANTX发送两个隐性位,而对于NODE 2,当发送者NODE 1的CANTX到了报文的ACK时间,NODE2也接收完数据,如果CRC校验通过,则NODE2的CANTX会相应的发送显性位,即通道C的红色图标处。如果总线上存在NODE 3和NODE 4或是更多NODE,则波形相同。图中的B和D都是CANRX,所以都有ACK的显性位出现。

<think>好的,我现在需要处理用户关于CAN报文格式、使用和解析的问题。首先,用户提到了参考的站内引用内容,里面提到了DBC文件的作用和基本概念。我需要确保回答中正确引用这些信息,同时还要结合用户的问题点展开。 首先,我应该先理解用户的问题:用户想了解CAN报文的格式、使用方法和解析方式。根据提供的引用内容,DBC文件是关键,因为它描述了如何解析CAN报文中的原始数据。因此,我需要从CAN报文的基本结构开始介绍,包括ID、数据长度、数据段等。 接下来,使用部分需要说明CAN报文在汽车网络中的实际应用,比如ECU之间的通信,以及如何通过DBC文件将原始数据转换为物理值。这里可能需要举例说明,比如发动机转速的解析,这样用户更容易理解。 然后是解析方法,这里需要详细说明DBC文件的结构,比如版本、波特率、信号定义等。同时,要提到常用的工具,比如Vector的工具、CANdb++ Editor,以及Python库如cantools。这样用户知道有哪些工具可以使用,特别是代码示例可能对开发者有帮助。 在确保格式正确方面,用户之前提到的系统级指令要求数学表达式用$...$,但这里可能用不上。但需要检查是否有需要的地方,比如数据位的计算。不过CAN报文更多是十六进制和二进制处理,可能不需要数学公式。但如果有涉及计算的话,比如信号值的转换,可能需要用LaTeX表达公式,比如物理值 = 原始值 × 因子 + 偏移量,写成$物理值 = 原始值 \times 因子 + 偏移量$。 另外,用户要求生成相关问题,我需要根据内容提出几个相关问题,比如DBC文件的具体结构、解析工具的比较、实时解析的挑战等,这些能帮助用户深入探索。 需要确保回答结构清晰,分点说明,每个部分有明确的标题。同时,引用标识要正确添加在相关段落末尾,例如在提到DBC文件作用的地方加上[^1]。 可能还需要检查是否有遗漏的信息,比如CAN报文的标准格式(标准帧和扩展帧的区别),数据段的字节排列方式(大端或小端),以及信号的多路复用等高级内容。不过根据用户的问题,可能不需要太深入,但简要提及可以增加全面性。 最后,确保语言使用中文,避免专业术语使用过多,必要时进行解释,让不同层次的用户都能理解。同时,代码示例部分要正确使用Python的语法,比如使用cantools库加载dbc文件并解析报文,这部分需要验证代码的正确性,确保示例能够运行。</think>### CAN报文格式、使用与解析方法 #### 一、CAN报文基础格式 CAN报文由**帧头**和**数据段**组成,具体结构如下: 1. **标识符(ID)**:11位(标准帧)或29位(扩展帧),用于区分报文优先级和类型 2. **数据长度码(DLC)**:4位,表示数据段长度(0-8字节) 3. **数据域**:0-8字节的负载数据,存储实际信息 4. **校验与控制段**:包括CRC校验位、ACK应答位等 标准帧示例: $$ ID(11bit)|RTR|IDE|DLC(4bit)|Data(0-8bytes)|CRC $$ #### 二、实际应用场景[^1] 1. **车辆控制**:发动机转速$RPM=Data[0] \times 256 + Data[1]$ 2. **状态监测**:电池电压$V=Data[2] \times 0.1 + 8.0$ 3. **故障诊断**:通过DTC码定位问题位置 #### 三、DBC文件解析流程 1. **文件结构** ```dbc BO_ 500 EMS_RPM: 8 EMS SG_ EngineRPM : 0|16@1+ (0.25,0) [0|65535] "rpm" VCU SG_ CoolantTemp : 16|8@1+ (1,-40) [-40|215] "℃" IPC ``` 2. **关键参数说明** - 信号起始位:`0|16`表示从第0位开始,长度16bit - 编码方式:`@1+`表示小端格式,数值无符号 - 转换公式:`物理值 = 原始值 × 0.25 + 0` #### 四、Python解析示例 ```python import cantools # 加载DBC文件 db = cantools.database.load_file('vehicle.dbc') # 解析CAN报文 message = db.get_message_by_name('EMS_RPM') decoded = message.decode(b'\x12\x34\x56\x78\x9A\xBC\xDE\xF0') print(f"转速: {decoded['EngineRPM']} rpm") print(f"水温: {decoded['CoolantTemp']} ℃") ``` #### 五、常用工具对比 | 工具名称 | 特点 | 适用场景 | |----------------|-------------------------------|--------------------| | CANalyzer | 图形化界面,实时分析 | 整车网络测试 | | CANdb++ Editor | DBC文件专用编辑器 | 数据库文件管理 | | cantools | Python库,支持脚本化处理 | 自动化测试开发 |
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值