CAN协议-数据帧-标准帧简介

CAN协议

CAN(Controller Area Network)是一种串行通信协议,用于在不同的电子设备之间进行通信。它最初是由德国的Bosch公司开发的,用于汽车电子系统中的通信。CAN协议被广泛应用于工业自动化、航空航天、医疗设备等领域。 

CAN协议使用的是一种基于广播的通信方式,即一个节点发送的数据可以被所有节点接收。

CAN协议采用了一种先进的差分信号传输技术,可以在高速通信时保证数据传输的可靠性。差分信号传输是指将数据信号与其反相信号同时传输,两个信号之间的电压差值表示数据信号的大小。CAN总线的差分信号传输方式可以有效地抵消噪声和干扰,提高通信的可靠性和抗干扰能力。

CAN协议中的帧主要分为四种类型:

  1. 数据帧(Data Frame):用于在CAN总线上传输数据,包含数据和标识符(ID)信息,最长可以传输8字节数据。

  2. 远程帧(Remote Frame):用于请求其他节点发送数据,只包含标识符信息,不包含数据。

  3. 错误帧(Error Frame):用于在CAN总线上报告错误信息,例如传输错误、格式错误等。

  4. 帧间隔(Interframe Space):用于在数据帧和远程帧之间提供一个时间间隔,以便其他节点有时间处理数据帧或远程帧。

数据帧和远程帧是CAN协议中最常用的两种帧。数据帧用于传输数据,而远程帧则用于请求其他节点发送数据。每个CAN节点都有一个唯一的地址,可以通过这个地址来确定数据的发送和接收方。在实际应用中,可以根据具体的通信需求选择使用合适的帧类型。

数据帧

CAN协议的数据帧分两种:标准帧和拓展帧,其差异主要在于识别位不同,标准帧的识别位是11位,而拓展帧是29位。

数据帧(标准帧和拓展帧)由7个段构成,分别是:
(1) 帧起始:表示数据帧开始的段。--SOF
(2) 仲裁段:表示该帧优先级的段。--ID和RTR

  • ID:表明报文的含义和优先级;(标准帧:11位ID;拓展帧:29位ID)
  • RTR 远程传送请求位(0:数据帧、 1:远程帧)
  • SRR 远程代替请求位   SRR = 1代表是远程帧(不包含数据段,只含标识符和控制位)
  • IDE 标识符拓展位  (0:11位ID,标准帧。1:29位ID,拓展帧)

(3) 控制段:表示数据的字节数及保留位的段。

  • IDE 标识符拓展位 (0:11位ID,标准帧。1:29位ID,拓展帧)
  • r1、r0 为保留位,默认为显性电平(逻辑0)
  • DLC 数据长度码:表示数据段的字节数,表示为0~8

(4) 数据段:数据的内容,可发送 0~8 个字节的数据。
(5) CRC 段:检查帧的传输错误的段。
(6) ACK 段:表示确认正常接收的段。
(7) 帧结束:表示数据帧结束的段。

标准帧

标准帧的数据帧由起始位、识别码、控制码、数据码、CRC、ACK和结束位组成,具体每一位的含义如下:

1.起始位:标识一个数据帧的开始,用于同步,只有在总线空闲期间节点才能发送。

2.识别码:用于标识数据帧所属的消息,是CAN协议中最重要的部分,也是唯一的消息标识符。高位表示消息的优先级,低位表示消息的类型。其长度和位分配可以根据具体的需求进行配置。

3.控制码:包括一个远程传输请求位(RTR)、一个扩展帧位(IDE)、保留位(空闲位res)和数据长度码(DLC)。

  • RTR位:用于标识数据帧是否为远程传输请求帧。当RTR位为0时,表示数据帧包含数据;当RTR位为1时,表示数据帧仅包含标识符,用于请求远程节点发送数据。
  • IDE位:用于标识数据帧的类型。当IDE位为0时,表示数据帧为标准帧;当IDE位为1时,表示数据帧为拓展帧。
  • res位:保留位,默认逻辑0。
  • DLC位:表示数据段的字节数,表示为0~8。

4.数据码:用于存储数据信息,数据域的长度可以为0-8个字节。

5.CRC码:用于进行CRC校验,其中最后一位是界定符--用于界定CRC序列,固定逻辑1。

6.ACK码:确定报文被至少一个节点正确接收。

7.结束位:7个连续的逻辑1,表示帧结束。

使用示例

以下是一个使用 CAN 协议的示例代码,使用了 Python 的 can 模块:

import can

# 创建 CAN 总线对象
bus = can.interface.Bus(bustype='socketcan', channel='vcan0', bitrate=250000)

# 创建 CAN 帧
msg = can.Message(arbitration_id=0x123, data=[0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], is_extended_id=False)

# 发送 CAN 帧
bus.send(msg)

# 接收 CAN 帧
msg = bus.recv()
if msg is not None:
    print(msg)

在上面的示例代码中,首先创建了一个 CAN 总线对象,使用了 socketcan 协议和一个虚拟的接口 vcan0,设置了比特率为 250000。然后创建了一个 CAN 帧,设定了帧 ID 为 0x123,数据为 0x11 到 0x88,共 8 个字节。接着发送了这个 CAN 帧,并尝试接收 CAN 帧,如果接收到了,就打印出来。

需要注意的是,使用 CAN 协议和具体的硬件相关,具体的设置可能因硬件而异。需要根据实际情况进行设置和调整。此外,还需要根据协议规范,对帧 ID 和数据进行编码和解码。

  • 6
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值