ADMT4000 多圈角度读取与断电记忆验证全流程实践
摘要: 本文从对 ADMT4000 磁性多圈编码器的初步认知出发,系统梳理了其核心技术参数与工作原理,通过 ANSYS 电磁仿真确定了芯片在磁路中的最优布局,基于 STM32G431 完成了 SPI 通信驱动开发,最终依托伺服系统对多圈角度读取及断电记忆功能进行了完整验证。全文覆盖"仿真-编码-实测"三个环节,可作为同类磁性编码器选型与集成的参考。
一、我的初步认知:磁性多圈编码器的痛点与期待
在多圈绝对值编码器领域,传统方案通常采用机械齿轮组或电池-backed 计数器来实现断电后的圈数保持。前者结构复杂、成本高;后者存在电池寿命和低温失效的风险。因此,当我接触到 ADMT4000 这颗"True Power-On Multiturn Sensor"时,最吸引我的点在于:它不需要外部电池,断电后依然能记住转过的圈数。
其核心原理是利用 GMR(巨磁阻)螺旋纳米线中的磁畴壁运动来记录旋转次数——这是一种真正的非易失性磁性记忆,而非依赖外部供电维持数据。这意味着即使在设备完全断电、磁体继续旋转的情况下,芯片也能在重新上电时报告正确的绝对位置。
二、ADMT4000 核心参数梳理
在正式动手之前,先对芯片的关键参数做一个系统梳理,这些参数直接决定了后续的磁路设计、通信配置和校准策略。
2.1 角度与位置测量能力
参数项 | 数值 | 说明 |
|---|---|---|
单圈角度范围 | 0° ~ 360° | AMR 角度传感器 + GMR 象限检测器 |
多圈计数范围 | 0 ~ 46 圈 | GMR 多圈传感器,True Power-On |
绝对角度输出范围 | 0° ~ 16,560° | 圈数与单圈角度组合输出 |
角度精度 | ±0.25° | 理想磁场条件下 |
角度分辨率 | 0.0879° (12-bit) | ANGLE 寄存器有效位 [15:4] |
绝对角度分辨率 | 0.351° | ABSANGLE 寄存器 10-bit 角度字段 |
角度噪声 (RMS) | 0.25° / 0.03° | 无滤波 / IIR 滤波启用 |
采样更新率 | 100 kSPS |
|
2.2 磁场工作窗口
参数项 | 数值 |
|---|---|
磁场工作范围 | 16 mT ~ 31 mT |
磁复位阈值 | > 60 mT @ 315°,≥ 10 μs |
绝对最大磁场 | 200 mT |
16 mT 的下限非常关键——手册明确指出这是保证 1 ppm 错误率所需的最低磁场强度。磁路设计必须确保在最差工况(温度漂移、机械公差、老化衰减)下,传感器位置的磁场强度仍然不低于 16 mT。
2.3 电气与通信接口
参数项 | 数值 |
|---|---|
主电源 VDD | 3.0 V ~ 3.6 V(典型 3.3 V) |
逻辑接口 VDRIVE | 1.7 V ~ 5.5 V |
工作电流 (连续转换) | 22 mA(典型)/ 30 mA(最大) |
零功耗模式电流 | 22 nA |
SPI 模式 | Mode 0(CPOL=0, CPHA=0),32 位帧 |
最高 SPI 速率 | 10 MHz |
启动时间 | 10 ms |
2.4 读取角度的关键注意事项
这一点在实际编程中极其重要,也是最容易踩坑的地方:
- ANGLE(0x05)和 ABSANGLE(0x03)必须在同一 SPI 事务中连续读取,即使用 64 位帧,且 CS 全程保持低电平。否则可能在读数间隙寄存器被更新,导致圈数和角度不匹配。
- GMR 多圈传感器的有效断电记忆范围严格限定在 0 ~ 46 圈。如果断电期间磁体转出了这个范围,上电后读数可能是错的
三、ANSYS 磁仿真:确定芯片最优安装位置
在将 ADMT4000 集成到伺服电机之前,磁路设计是必须跨越的第一道门槛。我使用 ANSYS Maxwell 对整个磁系统进行仿真,目标是:
- 确认传感器位置的磁场强度始终在 16 mT ~ 31 mT 的工作窗口内
- 优化芯片与磁体的相对位置,使磁场方向尽量平行于芯片平面
3.1 仿真模型搭建
仿真对象是一个典型的轴端安装方案(end-of-shaft):圆柱形径向充磁磁体10mm直径(材质 N35)安装在电机轴端,ADMT4000 放置在 PCB 上,正对磁体中心。
主要考虑的几何参数包括:
- 气隙(Air Gap):磁体底面到芯片表面的距离
3.2最终布局决策
基于仿真结果,最终确定:
- 标称气隙:6 mm

3.3 3D打印支架安装ADTM4000模块

四、软硬件流程介绍
磁路设计完成后,接下来需要编写 MCU 端的 SPI 驱动程序。我选用的是 STM32G431RBTx,主频 170 MHz,带有 3 路 SPI 接口,完全满足 10 MHz 通信速率的要求。
4.1 硬件连接流程图
4.2 主要硬件连接
ADMT4000 引脚 | STM32G431 引脚 | 说明 |
|---|---|---|
CS (Pin 17) | PA4 | 片选,低电平有效 |
SCLK (Pin 16) | PA5 (SPI1_SCK) | 时钟 |
SDI (Pin 15) | PA7 (SPI1_MOSI) | 数据输入到编码器 |
SDO (Pin 14) | PA6 (SPI1_MISO) | 数据输出到 MCU |
GND | GND | 供地 |
STM32G431最小系统板 | H7TOOL | TTL串口连接 |
H7TOOL | 电脑 | 电脑显示角度和多圈数据 |


4.3 软件流程图

4.4 CUBEMAX生产的SPI配置
void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
4.5 圈数与角度读取与解析
#include "admt4000.h"
/* 私有变量 ---------------------------------------------------------*/
static uint8_t tx_buff[8] = {0x83, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00};
static uint8_t rx_buff[8];
/* 私有函数声明 ---------------------------------------------------------------*/
static void admt4000_cs_low(void);
static void admt4000_cs_high(void);
/* 私有函数 ---------------------------------------------------------*/
static void admt4000_cs_low(void)
{
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
}
static void admt4000_cs_high(void)
{
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
}
/* 导出函数 --------------------------------------------------------*/
/**
* @brief 计算ADMT4000协议的CRC5校验码
* @param data 32位数据字
* @return 5位CRC校验值
*/
uint8_t admt4000_crc5(uint32_t data)
{
uint8_t crc = 0x1F; /* 初始值: 全1 */
for (int i = 30; i >= 5; i--) {
uint8_t input_bit = ((data >> i) & 0x01);
uint8_t feedback = ((crc >> 4) & 0x01) ^ input_bit;
crc = (crc << 1) & 0x1E; /* 左移1位,保持低5位 */
if (feedback) {
crc ^= 0x05; /* 多项式 x^2 + x^0 (二进制: 00101) */
}
}
return crc & 0x1F; /* 返回低5位 */
}
/**
* @brief 初始化ADMT4000接口
*/
void admt4000_init(void)
{
/* 命令字节已预设在tx_buff中 */
/* CS引脚和SPI初始化由CubeMX的MX_GPIO_Init/MX_SPI1_Init处理 */
}
/**
* @brief 从ADMT4000传感器读取角度数据
* @param data 数据结构的指针,用于存储读取结果
* @return 0=成功, 1=错误
*/
uint8_t admt4000_read(ADMT4000_Data_t *data)
{
if (data == NULL) {
return 1;
}
/*SPI通信*/
admt4000_cs_low();
HAL_SPI_TransmitReceive(&hspi1, tx_buff, rx_buff, 8, 0xFF);
admt4000_cs_high();
/* 复制原始缓冲区 */
for (int i = 0; i < 8; i++) {
data->raw[i] = rx_buff[i];
}
/* 从字节1-2解析粗角度 (10位) */
data->angle_raw = ((rx_buff[1] << 8) | rx_buff[2]) & 0x3FF;
data->angle_deg = data->angle_raw / 1024.0 * 360.0;
/* 从字节1高位解析圈数 */
data->turn = rx_buff[1] >> 2;
/* 从字节5-6解析细角度 (12位) */
data->angle_fine_raw = ((rx_buff[5] << 8) | rx_buff[6]) >> 4;
data->angle_fine_deg = data->angle_fine_raw / 4096.0 * 360.0;
/* 对前4字节进行CRC校验 */
data->crc_received = rx_buff[3] & 0x1F;
uint32_t crc_data = ((uint32_t)tx_buff[0] << 24) |
((uint32_t)rx_buff[1] << 16) |
((uint32_t)rx_buff[2] << 8) |
rx_buff[3];
data->crc_calculated = admt4000_crc5(crc_data);
data->crc_ok = (data->crc_received == data->crc_calculated) ? 1 : 0;
return 0;
}
五、伺服系统验证:多圈角度与断电记忆实测
驱动代码完成后,将整个系统接入伺服平台进行实测验证。验证目标分为三个层面:
5.1 验证项一:验证不断电的角度读取和多圈验证
方法:让伺服电机旋转360度看串口打印到电脑上的角度变化和多圈变化
结果:
- 单圈角度不变,341.19°
- 多圈数减少,23变为22


5.2 验证项二:验证断电的角度读取和多圈验证
方法: 断开编码器供电和单片机供电,让伺服单方向旋转3600度,看串口打印到电脑上的角度变化和圈速变化
结果:
- 单圈角度不变,341.19°
- 多圈数减少10,22变为12

结论: ADMT4000 的断电记忆功能工作正常,验证了 GMR 多圈传感器的非易失性记忆能力。
六、总结与经验
通过这次从仿真到编码再到伺服实测的完整验证流程,我对 ADMT4000 有了更深入的理解,也总结了几点关键经验:
- 磁路设计是根基。ANSYS 仿真帮助我在打板之前就确认了气隙、避免了反复打印结构的时间与成本。
- SPI 读取必须一次读取。ANGLE 和 ABSANGLE 必须在同一 CS 低电平窗口内读取,这是保证数据一致性的底线。代码中不要拆分两次独立的 SPI 事务。
总体而言,ADMT4000 是一颗设计成熟、功能可靠的磁性多圈编码器。它消除了电池备份的痛点,简化了系统架构,对于需要绝对位置感知但又受限于空间和成本的伺服系统来说,是一个非常值得考虑的选择。
