基于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。
相关推荐
homelook4 小时前
【mqtt参数上云和小程序开发】【第5期】hcsr04超声波测距模块调试完成
嵌入式硬件
点灯小铭4 小时前
基于单片机的PWM三基色LED灯控制器设计与无线调色系统
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
Vae_Mars12 小时前
单片机中的TVS管
单片机·嵌入式硬件
hazy1k14 小时前
51单片机基础-直流电机控制
stm32·单片机·嵌入式硬件·51单片机
小莞尔16 小时前
【51单片机】【protues仿真】基于51单片机智能窗帘系统
c语言·stm32·单片机·嵌入式硬件·物联网·51单片机
我先去打把游戏先18 小时前
ESP32学习笔记(基于IDF):IOT应用——WIFI连接
笔记·单片机·嵌入式硬件·mcu·物联网·学习·esp32
清风66666620 小时前
基于单片机的简易智能衣架控制系统设计
单片机·嵌入式硬件·毕业设计·课程设计
酷飞飞21 小时前
I2C软实现基于GD32F407VE的天空星的配置
单片机·嵌入式硬件
充哥单片机设计21 小时前
【STM32项目开源】基于STM32的人体健康监测系统
stm32·单片机·嵌入式硬件