【STM32系列教程】0x0B CAN与大疆电机

CAN协议

协议概述

教程:

特征:

  • 两根差分数据线(CAN_H、CAN_L),抗干扰,无需时钟线
  • 总线上挂载多设备,异步通信,冲突时通过报文ID进行仲裁
  • 报文长度1~8字节
  • 广播式通信、请求-响应式通信
  • 应答机制、CRC校验机制
  • 分为低速和高速两种,电路连接和电平有所不同

差分信号

https://en.wikipedia.org/wiki/Differential_signalling

用两条平行的、等长的走线,传递互补的信号,利用两根线之间的电平差表示数值。
例如:RS485, USB, CAN

差分信号抗干扰能力强,因为两根差分走线之间的耦合很好,当外界存在噪声干扰时,几乎是同时被耦合到两条线上,而接收端关心的只是两信号的差值,所以外界的共模噪声可以被完全抵消。

电路连接

高速/低速CAN的总线连接

显性电平/隐性电平:

  • 和生物学到的显性基因/隐性基因类似
  • 显性电平和隐性电平同时发送时,信号线上读取到的为显性电平
  • 在CAN通信中,0为显性电平,1为隐性电平
  • 两个设备分别同时发送0和1,信号线上读取到0

高速/低速CAN的电平标准

CAN收发器

帧格式

帧类型

  • 数据帧:主动发送帧,发送数据,根据ID长度分为标准的和扩展的两种
  • 遥控帧:主动发送帧,请求数据,根据ID长度分为标准的和扩展的两种
  • 错误帧:硬件自动发送,出错时会发送
  • 过载帧:硬件自动发送,忙碌时会发送
  • 帧间隔:硬件自动发送,分割主动发送帧,以空出时间插入自动发送帧

数据帧格式

  • 起始段(SOF):1bit,标志帧起始,显性电平0
  • 仲裁段
    • (ID):11bit,表示CANID,同时用于仲裁
    • (RTR):1bit,数据帧为0,遥控帧为1
  • 控制段:
    • (IDE):1bit,标准帧为0,扩展帧为1
    • (R0):1bit,保留位,0
    • (DLC):4bit,数据长度
  • 数据段:0~8bytes
  • 校验段
    • (CRC):15bit,CRC校验码
    • (CRC delimiter):1bit,隐性电平1
  • 回复段
    • (ACK):1bit,接收设备控制,正确为0,错误为1
    • (ACK delimiter):1bit,隐性电平1
  • 结束段(EOF):7bit,隐性电平1

ID仲裁

概念:在同一个通信系统中,有时有多个设备想要同时发送信息。但是通信资源有限,当多个设备均想要占用同一个通信资源时,协议必须制定一种规则,旨在协调冲突,判断谁先应该占用资源,同时规定未占用资源的设备的行为。这就是仲裁。对于CAN这样的总线协议,数个设备直接连接到同一对线缆上,对线缆这个公用通信资源的仲裁尤其重要。

我们先理解只要有节点发送显性位,不论总线上其他节点如何发送,总线的整体状态一定是显性(逻辑0)。所有节点同步发送自己的ID的每一位时,查看总线状况。由于显性位会覆盖隐形位,于是对于节点来说,发送时只会有三种情况:自己发送隐性并且总线状态隐性、自己发送显性并且总线状态显性、自己发送隐性并且总线状态显性。

节点发送\总线上其它设备 显性(0) 隐性(1)
显性(0) 继续发送 总线状态被自己覆盖为显性,相当于(显性,显性)
隐性(1) 终止发送(失去仲裁) 继续发送

节点一边发送,一边接收。

  • 如果节点发送的位与总线上的位相同,那么节点继续发送。
  • 如果节点发送时,总线状态与自己发送的不一样,那么意味着这个节点的ID一定比某个同时发送的节点的大。那么根据CAN协议规定,这个节点失去仲裁。

这样一来,每个节点在发送自己ID的时候同步的进行了仲裁,任何接收端只需要一直接受就可以,总线是否有冲突与接收端无关,使得CAN系统不需要额外的时间来仲裁,非常高效。

举例:两节点ID分别为9和10

  • 9(1001)

  • 10(1010)

假设两节点同时发送数据。第一个时间段,两者同步发送1,总线为1,均继续发送。第二个时间段,两者同步发送0,总线为0,均继续发送。第二个时间段9发送0,10发送1,总线状态0。9继续发送,10看到总线状态与自己发送的不一致,于是中断之后所有发送。仲裁完成。9之后继续正常发送

位时序

概述

  • CAN协议为异步协议,无时钟线。设定固定的波特率进行采样
  • 由于晶振会随着温度变化而产生漂移,为了避免细微的时钟不一致,使得采样更加精确,设计以下的机制
  • 将传输一个Bit的时间细分为多个阶段,每一段时长为若干Tq最小的时间单位

分段

  • SS 同步段 1Tq 边沿跳变应该发生在这一段时间里
  • PTS 传播时间段 1~8Tq 实际上电平跳变时可能会有震荡,为了等待数据线上的电压稳定下来而设置
  • PBS1 相位缓冲段1 1~8Tq
  • PBS2 相位缓冲段2 2~8Tq 通过调整PBS1和PBS2的时间长短,控制采样点的前后

image-20240921213813329

硬同步(帧开始时同步)

  • 开始发送,发送方开始计时,在SS时间段中将数据线驱动为逻辑低电平
  • 在检测到SOF (Start Of Frame)下降沿时,接收方同步开始从SS段计时

再同步(逻辑电平跳变边沿不在SS段时再同步)

  • 除了帧开始时的第一个下降沿,后续每个数据位都可以进行再同步
  • 如果逻辑跳变发生在SS段前或后,则对应增加PBS1或者减少PBS2
  • SJW:最大补偿的Tq数,用于防止单次补偿过度

image-20240921214017002

STM32 CAN外设

image-20240920200822204

发送

  • 三个发送缓存(邮箱)
  • CAN外设自动在总线空闲时从三个邮箱中选择一个进行发送
  • 可以配置优先级TXFP (TX Fifo Priority)
    • 1: 先请求先发送
    • 0: 按报文ID优先级发送
  • 如果发送失败,可以配置NART (Not Allow ReTransmit)=1禁止自动重传

一个邮箱的状态图如下:

image-20240921170812871

  • RQCP:发送请求已经完成

  • TXOK:发送成功

  • TME:发送邮箱空

  • ABRQ:终止发送

接收

  • 两个三级接收FIFO缓存(邮箱)
  • CAN外设接收到报文,进入过滤器匹配
  • 如果报文符合过滤条件,则会被放入过滤器指定的一个FIFO
  • 如果FIFO已满,有新的报文到达,可以配置RFLM (Recieve Fifo Lock Mode)
    • 1: FIFO上锁,新到来的报文被丢弃
    • 0: FIFO未上锁,丢弃队列中末尾(最晚到达)的报文,再放入新的报文

一个三级接收FIFO的状态图如下

image-20240921171104858

过滤器

image-20240921181559968

每一个过滤器有两个32位的寄存器,和以下几个过滤器配置位

  • FSCx(Filter Bank Scale):

    • 0: 每个过滤器使用4个16位寄存器,仅支持标准CAN地址长度 (将32位的寄存器拆成两个16位的使用,能更好的利用资源)
    • 1: 每个过滤器使用2个32位寄存器,支持标准和扩展CAN地址长度
  • FBMx(Filter Bank Mode):

    • 0: 掩码模式 将新收到的报文ID和过滤器中的ID进行比较,但是仅比较Mask中为1的位(类似IP地址掩码)
    • 1: 列表模式 将新收到的报文ID和过滤器中的ID进行比较,一个过滤器允许两个特定的报文ID
  • FACT(Filter ACTive): 过滤器使能开关

  • FFA(Filter Fifo Assignment): 通过过滤器的报文进入哪一个FIFO

掩码机制

配置为掩码模式时,过滤器将输入的报文ID和寄存器中的ID进行比较,但是仅比较二进制下,Mask中为1的位,其它位无论是什么都可以。

用公式来描述,满足以下公式的数据包,可以通过过滤器 CAN_ID & MASK == FILTER_ID & MASK

例子

  • 屏蔽所有单数ID
    Filter = 0
    Mask = 1
  • 接收 ID 范围在 0x100 ~ 0x1FF 的报文
    Filter = 000100000000
    Mask = 101100000000
  • 接收 ID 为偶数且最高 4 位固定的报文
    Filter = 10100000
    Mask = 11110001
    表示最高 4 位必须匹配(必须是0x1010),中间 3 位可以忽略,最低位必须为 0(偶数)

DJI电机

分类

电机型号 电调型号 减速比 驱动方式 链接
snail C615 电机直驱 PWM https://www.dji.com/cn/snail
2006 C610 36:1 CAN+PWM https://www.robomaster.com/zh-CN/products/components/general/M2006
3508 C620 3591:187 CAN+PWM https://www.robomaster.com/zh-CN/products/components/general/M3508
6020 内置电调 电机直驱 CAN+PWM https://www.robomaster.com/zh-CN/products/components/general/gm6020/

编码器和减速箱

编码器:可以读取某个旋转轴的角度/速度信息。

对于没有减速箱的电机(6020),编码器可以直接读出输出轴角度

对于包含减速箱的电机(2006/3508),编码器安装在动力未经过减速箱之前的位置上(电机屁股上)。此时会出现问题:编码器同一个位置对应着电机总体动力输出轴的不同位置。

CAN通信与报文

电机ID

为了能在一根总线上挂载多个电机,每个电机有一个唯一的电机ID,范围1~8共8个可用ID。

可以观察电调绿灯闪烁次数,得知当前设置的电机ID。设置电机ID的方式请参考对应电调的说明书。

[!NOTE]

注意区分电机IDCAN报文ID

通信报文

电调说明书里详细描述了大疆电机的通信报文。

根据电机ID的不同,电调会接收某个CAN ID上的控制报文,并且将自己的实时状态用另一个CAN ID发送到总线上。控制报文(8字节)包括16bit的字段“转矩电流”,它正比于电机的输出力矩。反馈报文(8字节)包括角度、转速、实际转矩电流、温度多个字段。

GM6020电机比较特殊,旧固件只能控制“转矩电压”,新固件可以在RoboMaster Assistant软件中开启“转矩电流”控制。

为了节省CAN带宽,控制报文设计为一个报文可以控制四个电机。一个控制报文有8字节,包括4个16bit的转矩电流字段,对应电机ID为1~4或5~8的电机。也就是说,多个电调侦听同一个CAN ID上的控制报文,并且将自己的数据用独立的CAN ID反馈。

电机ID C610与C620 6020 电压|电流模式
1 0x200[0:1] / 0x201 0x1FF|0x1FE[0:1] / 0x205
2 0x200[2:3] / 0x202 0x1FF|0x1FE[2:3] / 0x206
3 0x200[4:5] / 0x203 0x1FF|0x1FE[4:5] / 0x207
4 0x200[6:7] / 0x204 0x1FF|0x1FE[6:7] / 0x208
5 0x1FF[0:1] / 0x205 0x2FF|0x1FE[0:1] / 0x209
6 0x1FF[2:3] / 0x206 0x2FF|0x1FE[2:3] / 0x20A
7 0x1FF[4:5] / 0x207 0x2FF|0x1FE[4:5] / 0x20B
8 0x1FF[6:7] / 0x208 不支持