一、前言

最近在做外骨骼相关控制板时,用到了 MT6701 磁编码器来获取关节角度。

这个器件支持很多输出方式,比如 ABZ、UVW、PWM、模拟量、I2C、SSI 等。对于 MCU 读取绝对角度这件事来说,SSI 模式是一个很实用的方案:

  • 接线简单
  • 读取速度快
  • 直接输出绝对位置
  • 带磁场状态位和 CRC 校验,可靠性较高

但真上手以后会发现,MT6701 的 SSI 并不是“随便按 SPI 读一下就完事”。尤其在时钟边沿、CS 时序、首位对齐、CRC 校验这些细节上,如果没理解透,读出来的数据就很容易错位、跳变甚至完全不对。

这篇文章就结合手册和项目实践,系统整理一下:

  • MT6701 的 SSI 数据格式
  • 时序图到底该怎么理解
  • STM32 上如何正确读取
  • 有哪些容易踩坑的点
  • 实际开发中有哪些使用技巧

二、MT6701 的 SSI 模式到底是什么

MT6701 的 SSI 接口本质上是一个同步串行输出接口,使用三根核心线:

  • CSN:片选,低有效
  • CLK:时钟,由主机提供
  • DO:数据输出,由 MT6701 输出给主机

工作方式很简单:

  1. 主机把 CSN 拉低
  2. 主机输出时钟 CLK
  3. MT6701 在时钟配合下从 DO 输出角度数据
  4. 主机把数据采回来
  5. 主机把 CSN 拉高,本次传输结束

三、MT6701 SSI 一帧数据格式

根据手册,MT6701 的 SSI 一帧总共 24 bit,而且是 MSB first,高位先出。

数据组成如下:

D13 D12 ... D0 Mg3 Mg2 Mg1 Mg0 CRC5 CRC4 ... CRC0

也可以写成:

  • 前 14 bit:角度原始值 D[13:0]
  • 中间 4 bit:磁场状态 Mg[3:0]
  • 最后 6 bit:CRC 校验 CRC[5:0]

1)角度数据

角度数据为 14 位,所以范围是:

0 ~ 16383

换算成角度公式:

angle = raw / 16384.0f * 360.0f;

比如:

  • 0 对应 0°
  • 8192 对应 180°
  • 16383 接近 360°

2)磁场状态位

SSI 不仅给角度值,还带了磁场状态,这一点很有用。

Mg[3:0] 中,常用判断主要看低两位:

Mg[1:0]含义
0磁场正常
1磁场过强
2磁场过弱

此外还有扩展状态位,例如:

  • Mg[2]:按键相关状态
  • Mg[3]:失去追踪

在工程上最重要的一点是:

不要只读角度,必须顺带检查磁场状态。

因为很多“角度值抖动、跳变、偶发错误”并不是通信问题,而是磁钢位置、气隙、偏心或磁场强度不合适。

3)CRC 校验

MT6701 的 SSI 数据帧最后 6 位是 CRC,用来保证通信可靠性。

CRC 特征:

  • 位宽:6 bit
  • 多项式:x^6 + x + 1
  • MSB first
  • CRC 覆盖范围是:
    • 14 bit 角度
    • 4 bit 磁场状态
    • 共 18 bit

这意味着什么?

你不能只把前两个字节一拼就当结果可信,最好必须做 CRC 校验。

如果不做 CRC,在电机、CAN、电源开关等强干扰环境下,偶发的位错误很难第一时间发现。

四、MT6701 的 SSI 时序该怎么理解

这里是最容易踩坑的地方。

根据手册时序说明,可以提炼成一句最关键的话:

DO 在 CLK 上升沿更新,主机应在 CLK 下降沿采样。

这句话很重要,几乎决定了 SPI 模式配置对不对。

1)边沿关系

MT6701 的 SSI 推荐理解方式是:

  • 上升沿:MT6701 更新输出位
  • 下降沿:主机采样这一位

所以从 MCU 接收的角度看:

下降沿读数是安全的。

2)为什么常配置成 SPI Mode 2

如果 MCU 用 SPI 外设来模拟 SSI,一般会配置成:

  • CPOL = 1
  • CPHA = 0

即 SPI Mode 2

前面我们刚聊过这个模式:

  • CPOL=1:时钟空闲为高
  • CPHA=0:第一个边沿采样
  • 因为空闲高,所以第一个边沿是下降沿

于是刚好对应:

下降沿采样

这就和 MT6701 的时序要求匹配上了。

3)一句话记忆

如果你总忘,可以直接记:

MT6701 SSI:空闲高,下降沿采样。

五、项目里最关键的一个坑:第一个采样位无效

这是我觉得最值得专门强调的一点。

在项目实践中,虽然 SPI 配成了 Mode 2,但直接读 24 bit 往往还是不对。根本原因在于:

MT6701 是在 CSN 拉低以后才开始驱动 DO 的,而 SPI 主机通常在 CS 拉低后会立刻打时钟。

这样就容易导致:

  • 第一个采样点到来时
  • DO 还没有准备好真正的首位数据
  • MCU 读到的是一个无效空闲位

最终表现就是:

  • 24bit 整体错 1 位
  • 角度数值完全不对
  • CRC 校验失败

实际测试时会发现,解析之后的角度一直在 180 度以上,而且 CRC 无法通过。我们先看两张图:

在这里插入图片描述
在这里插入图片描述

很明显,数据在时钟空闲(高电平)时更新,之后的第一个边沿(下降沿)采样即可得到正确的数据。SPI 设置为模式 2 符合时序,但是我们的硬件 SPI 在 CSN 拉低时就已经工作了,此时 CLK 为高电平(空闲)。我们看手册里的 Figure 25,当 CLK 第一次下降沿时 DO 还没有写入,读出来的第一个数恒为 1,当然会失败。

在这里插入图片描述

解决办法

一个非常实用的技巧是:

不要只读 24 bit,而是多读 8 bit,总共读 32 bit。

然后处理方式是:

  1. 连续收 4 个字节
  2. 拼成 32 位
  3. 左移 1 位
  4. 丢弃无效首位
  5. 取高 24 位作为真正有效数据帧

这个方法在工程上很好用,能稳定解决首位错位问题。

代码思路示意

uint8_t rx[4];
uint32_t frame32;
uint32_t valid24;

CSN_Low();
spi_read_4bytes(rx);
CSN_High();

frame32 = ((uint32_t)rx[0] << 24) |
          ((uint32_t)rx[1] << 16) |
          ((uint32_t)rx[2] << 8 ) |
          ((uint32_t)rx[3] << 0 );

frame32 <<= 1;                 // 丢弃首个无效位
valid24 = (frame32 >> 8) & 0xFFFFFF;

然后再从 valid24 中拆字段。

六、24bit 数据怎么拆

拿到 valid24 后,就可以这样提取:

uint16_t raw_angle = (valid24 >> 10) & 0x3FFF;   // 14bit
uint8_t  mag_state = (valid24 >> 6)  & 0x0F;     // 4bit
uint8_t  crc_rx    =  valid24        & 0x3F;     // 6bit

解释一下:

  • bit23~10:角度值
  • bit9~6:磁场状态
  • bit5~0:CRC

这和前面说的帧格式一一对应。

七、总结

本文从项目实战的角度,系统梳理了 MT6701 磁编码器在 SSI 模式下的使用要点,核心收获如下:

1. 数据帧结构要记牢:24 bit 数据包含 14 bit 角度、4 bit 磁场状态和 6 bit CRC,解析时必须按位正确提取。

2. 时序配置有讲究:MT6701 的 SSI 要求“空闲高、下降沿采样”,对应 SPI Mode 2(CPOL=1, CPHA=0),这是正确通信的前提。

3. 首位错位是最大陷阱:由于 CSN 拉低后 DO 尚未就绪,直接读 24 bit 会导致首位无效。工程上推荐读 32 bit 再左移丢弃无效位,这是经过验证的可靠方案。

4. 可靠性检查不能省:磁场状态位和 CRC 校验是 MT6701 提供的两大可靠性保障。在电机、CAN 等强干扰环境下,务必检查这两项,否则偶发的位错误很难排查。

5. 代码实现有模板:本文提供的读 32 bit 左移取高 24 bit、再按位拆字段的代码思路,可以直接复用到 STM32 项目中,稍作适配即可稳定运行。

总的来说,MT6701 的 SSI 模式并不复杂,但细节决定成败。只要理解了时序关系,掌握了首位对齐的技巧,并养成检查磁场状态和 CRC 的习惯,就能在项目中稳定可靠地获取绝对角度数据。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐