Funpack4-3 - 基于ADMT4000实现断电磁数据存储功能
该项目使用了ADMT4000,实现了ADMT4000传感器板的设计,它的主要功能为:磁数据采集。
标签
ADMT4000
Funpack4-3
磁数据采集
Bymyself
更新2026-02-03
12

一、项目描述

本次项目依托ADMT4000实现磁转数据的精准采集与直观显示,此项工作对应任务1。具体任务内容的实现,我们需要完成ADMT4000电路板及其测试结构的设计与实际搭建(这里的结构我们依托的之前参加活动用到的一个转动角度采集的结构)。在此基础上,利用任意一款MCU或Linux SoC精心设计了一套程序,该程序能够读取旋转圈数及角度数据,并实时呈现在彩色LCD屏幕上。其中,核心子任务便是开发ADMT4000的驱动程序,以准确捕获相关数据,同时借助彩屏驱动技术,实现数据的可视化展示。

二、硬件介绍

首先我们设计的主要器件就是ADMT4000,它是一种磁转数传感器,即使在设备断电时也能够记录磁系统的旋转次数。通电时可以查询该套件,以报告系统的绝对位置。绝对位置通过串行外设接口 (SPI) 报告。ADMT4000 最多可计数 46 圈外部磁场,以顺时针 (CW) 方向递增绝对位置计数。该套件包括三个磁传感器,一个用于计数系统旋转次数的巨磁电阻(GMR)转数计数传感器,一个 GMR 象限检测传感器和一个各向异性磁阻(AMR)角度传感器。AMR 角度传感器与 GMR 象限检测传感器结合使用,可确定系统在 360° 范围内的绝对位置。将 GMR 转数计数传感器输出与 AMR 角度传感器输出相结合,该套件就能以高角度精度报告系统的位置。

然后主控和显示用到的是我们论坛常用的一款开发板——带屏版的12指神探,它是在原板基础上,配备了一块240*240分辨率的LCD彩屏以及两个可程控按键和一个拨轮,丰富了人机交互功能,方便信息观察、界面切换等使用方式。此外还配备了白色外壳,精心设计的包装不仅使板卡日常使用时更加美观也便于板卡的站立以及使用安全。下面是我们实用的主要接口:


0

我们这里主要用到是SPI1接口。

三、硬件设计

这里我们主要是根据数据手册里面的推荐电路进行的设计,我们可以在数据手册中找到相应的硬件设计推荐,不需要太多的解读,可以直接进行参考设计,下面是数据手册中的推荐的一种:


0

我们由于结构上的限制我们绘制了如下的原理图和PCB:


0


0

实物图如下:


0

整体的连接效果如下:


0

四、软件流程及代码说明

软件流程图:

image.png

这里我们主要实现的就是屏幕的基本控制与显示,传感器的接口配置与基本控制再到数据的基本采集,然后实现数据与屏幕显的关联。。

下面介绍一下ADMT4000驱动文件的内容,主要包括的就是SPI接口的基本关联以及数据交互的函数,在此基础上进行应用函数的基本设计,主要包括的就是传感器读数据与写数据函数的关联,还有就是辞数据的读取以及处理:

class ADMT4000:
def __init__(self, spi_bus, cs_pin):
# Initialize SPI communication
self.spi = spi_bus
self.cs = Pin(cs_pin, Pin.OUT)
self.cs.value(1) # Set CS high initially

def _select(self):
"""Select the ADMT4000 by pulling CS low"""
self.cs.value(0)

def _deselect(self):
"""Deselect the ADMT4000 by pulling CS high"""
self.cs.value(1)

def _transfer(self, data):
"""Send and receive data over SPI"""
return self.spi.write_readinto(data, data)
def admt4000_compute_crc(reg_addr, reg_data, excess, is_write):
# Initialize CRC values for the 5-bit polynomial x^5 + x^2 + 1
crc = [1, 1, 1, 1, 1] # CRC bits, initialized to 1
poly = 0
xor = 0
data_in = 0

if is_write:
# For write, we prepare the data (reg_addr << 16) | reg_data, then shift it left by 3
data_in = ((reg_addr << 16) | reg_data) << 3
else:
# For read, we include excess in the CRC calculation
data_in = ((reg_addr << 16) | reg_data) << 3 | excess

# Perform CRC computation, starting from the highest bit (25 down to 0)
for i in range(25, -1, -1):
xor = ((data_in >> i) & 0x1) ^ crc[4]
poly = crc[1] ^ xor

# Shift the CRC values
crc[4] = crc[3]
crc[3] = crc[2]
crc[2] = poly
crc[1] = crc[0]
crc[0] = xor

# Return the calculated 5-bit CRC value
crc_ret = (16 * crc[4]) + (8 * crc[3]) + (4 * crc[2]) + (2 * crc[1]) + crc[0]
return char(crc_ret)

def read_register(self, register):
"""Read a register value from ADMT4000"""
data = bytearray(4) # Prepare for 16-bit register read
data1 = bytearray(4)
data[0] = register|0x00 # Register address
data[1] = 0x00 # Register address
data[2] = 0x00 # Register address
data[3] = 0x00 # Register address

Data1 = 0x0000

self._select() # Begin SPI transaction
self.spi.write_readinto(data, data1) # Transfer data
self._deselect() # End SPI transaction

Data1 = data1[1] << 8
Data1 |= data1[2]
return int(Data1) # Combine two bytes into 16-bit value

def write_register(self, register, value):
"""Write a value to a register"""
data = bytearray(4)
data[0] = register|0x40 # Register address
data[1] = (value >> 8) & 0xFF # High byte
data[2] = value & 0xFF # Low byte

data[3] = self.admt4000_compute_crc(data[0], value, 0x00, 1) # Low byte

self._select() # Begin SPI transaction
self._transfer(data) # Transfer data
self._deselect() # End SPI transaction

def read_angle(self):
"""Read the angle register (ANGLE)"""
angle = self.read_register(0x05) # ANGLE register address
return (angle>>4)*360/4096; # Convert to degrees

def read_abs_angle(self):
"""Read the absolute angle register (ABSANGLE)"""
abs_angle = self.read_register(0x03) # ABSANGLE register address
TurnCnt = (abs_angle>>8)/4;
ABSANGLE = (abs_angle&0x3ff)*0.351+TurnCnt*360;
return TurnCnt,ABSANGLE # Convert to degrees

在主程序中进行传感技数据的采集以及显示的刷新:

while True:

angle = sensor.read_angle()
Turn,Abs = sensor.read_abs_angle()

display.text(font2, str(int(angle))+" ", 80, 60,st7789.BLUE)
display.text(font2, str(int(Abs))+" ", 80, 100,st7789.BLUE)
display.text(font2, str(int(Turn))+" ", 80, 140,st7789.BLUE)

time.sleep(0.1)

五、功能展示

我们通过动图看一下转动磁铁带来的变化:


0

六、项目中遇到的问题

本次项目实现过程中遇到的最大问题就是在传感器数据读取的时候,由于我们在数据手册中发现,实际上如果不进行深入的配置的话,只需要对其中的两个传感器进行读取就可以,在实际读取过程中发现数据有时候是有的,有时候是没有的,也就是说有时候读的数据是准确的,有时候读的数据是非常不准确的,但是这些值都是稳定的值,所以说在排除的过程中发现我们的复位引脚需要控制,没有进行上拉导致了这个问题出现,所以我们在,进行原理图设计的时候一定要考虑一些冗余的设计或是些初始状态的一些设计,否则就需要我们通过软件控制进行。

七、心得体会

ADI推出的这款磁转数传感器,可以称为行业内的顶尖之作。感激此次活动的圆满举行,它为我们搭建了一个接触前沿器件的宝贵平台。此款传感器的控制操作相对简便易行,对于ADI的SPI通信机制,可以借助逻辑分析仪等专业工具,对通信过程实施严密监控,以确保其严格遵循时序规范,本次在进行问题处理的时候,我就借助了咱们这次12指神探化作的逻辑分析仪找到了问题的所在,大大解决了时间。

附件下载
20251115_NSPeetree.zip
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号