内容介绍
内容介绍
1. 所选任务介绍
任务名称 【新增 - 入门题】多圈角度读取与断电记忆验证
任务要求
0. 手动旋转磁铁,通过串口实时显示 ADMT4000 的圈数和角度,验证断电后数据是否保持。
- 通过 SPI 读取 ADMT4000 的多圈圈数和精确角度
- 串口实时打印当前圈数、角度值
- 手动旋转到任意位置后断电,重新上电,串口显示的圈数和角度与断电前一致
- 在 46 圈范围内多次测试,记录并展示断电前后的数据对比
2. 项目描述
使用Arduino通过SPI连接ADMT4000,完成通过SPI接口的寄存器的读取,对读取到的角度寄存器的换算。以实现断电多圈的实现。
由于手上没有合适的径向磁铁,故选用一个D10*H3的N52轴向磁铁作为传感器,通过美纹胶带固定在步进电机出轴上,同时,ADMT4000传感器模块通过铜柱,一同固定在步进电机上,从而保证一定的同心度,以及保留mm级别的误差,以模拟恶劣的现实条件。后期也可以通过控制步进电机,来完成闭环控制。
通过读取单圈角度和多圈角度,相互对照,来判断读取协议是否存在问题。
3.硬件介绍
3.1.硬件清单
- Arduino NANO与拓展模块 1枚
- ADMT4000 传感器模块 1枚
- GH转杜邦5P线 2组
- USB-TypeC线 2组
- 42步进电机 1个
3.2.硬件连接
// 硬件连接:
// MOSI - D11
// MISO - D12
// SCLK - D13
// nCS - D10
// RST - 3.3V / NC
// SHDN - 3.3V / GND
// COIL - NC
- 需要注意的是SHDN引脚,如果悬空会造成数据异常抖动,但是接高电平或者低电平皆不影响。
- Arduino是5V的逻辑电平,而ADMT的逻辑电平是3.3V,所以RST和SHDN引脚都无法接入GPIO。
3.3.硬件框图

3.4.硬件实物


4.软件代码
4.1.Arduino程序-初始化部分
// 本程序为ADMT4000 磁编码器的测试程序
// 硬件连接:
// MOSI - D11
// MISO - D12
// SCLK - D13
// nCS - D10
// RST - 3.3V / NC
// SHDN - 3.3V / GND
// COIL - NC
/************************* 硬件IO连接说明 *************************/
#define PIN_Serial_RX 0
#define PIN_Serial_TX 1
#define PIN_ADMT_SPI_MOSI 11
#define PIN_ADMT_SPI_MISO 12
#define PIN_ADMT_SPI_SCLK 13
#define PIN_ADMT_SPI_nCS 10
/************************* 串口配置 *************************/
#define Serial_BAUD 115200
/************************* 寄存器地址定义(片内无关页)*************************/ /*(用到)*/
#define ADMT_CNVPAGE 0x01 // 转换启动&页选择寄存器- [15:14]:CNV 位(00 = 触发转换,11 = 中止转换);- [4:0]:PAGE 位(选择目标页地址)
#define ADMT_ABSANGLE 0x03 // 绝对多圈角度寄存器(只读)- [15:10]:整圈数(0~46,0b110110 = 无效圈数);- [9:0]:单圈偏移(分辨率 0.351°)
#define ADMT_DIGIO 0x04 // 数字IO寄存器,需配合DIGIOEN寄存器配置端口模式
#define ADMT_ANGLE 0x05 // 单圈角度寄存器(只读)- [15:4]:12 位有效角度(分辨率 0.08789°,范围 0°~360°);- [3:0]:保留位(无意义)
#define ADMT_FAULT 0x06 // 故障寄存器- 故障位触发后保持高电平,需写0x0000清除;- 关键位:D13(圈数校验错误)、D0~D3(电源故障)
/************************* 寄存器地址定义(Page0x0)*************************/ /*(用不到)*/
//主要存储原始传感器数据、温度测量值等基础信息,需通过CNVPAGE寄存器切换至Page 0x0(PAGE[4:0]=0x00)访问。
#define ADMT_SINE 0x10 // 存储 AMR 角度传感器原始正弦值(未校正)
#define ADMT_COSINE 0x11 // 存储 AMR 角度传感器原始余弦值(未校正)
#define ADMT_RADIUS 0x18 // 存储 SINE/COSINE 向量的幅值(SQRT(SINE²+COSINE²))
#define ADMT_TMP 0x20 // 存储内部温度传感器数据(用于角度温度补偿)- 转换公式:T(°C)=(TMP_CODE-1168)/15.66;- [15:4]:12 位温度码
/************************* 寄存器地址定义(Page0x2)*************************/ /*(用不到)*/
//主要存储原始传感器数据、温度测量值等基础信息,需通过CNVPAGE寄存器切换至Page 0x2(PAGE[4:0]=0x02)访问。
#define ADMT_GENERAL 0x10 // 设备核心功能配置(采样模式、滤波、谐波校正源)
#define ADMT_DIGIOEN 0x12 // 配置 GPIO 端口功能模式(GPIO / 专用功能)及输出使能
#define ADMT_CNVCNT 0x14 // 存储转换序列完成次数计数器
#define ADMT_H1MAG 0x15 // 1 次谐波误差幅值校准
#define ADMT_H1PH 0x16 // 1 次谐波误差相位校准
#define ADMT_H2MAG 0x17 // 2 次谐波误差幅值校准
#define ADMT_H2PH 0x18 // 2 次谐波误差相位校准
#define ADMT_H3MAG 0x19 // 3 次谐波误差幅值校准
#define ADMT_H3H 0x1A // 3 次谐波误差相位校准
#define ADMT_H8MAG 0x1B // 8 次谐波误差幅值校准(默认使用出厂值)
#define ADMT_H8PH 0x1C // 8 次谐波误差相位校准
#define ADMT_ECCEDC 0x1D // 存储用户配置寄存器的错误校正码(ECC)
#define ADMT_UNIQID0 0x1E // 唯一设备标识寄存器 0 - 出厂烧录,用于设备追溯
#define ADMT_UNIQID1 0x1F // 唯一设备标识寄存器 1 - 与 UNIQID0/UNIQID2 组合构成完整设备 ID
#define ADMT_UNIQID2 0x20 // 唯一设备标识寄存器 2 - 只读,不可修改
#define ADMT_UNIQID3 0x21 // 唯一设备标识寄存器 3 - 存储 3.3V 供电、产品型号等固定信息
#define ADMT_ECCDIS 0x23 // 禁用 / 启用用户配置寄存器的 ECC 功能 - 写0x4D54禁用 ECC(更新配置前需操作);- 写0x0000启用 ECC
#include <SPI.h>
4.2.Arduino程序-SPI通讯接口API
// ADMT 通过SPI读取指定地址的寄存器(6位地址),返回16位数据
unsigned int ADMT_READ_REG(byte ADDR)
{
// SPI读时序:32位帧,格式为[忽略位(0) + 读写位(0为读指令) + 寄存器地址6位 + 读取返回24位(0x00)]
ADDR = 0b00111111 & ADDR; // 发送的高2位均为0,寄存器地址的6位按位取与
byte ReadByteBuff[] = {0x00,0x00,0x00}; // 用以存储返回的24位的数据,包括校验位
unsigned int ReturnData = 0x00; // 用以存储最后读取到的有效值,以供返回
bool CheckFlag = false; // 用以存储教研状态,教研状态通过则为true
while(CheckFlag == false) // 校验数据状态
{
digitalWrite(PIN_ADMT_SPI_nCS,LOW); // 第一步:SPI片选设为低电平,表示ADMT通信开始
SPI.transfer(ADDR); // 第二步:发送读指令和寄存器地址(高位先行)
for(int i=0;i<3;i++)
{
ReadByteBuff[i] = SPI.transfer(0x00); // 第三步:读取24byte的返回值
}
digitalWrite(PIN_ADMT_SPI_nCS,HIGH); // 第四步:SPI片选设为高电平,表示ADMT通信结束开始
ReturnData = (ReadByteBuff[0] << 8) | ReadByteBuff[1]; // 第五步:拼接2个Byte数据成一个int型
CheckFlag = true;
/*
if(((ReadByteBuff[2] & 0b10000000) >> 7) == 0x01) // 第六步:校验位最高第一位应为1
{
if((true) | (((ReadByteBuff[2] & 0b01000000) >> 6) == 0x00)) // 第七步:校验位最高第二位为C1,表示新数据,(0 = 无新数据,1 = 数据已更新),不做校验
{
if((true) | (((ReadByteBuff[2] & 0b00100000) >> 5) == 0x00)) // 第八步:校验位最高第三位为C0,表示转换忙标志,(0 = 空闲,1 = 转换中),不做校验
{
byte ReadByte = ReadByteBuff[2] & 0b00011111; // 第九步,校验CRC5
byte CheckByte = ReadByte; // 暂不做CRC5校验
if(ReadByte == CheckByte)
{
CheckFlag = true; // 校验通过,Flag为true,不进入下一个循环
}
}
}
}*/
}
return ReturnData;
}
4.3.Arduino程序-主程序
void setup()
{
delay(100);
Serial.begin(Serial_BAUD); // 串口初始化
pinMode(PIN_ADMT_SPI_nCS,OUTPUT); // SPI片选引脚设为输出
digitalWrite(PIN_ADMT_SPI_nCS,HIGH); // SPI片选设为高电平,表示未选中ADMT
SPI.begin(); // 初始化硬件SPI
SPI.setClockDivider(SPI_CLOCK_DIV2); // SPI时钟分频,Uno/Nano为16MHz/2=8MHz(接近10MHz,兼容)
SPI.setDataMode(SPI_MODE0); // SPI设置模式为Mode 0
SPI.setBitOrder(MSBFIRST); // SPI设置高位先行
Serial.println("System Online ...");
}
void loop()
{
// 读取单圈角度和绝对多圈角度
unsigned int rawAngle = ADMT_READ_REG(ADMT_ANGLE); // 读取单圈角度寄存器 - [15:4]:12 位有效角度(分辨率 0.08789°,范围 0°~360°);- [3:0]:保留位(无意义)
rawAngle = rawAngle >> 4; // 12位有效角度,保留高12位,去除低4位无意义的保留位
rawAngle = rawAngle * 0.08789; // 单圈角度转换为角度值,分辨率为0.08789°
unsigned int rawAbsAngle = ADMT_READ_REG(ADMT_ABSANGLE); // 读取绝对多圈角度 - [15:10]:整圈数(0~46,0b110110 = 无效圈数);- [9:0]:单圈偏移(分辨率 0.351°)
unsigned int raw = rawAbsAngle >> 10; // 6位整圈数,保留高6位,去除低10位单圈偏移
unsigned int absAngle = rawAbsAngle & 0b0000001111111111; // 10位单圈偏移,保留低10位,去除高6位整圈数
absAngle = absAngle * 0.351; // 单圈偏移转换为角度值,分辨率为0.351°
Serial.print("单圈角度: ");
Serial.print(rawAngle);
Serial.print(" | 圈数: ");
Serial.print(raw);
Serial.print(" | 绝对圈剩余角度: ");
Serial.println(absAngle);
}
4.4.串口反馈信息:

4.5.嵌入式代码说明:
- 软件代码均有注释,流程简单明了,就不做流程图叻。
- CRC5校验看起来比较复杂,这里保留了校验的流程与框架,但实际代码中已跳过。如果感兴趣可以自行补充。
- 程序未使用状态机,后续修改可以使用子函数编辑。
附件下载
STEP_MOTER.ino
团队介绍
个人爱好者,12年Arduino经验,15年ad经验的菜鸡。
评论
0 / 100
查看更多
猜你喜欢
2026 ADI机器控制设计竞赛 - 基于ADMT4000模块实现多圈角度读取与断电记忆验证本项目基于rp2350核心板,使用ardunio平台开发ADMT4000模块实现多圈角度读取与断电记忆验证的驱动程序。现在已经实现圈速读取功能,由于基于ardunio平台,其他开发板简单修改spi引脚配置即可快速上手,实现更广泛的应用。
Forest
10
2026 ADI机器控制设计竞赛-基于ADMT4000模块实现多圈角度读取与断电记忆验证该项目使用了ADMT4000模块,实现了多圈角度读取与断电记忆验证的设计,它的主要功能为:多圈角度读取与断电记忆验证。
Y_HT
10
2026 ADI机器控制设计竞赛 - 用ADMT4000模块实现多圈角度读取与断电记忆验证该项目使用了IAR软件开发平台、C语言,实现了通过GD32单片机驱动ADMT4000磁传感器的设计,它的主要功能为:ADMT4000的多圈圈数、单圈角度的读取与断电记忆。
xiaohutu...
12