简介:MT6701_Rev.1.6_中文版.pdf 是麦歌恩微电子 MT6701 磁性角度传感器芯片的官方中文数据手册,面向从事电机控制、机器人关节设计及非接触式人机交互的硬件工程师与嵌入式开发者。该芯片基于差分霍尔原理实现 0~360° 绝对角度检测,支持 I2C、SSI、ABZ、UVW、模拟电压、PWM 及 Z 轴按压检测等多种独立输出接口,最高转速 55,000 转/分钟,角度输出系统延时小于 5 微秒,并内置 EEPROM 供参数反复擦写。资源包共 1 个 PDF 文件,约 1.27MB,内容涵盖引脚定义、型号列表、功能框图、极限与电气参数、外加磁场参数、各输出模式参考电路与时序、寄存器表及 EEPROM 编程、机械角度与方向、SOP-8 与 QFN3x3-16L 封装信息等完整章节。目前已有 834 人学习下载,适合需要快速完成选型评估、接口配置与寄存器调试的读者对照查阅。
1. 拿到 MT6701_Rev.1.6_中文版.pdf 之后:磁编码器选型到底在选什么
如果你手上正躺着一份 MT6701_Rev.1.6_中文版.pdf,大概率你面对的是一个关节电机、云台或者闭环步进的方案,需要一颗能输出绝对角度、体积小、抗干扰还行的磁编码器芯片。MT6701 是一颗磁角度传感器,核心能力是把一颗径向充磁的磁铁旋转角度,转成 14 位分辨率的数字角度输出,同时支持 ABZ 增量、PWM、SSI、I2C 等几种对外接口。很多人第一次翻这份中文版手册,会被寄存器表和时序图劝退,但真正决定项目能不能跑起来的,其实就那么几个点:磁铁怎么装、气隙留多少、输出模式怎么选、零点怎么标定。这篇笔记就按我实际调这颗芯片的顺序,把手册里散落的关键信息串成一条能复现的路径,适合正在做电机闭环、又不想上昂贵光编的硬件和嵌入式工程师。
2. 先看懂 MT6701 的三种输出模式:ABZ、SSI、I2C 各自适合谁
选型阶段最容易翻车的地方,是拿到芯片就照着参考原理图焊,结果发现主控根本读不出角度。问题往往不在焊接,而在输出模式没和主控的接口能力对齐。MT6701 的几种输出不是随便挑的,它们对应完全不同的系统架构。
2.1 ABZ 增量输出:给只会数脉冲的 MCU 用
ABZ 是最省事的一种接法。芯片内部把绝对角度换算成 A/B 两路正交脉冲加一路 Z 索引,主控只要有个正交解码外设或者外部中断,就能算出相对角度。它的代价是上电不知道绝对位置,必须转一圈找到 Z 信号才能建立零点。
配置 ABZ 主要改两个参数:每圈脉冲数 PPR 和 Z 信号宽度。PPR 决定了分辨率,手册里给的寄存器可以设成 1 到 1024 之间的值。我一般按「电机极对数 × 4」起步,比如 7 对极的云台电机,PPR 设 28 就够做换相,想提高低速平滑度再往上加。
// 通过 I2C 配置 MT6701 为 ABZ 模式,PPR = 256 // 假设 7 位从机地址为 0x06,寄存器地址以手册 Rev.1.6 为准 #define MT6701_ADDR 0x06 #define REG_ABZ_RES 0x0E // ABZ 分辨率寄存器(示例地址,以手册为准) void mt6701_set_abz(uint16_t ppr) { uint8_t buf[3]; buf[0] = REG_ABZ_RES; // PPR 写入时通常按 实际值-1 编码,具体位域看手册寄存器表 buf[1] = (uint8_t)((ppr - 1) >> 8); buf[2] = (uint8_t)((ppr - 1) & 0xFF); i2c_write(MT6701_ADDR, buf, 3); }这段代码的关键不是 I2C 本身,而是ppr - 1这个编码习惯。很多磁编芯片的分辨率寄存器都是「写 N-1 表示 N 线」,手册寄存器表里会写清楚位宽和偏移。如果你直接写 256,实际出来是 257 线,低速换相就会有固定偏差。写完记得读回验证,别只写不读。
2.2 SSI 绝对输出:要上电即知角度就选它
SSI 是同步串行接口,主控给时钟,芯片在时钟沿把 14 位角度数据吐出来。它的好处是上电第一帧就是绝对角度,不需要找 Z。代价是占引脚,而且时钟频率不能太高,手册里一般标到几 MHz,实际走线长的时候我建议压到 1 MHz 以内。
SSI 的帧格式是「起始位 + 14 位数据 + 状态位 + CRC(可选)」。如果你主控的 SPI 外设支持 16 位以上帧,可以直接当 SPI 从机读,但要注意 MT6701 是芯片主动在时钟下降沿更新数据,CPOL/CPHA 要设成模式 1 或 3,具体看手册时序图。我踩过的坑是拿 SPI 模式 0 去读,数据整体偏移一位,角度看着像对的,其实一直在跳。
2.3 I2C 输出:调试和标定阶段最顺手
I2C 是我最推荐的调试入口。它速率不高,但胜在能读寄存器、能改配置、能读原始角度,标定零点的时候不用反复烧录固件。MT6701 的 I2C 从机地址通常是 0x06 或 0x0C,取决于 ADDR 引脚接法。读角度一般读两个字节,高字节在前,低 14 位有效。
import smbus2 bus = smbus2.SMBus(1) ADDR = 0x06 ANGLE_REG = 0x03 # 角度结果寄存器(示例,以手册为准) def read_angle(): data = bus.read_i2c_block_data(ADDR, ANGLE_REG, 2) raw = (data[0] << 8) | data[1] # 14 位有效,低两位可能是状态位,按手册掩码处理 angle = (raw >> 2) & 0x3FFF return angle * 360.0 / 16384.0 print(read_angle())这段 Python 适合在树莓派或者带 I2C 的调试板上快速验证磁铁装没装对。如果读出来角度一直在 0 和 360 之间乱跳,先别怀疑代码,大概率是磁铁没对准芯片中心,或者气隙太大导致磁场太弱。
3. 磁铁选型和机械安装:角度跳变的根源八成在这里
MT6701 是磁角度传感器,它的精度上限不取决于芯片,而取决于磁铁在芯片正上方产生的磁场质量。手册里会写推荐磁铁尺寸和磁场强度范围,但实际装配里,机械公差才是玄学的主要来源。
3.1 磁铁规格:直径、厚度、材料怎么定
常见做法是用直径 6mm、厚度 2.5mm 的钕铁硼径向充磁磁铁,表面磁场在芯片位置大概 30mT 到 60mT 之间。直径太小,磁场随角度变化不够明显,信噪比差;直径太大,边缘磁场不均匀,非线性误差上来。厚度影响的是磁场强度,太薄了气隙稍微一大就读不到。
我一般会先拿高斯计在芯片位置量一下,确认在手册推荐的磁场窗口内。如果没有高斯计,就用 I2C 读原始角度,手动转一圈,看角度曲线是不是单调。如果中间有平台或者回跳,先换磁铁,别急着改代码。
3.2 气隙和偏心:两个最容易被忽略的公差
气隙指的是磁铁底面到芯片表面的距离。手册里通常给一个推荐范围,比如 0.5mm 到 2mm。气隙越大,磁场越弱,角度噪声越大;气隙太小,磁铁可能蹭到芯片或者封装。我一般留 1mm 左右,用非磁性垫片控制。
偏心是磁铁旋转中心和芯片中心不重合。偏心 0.2mm 以内,角度误差还能接受;超过 0.5mm,你会看到角度曲线出现明显的二次谐波误差,表现就是电机低速转动时有一顿一顿的感觉。解决方法是把芯片放在磁铁正下方,用定位工装保证同轴。
3.3 零点标定:把机械零位写进芯片
绝对角度芯片都有零点偏移。MT6701 支持通过寄存器写零点偏移值,把某个机械位置对应的角度设成 0。标定步骤是:把电机固定到机械零位,读当前角度,把这个角度的补码写进零点寄存器。
// 把当前角度设为机械零点 void mt6701_set_zero(void) { uint16_t cur = mt6701_read_raw_angle(); // 读 14 位原始角度 uint16_t zero = (0x4000 - cur) & 0x3FFF; // 补码,具体算法看手册 uint8_t buf[3] = {REG_ZERO_H, (uint8_t)(zero >> 8), (uint8_t)(zero & 0xFF)}; i2c_write(MT6701_ADDR, buf, 3); }零点寄存器写入后,建议断电再上电,确认零点保持住了。有些批次的芯片零点寄存器需要写使能位,手册里会写,漏了这一步就会觉得「怎么标完又回去了」。
4. 避坑与排查:调 MT6701 时最常见的 5 个翻车现场
这一章是我自己踩过的坑,按现象、原因、解决三段写。你如果正卡在某个现象上,可以直接对号入座。
4.1 角度读数一直在跳,静止时也不稳
现象:电机不动,I2C 读出来的角度在正负几度范围内随机跳。
原因:磁场太弱或者电源噪声大。磁铁气隙过大、磁铁牌号不对、芯片供电没有去耦电容,都会导致 ADC 采样噪声变大。
解决:先把气隙缩到 1mm 以内,换 N42 以上牌号的磁铁;然后在芯片 VDD 和 GND 之间并 100nF 加 1uF 电容,走线尽量短。如果还跳,读一下手册里的磁场强度诊断寄存器(如果有),确认磁场在推荐窗口。
4.2 ABZ 模式下电机换相有固定偏差
现象:电机能转,但每个电周期都有一点点顿挫,像是换相时刻偏了。
原因:PPR 设置和电机极对数不匹配,或者 Z 信号宽度太窄,主控没抓到。
解决:PPR 设成极对数整数倍,Z 宽度按手册调到至少几个时钟周期。用示波器看 A/B/Z 三路波形,确认 Z 出现的位置和机械零位对齐。
4.3 SSI 读出来全是 0 或者全 1
现象:主控 SPI 读 SSI,数据要么全 0 要么全 1,偶尔有几个正常值。
原因:时钟极性相位不对,或者时钟太快,芯片还没更新数据主控就采样了。
解决:把 SPI 降到 500kHz 先试,CPOL/CPHA 按手册时序图改成模式 1 或 3。如果用的是软件模拟 SPI,注意在下降沿之后留一点延时再读。
4.4 标定完零点,断电又变了
现象:零点寄存器写进去,当时读是对的,断电重启后角度又偏了。
原因:零点寄存器需要写使能,或者写的是易失性寄存器,没有写到 EEPROM。
解决:查手册里零点寄存器的使能位和烧写命令,按顺序写。有些芯片需要发一个专门的「保存」命令,漏了这一步就白标。
4.5 I2C 通信偶尔 NACK
现象:大部分时间能读,偶尔 I2C 返回 NACK,重试又好了。
原因:上拉电阻太大或者总线电容太大,上升沿太缓。MT6701 在快速模式下对上升时间有要求。
解决:把上拉电阻从 10k 降到 4.7k 甚至 2.2k,缩短走线,降低总线速率到 100kHz 先验证。如果总线上挂了很多设备,考虑加 I2C 缓冲器。
5. 把 MT6701 用进闭环:从读角度到跑电流环的最后一公里
前面几章把芯片读通了,但真正让电机转得稳,还得把角度数据喂进电流环。这一章讲两个进阶技巧:一是怎么用 MT6701 的 14 位角度做电角度换算,二是怎么用它的零延迟特性做低速观测。
5.1 电角度换算:极对数和方向别搞反
MT6701 给的是机械角度,电机换相需要电角度。电角度 = 机械角度 × 极对数,再对 360 取模。方向也要注意,如果电机正转时角度减小,换相顺序要反过来。
#define POLE_PAIRS 7 float mech_angle = mt6701_read_angle_deg(); // 0~360 float elec_angle = fmodf(mech_angle * POLE_PAIRS, 360.0f); // 如果正转角度减小,取反 // elec_angle = fmodf((360.0f - mech_angle) * POLE_PAIRS, 360.0f);这段代码里fmodf不能省,否则电角度会一直累加,超出 360 后换相表就查错了。极对数写错的表现是电机能转但力矩小、发热大,用示波器看相电流波形会明显不对称。
5.2 低速平滑:用绝对角度做速度观测
低速时用差分角度算速度噪声很大,因为 14 位分辨率在 1ms 周期下量化误差被放大。我的做法是用一个一阶低通滤波加前馈:先算角度差分,再过一个截止频率 50Hz 左右的低通,同时把电流环的带宽压到速度环的 1/5 以下。
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 速度环周期 | 1ms | 和电流环同步 |
| 角度低通截止 | 50Hz | 再低会引入相位滞后 |
| 电流环带宽 | 1kHz | 至少是速度环 5 倍 |
| 极对数 | 按电机 | 写错直接换相异常 |
这张表是我在云台电机上跑下来的经验值,不是手册里的硬性规定。如果你的电机惯量更大,速度环可以再慢一点。
5.3 一个我常用来验证角度线性的小技巧
拿 MT6701 读一圈角度,存成 CSV,用 Python 画出来,看和理想直线的偏差。如果偏差曲线是正弦形状,说明磁铁偏心;如果是方波形状,说明某一位数据错了;如果是一条斜线,说明零点没标好。这个习惯帮我省了很多来回拆装的时间。
import numpy as np import matplotlib.pyplot as plt raw = np.loadtxt('angle.csv', delimiter=',') ideal = np.linspace(0, 360, len(raw)) error = raw - ideal plt.plot(error) plt.ylabel('angle error (deg)') plt.show()误差在正负 0.5 度以内,基本可以认为机械装配合格。超过 1 度,先查磁铁,再查零点,最后才怀疑芯片。
我自己的习惯是,每换一批磁铁或者改一次结构,都先跑一遍这个误差曲线,确认没问题再上电调电机。希望帮到你。
本文还有配套的精品资源,点击获取