基于STM32F103驱动AS5600读取磁体旋转的模拟量/角度数据

文章目录

一、AS5600简介

  AS5600 是一款易于编程的磁性旋转位置传感器,具有高分辨率 12 位模拟或 PWM 输出。该非接触式系统可测量径向磁化同轴磁体的绝对角度。AS5600 专为非接触式电位器应用而设计,其坚固的设计可消除任何均匀外部杂散磁场的影响。 I²C 接口支持用户轻松编程非易失性参数,无需专用编程器。默认情况下,输出范围为 0 至 360 度。也可以通过编程零角度(起始位置)和最大角度(停止位置)来定义更小的输出范围。

AS5600 还配备了智能低功耗模式功能,可自动降低功耗。输入引脚 (DIR) 可根据旋转方向选择输出极性。如果 DIR 接地,则输出值会随着顺时针旋转而增大。如果 DIR 连接到 VDD,则输出值会随着逆时针旋转而增大。

  特性

    非接触式角度测量

    可编程最大角度从 18° 到 360°

    12位DAC输出分辨率

    输出方式:I2C接口 / PWM / 模拟输出

    7位I2C地址:0x36(地址不可配置)

二、引脚说明

VDD5V 5V 模式下的正电压供电
VDD3V3 3.3V 模式下的正电压电源
OUT 模拟/PWM输出
GND 地
PGO 编程选项(内部上拉,连接到 GND = 编程选项 B)
SDA I2C 数据
SCL I2C 时钟
DIR 方向极性(GND = 值顺时针增加,VDD = 值逆时针增加)

PGO引脚说明:

  1. 在 I²C 模式下,GPO 可以配置为:

      PWM 输出:角度值对应占空比。

      模拟电压输出:角度值对应电压 (0--VDD)。

      磁场检测信号(高/低电平)。

      配置方式:通过 CONF 配置寄存器 (0x07) 的 OUTS 位来选择。

  2. 在 "无 I²C" 模式下(即不使用 I²C)

      芯片上电后会通过 DIR、OUTS、PWM、GPO 等引脚电平采样来决定工作模式。比如:

      GPO 上电时接高电平 → 芯片进入 数字(PWM)输出模式。

      GPO 上电时接低电平 → 芯片进入 模拟输出模式。

  DIR 引脚控制磁铁旋转方向。如果 DIR 连接到 GND (DIR = 0),则从顶部顺时针旋转将产生计算角度的增量。如果 DIR 引脚连接到 VDD (DIR = 1),则计算的角度将逆时针旋转。

三、功能框图和数据的读写

写数据

读数据

指定地址读数据

四、寄存器说明

常用寄存器有:

CONF(0x07 / 0x08):配置寄存器

RAW ANGLE(0x0C / 0x0D):未缩放/未处理的原始角度数据,12-bit。

ANGLE(0x0E / 0x0F):已缩放/处理后的角度寄存器,12-bit。

RAW和ANGLE寄存器的区别:RAW 是芯片内部直接计算得到的无缩放角度;ANGLE 是按 ZPOS/MPOS/MANG(如有编程)以及滤波/死区后的输出值。

STATUS(0x0B):状态寄存器,包含磁铁检测位(Magnet Detected,MD)、Magnet Low/High(ML/MH)等位,判断是否检测到合适的磁场(MD=1 表示检测到磁铁)。

AGC(0x1A):自动增益控制,表示放大倍数,5V 下范围 0...255,3.3V 下 0...128。可用来补偿因温度变化、IC 与磁体之间的气隙以及磁体性能下降而导致的磁场强度变化。为了获得最稳健的性能,增益值应位于其范围的中间。

  典型的径向磁铁感应气隙在 0.5 mm 到 3 mm 之间,这取决于所选的磁体。更大、更强的磁铁允许更大的气隙。以 AGC 值为指导,通过调整磁体和 AS5600 之间的距离,使 AGC 值位于其范围的中心,可以找到最佳气隙。当使用直径为 0.25mm 的磁体时,参考磁体的旋转轴从封装中心的最大允许位移为 6 mm。

MAGNITUDE(0x1B / 0x1C):用于判断磁场强弱与是否饱和/过弱。

BURN(0xFF):写 0x40 到 0xFF 可做永久写入/OTP,慎重,写入次数有限。

  Burn_Angle 命令 (ZPOS, MPOS):主机微控制器可以使用 BURN_ANGLE 命令对 ZPOS 和 MPOS 进行永久编程。要执行 BURN_ANGLE 命令,请将值 0x80 写入寄存器 0x​​FF。BURN_ANGLE 命令最多可执行 3 次。ZMCO 显示 ZPOS 和 MPOS 已永久写入的次数。此命令仅在检测到磁铁存在 (MD = 1) 时执行。

  Burn_Setting 命令 (MANG, CONFIG):主微控制器可以使用 BURN_SETTING 命令永久写入 MANG 和 CONFIG。要执行 BURN_SETTING 命令,请将值 0x40 写入寄存器 0x​​FF。只有在 ZPOS 和 MPOS 从未被永久写入 (ZMCO = 00) 的情况下,才能写入 MANG。BURN_SETTING 命令只能执行一次。

五、数据的换算公式

  角度(deg) = raw / 4096.0 * 360.0。raw 为 0...4095(12-bit),即每 LSB ≈ 360/4096 = 0.087890625°。

  MCU ADC(12-bit)电压换算:V = ADC_raw / 4095.0 * Vref。其中, ADC_raw为OUT引脚输出的模拟量,Vref为接的供电电压。

六、STM32F103驱动AS5600获取数据

准备工作

  STM32F103C8T6开发板,OLED显示屏,AS5600磁编码器模块,磁铁等。

接线说明

STM32F103C8T6 AS5600
3.3V VCC
GND GND
PB10 SCL
PB11 SDA
PA0 OUT
PB8 OLED-SCL
PB9 OLED-SDA

代码示例

AS5600.c

c 复制代码
#include "as5600.h"
#include "oled.h"

void AS5600_Init(void)
{
	MyI2C_Init();
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1, &ADC_InitStructure);
	
	ADC_Cmd(ADC1, ENABLE);
	
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}

void AS5600_WriteData(uint8_t Wordaddress, uint8_t Data)
{
	MyI2C_Start();
	MyI2C_SendByte(AS5600_ADDR);
	MyI2C_ReceiveAck();
	MyI2C_SendByte(Wordaddress);
	MyI2C_ReceiveAck();
	
	MyI2C_SendByte(Data);
	MyI2C_ReceiveAck();
	MyI2C_Stop();
}

uint32_t AS5600_ReadData(uint8_t Wordaddress)
{
	uint8_t Data;
	
	MyI2C_Start();
	MyI2C_SendByte(AS5600_ADDR);
	MyI2C_ReceiveAck();
	MyI2C_SendByte(Wordaddress);
	MyI2C_ReceiveAck();
	
	MyI2C_Start();
	MyI2C_SendByte(AS5600_ADDR | 0x01);
	MyI2C_ReceiveAck();
	Data = MyI2C_ReceiveByte();
	MyI2C_SendAck(1);
	MyI2C_Stop();
	
	return Data;
}

uint16_t AS5600_ReadRawAngle(void)	//获取原始数值
{
    uint8_t hi = (uint8_t)AS5600_ReadData(AS5600_RAW_HI_REG);
    uint8_t lo = (uint8_t)AS5600_ReadData(AS5600_RAW_LO_REG);
    uint16_t val = ((uint16_t)hi << 8) | (uint16_t)lo;
    val &= 0x0FFF;   
    return val;      
}

uint16_t AS5600_ADC_ReadRaw(void)  //获取ADC数值
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}

float AS5600_ReadVolatge(uint16_t Vol)  //获取电压值
{
	float Volatge;
	Volatge = (float)Vol / 4095 * 3.3;
	return Volatge;
}

float AS5600_RawToDegree(uint16_t angle)  //获取角度
{
	return ((float)angle) * 360.0f / 4096.0f;
}

main.c

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "delay.h"  
#include "Delay.h"
#include "AS5600.h"
#include "OLED.h"

uint16_t rawAngle;
uint16_t adcRaw;
float  adcVolt, angleDeg;
char tmp[16];

int main(void)
{ 
    OLED_Init();
    AS5600_Init();
	OLED_ShowString(1,1,"RAW: ");
	OLED_ShowString(2,1,"ADC: ");
	OLED_ShowString(3,1,"Vol: 0.00V");
	OLED_ShowString(4,1,"ANG: 000.0");

	while(1)
	{
		rawAngle = AS5600_ReadRawAngle();  //角度原始数值
		adcRaw = AS5600_ADC_ReadRaw();	   //ADC模拟量
		adcVolt = AS5600_ReadVolatge(adcRaw);	//电压值
		angleDeg = AS5600_RawToDegree(rawAngle);  //角度:0-360°
		
		OLED_ShowNum(1,6,rawAngle,4);
		
		OLED_ShowNum(2,6,adcRaw,4);
		
		OLED_ShowNum(3, 6, adcVolt, 1);
		OLED_ShowNum(3, 8, (uint16_t)(adcVolt * 100) % 100, 2);

        OLED_ShowNum(4, 6, angleDeg, 3);
		OLED_ShowNum(4, 10, (uint16_t)(angleDeg * 1000) % 1000, 1);
		
		Delay_ms(50);
	}
}

效果展示

将磁铁固定在电机上,让电机转动。

注意事项

  1. AGC 与磁铁摆放:把磁铁放到合适的间隙(典型 0.5--3 mm),并用 AGC 值把距离调到居中(3.3V 下 AGC 0...128,目标约中间值)。如果 AGC 很小或很大,说明磁场太弱或太强。
  2. 程序写 OTP(Burn)非常谨慎:write 0x40 to 0xFF 会永久写入,次数有限。务必在确认无误后再做。
  3. 滤波设定:默认有 slow/fast filter,能在精度与响应间做折中;如果需要高速动态测量请降低慢滤波系数/调整 FTH。
相关推荐
HQB20261 天前
EG1198|屹晶微电子 120V 内置 MOS 异步降压 DC‑DC(高性价比)
嵌入式硬件·硬件工程
果壳science1 天前
张祥前实验如何获取正电荷
笔记·科技·嵌入式硬件·硬件工程·制造
南山电子nscn1 天前
中科芯CETC汽车电池管理系统BMS进口芯片国产型号替代指南
单片机·汽车·bms
沉淀的.晴天1 天前
can总线
stm32
桀人1 天前
认识AT24C02
stm32·单片机·嵌入式硬件
国科安芯1 天前
星间激光通信终端CANFD控制网络的时延确定性与辐射可靠性
网络·嵌入式硬件·信息与通信·canfd·低轨卫星·商业航天·抗辐射
一直C1 天前
嵌入式 Linux 驱动开发学习笔记:内核定时器、platform 总线与 I²C 驱动
linux·驱动开发·嵌入式硬件·学习·imx6ull
传感器与混合集成电路1 天前
150MHz主频、8路DAC与6路PWM:JLH221360伺服控制SIP解析
嵌入式硬件
comyccccc1 天前
STM32PID控制板设计全解析学习笔记
单片机·嵌入式硬件
碧海银沙音频科技研究院1 天前
实现炬芯ATS308X的usb cdc 串口IAP 固件升级功能实现
人工智能·嵌入式硬件·深度学习·算法