文章目录
一、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引脚说明:
-
在 I²C 模式下,GPO 可以配置为:
PWM 输出:角度值对应占空比。
模拟电压输出:角度值对应电压 (0--VDD)。
磁场检测信号(高/低电平)。
配置方式:通过 CONF 配置寄存器 (0x07) 的 OUTS 位来选择。
-
在 "无 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 写入寄存器 0xFF。BURN_ANGLE 命令最多可执行 3 次。ZMCO 显示 ZPOS 和 MPOS 已永久写入的次数。此命令仅在检测到磁铁存在 (MD = 1) 时执行。
Burn_Setting 命令 (MANG, CONFIG):主微控制器可以使用 BURN_SETTING 命令永久写入 MANG 和 CONFIG。要执行 BURN_SETTING 命令,请将值 0x40 写入寄存器 0xFF。只有在 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);
}
}
效果展示

将磁铁固定在电机上,让电机转动。
注意事项
- AGC 与磁铁摆放:把磁铁放到合适的间隙(典型 0.5--3 mm),并用 AGC 值把距离调到居中(3.3V 下 AGC 0...128,目标约中间值)。如果 AGC 很小或很大,说明磁场太弱或太强。
- 程序写 OTP(Burn)非常谨慎:write 0x40 to 0xFF 会永久写入,次数有限。务必在确认无误后再做。
- 滤波设定:默认有 slow/fast filter,能在精度与响应间做折中;如果需要高速动态测量请降低慢滤波系数/调整 FTH。