基于STM32F103驅(qū)動(dòng)AS5600讀取磁體旋轉(zhuǎn)的模擬量/角度數(shù)據(jù)

一、AS5600簡(jiǎn)介

??AS5600 是一款易于編程的磁性旋轉(zhuǎn)位置傳感器,具有高分辨率 12 位模擬或 PWM 輸出。該非接觸式系統(tǒng)可測(cè)量徑向磁化同軸磁體的絕對(duì)角度。AS5600 專為非接觸式電位器應(yīng)用而設(shè)計(jì),其堅(jiān)固的設(shè)計(jì)可消除任何均勻外部雜散磁場(chǎng)的影響。 I2C 接口支持用戶輕松編程非易失性參數(shù),無(wú)需專用編程器。默認(rèn)情況下,輸出范圍為 0 至 360 度。也可以通過(guò)編程零角度(起始位置)和最大角度(停止位置)來(lái)定義更小的輸出范圍。
AS5600 還配備了智能低功耗模式功能,可自動(dòng)降低功耗。輸入引腳 (DIR) 可根據(jù)旋轉(zhuǎn)方向選擇輸出極性。如果 DIR 接地,則輸出值會(huì)隨著順時(shí)針旋轉(zhuǎn)而增大。如果 DIR 連接到 VDD,則輸出值會(huì)隨著逆時(shí)針旋轉(zhuǎn)而增大。
??特性
????非接觸式角度測(cè)量
????可編程最大角度從 18° 到 360°
????12位DAC輸出分辨率
????輸出方式:I2C接口 / PWM / 模擬輸出
????7位I2C地址:0x36(地址不可配置)

二、引腳說(shuō)明

VDD5V 5V 模式下的正電壓供電
VDD3V3 3.3V 模式下的正電壓電源
OUT 模擬/PWM輸出
GND
PGO 編程選項(xiàng)(內(nèi)部上拉,連接到 GND = 編程選項(xiàng) B)
SDA I2C 數(shù)據(jù)
SCL I2C 時(shí)鐘
DIR 方向極性(GND = 值順時(shí)針增加,VDD = 值逆時(shí)針增加)

PGO引腳說(shuō)明:
??PGO=高電平(懸空/VDD):AS5600處于正常工作模式,僅讀取角度數(shù)據(jù)。
??PGO=低電平(GND):進(jìn)入編程模式,允許配置零位、最大角度等參數(shù)。
??DIR 引腳控制磁鐵旋轉(zhuǎn)方向。如果 DIR 連接到 GND (DIR = 0),則從頂部順時(shí)針旋轉(zhuǎn)將產(chǎn)生計(jì)算角度的增量。如果 DIR 引腳連接到 VDD (DIR = 1),則計(jì)算的角度將逆時(shí)針旋轉(zhuǎn)。

三、功能框圖和數(shù)據(jù)的讀寫(xiě)

寫(xiě)數(shù)據(jù)

讀數(shù)據(jù)

指定地址讀數(shù)據(jù)

四、寄存器說(shuō)明

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

RAW ANGLE(0x0C / 0x0D):未縮放/未處理的原始角度數(shù)據(jù),12-bit。

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

RAW和ANGLE寄存器的區(qū)別:RAW 是芯片內(nèi)部直接計(jì)算得到的無(wú)縮放角度;ANGLE 是按 ZPOS/MPOS/MANG(如有編程)以及濾波/死區(qū)后的輸出值。

STATUS(0x0B):狀態(tài)寄存器,包含磁鐵檢測(cè)位(Magnet Detected,MD)、Magnet Low/High(ML/MH)等位,判斷是否檢測(cè)到合適的磁場(chǎng)(MD=1 表示檢測(cè)到磁鐵)。

AGC(0x1A):自動(dòng)增益控制,表示放大倍數(shù),5V 下范圍 0..255,3.3V 下 0..128。可用來(lái)補(bǔ)償因溫度變化、IC 與磁體之間的氣隙以及磁體性能下降而導(dǎo)致的磁場(chǎng)強(qiáng)度變化。為了獲得最穩(wěn)健的性能,增益值應(yīng)位于其范圍的中間。
??典型的徑向磁鐵感應(yīng)氣隙在 0.5 mm 到 3 mm 之間,這取決于所選的磁體。更大、更強(qiáng)的磁鐵允許更大的氣隙。以 AGC 值為指導(dǎo),通過(guò)調(diào)整磁體和 AS5600 之間的距離,使 AGC 值位于其范圍的中心,可以找到最佳氣隙。當(dāng)使用直徑為 0.25mm 的磁體時(shí),參考磁體的旋轉(zhuǎn)軸從封裝中心的最大允許位移為 6 mm。

MAGNITUDE(0x1B / 0x1C):用于判斷磁場(chǎng)強(qiáng)弱與是否飽和/過(guò)弱。

BURN(0xFF):寫(xiě) 0x40 到 0xFF 可做永久寫(xiě)入/OTP,慎重,寫(xiě)入次數(shù)有限。
??Burn_Angle 命令 (ZPOS, MPOS):主機(jī)微控制器可以使用 BURN_ANGLE 命令對(duì) ZPOS 和 MPOS 進(jìn)行永久編程。要執(zhí)行 BURN_ANGLE 命令,請(qǐng)將值 0x80 寫(xiě)入寄存器 0xFF。BURN_ANGLE 命令最多可執(zhí)行 3 次。ZMCO 顯示 ZPOS 和 MPOS 已永久寫(xiě)入的次數(shù)。此命令僅在檢測(cè)到磁鐵存在 (MD = 1) 時(shí)執(zhí)行。
??Burn_Setting 命令 (MANG, CONFIG):主微控制器可以使用 BURN_SETTING 命令永久寫(xiě)入 MANG 和 CONFIG。要執(zhí)行 BURN_SETTING 命令,請(qǐng)將值 0x40 寫(xiě)入寄存器 0xFF。只有在 ZPOS 和 MPOS 從未被永久寫(xiě)入 (ZMCO = 00) 的情況下,才能寫(xiě)入 MANG。BURN_SETTING 命令只能執(zhí)行一次。

五、數(shù)據(jù)的換算公式

??角度(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驅(qū)動(dòng)AS5600獲取數(shù)據(jù)

準(zhǔn)備工作

??STM32F103C8T6開(kāi)發(fā)板,OLED顯示屏,AS5600磁編碼器模塊,磁鐵等。

接線說(shuō)明

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

代碼示例

AS5600.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)  //獲取原始數(shù)值
{
    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數(shù)值
{
    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

#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();  //角度原始數(shù)值
        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);
    }
}

效果展示

將磁鐵固定在電機(jī)上,讓電機(jī)轉(zhuǎn)動(dòng)。

注意事項(xiàng)

  1. AGC 與磁鐵擺放:把磁鐵放到合適的間隙(典型 0.5–3 mm),并用 AGC 值把距離調(diào)到居中(3.3V 下 AGC 0..128,目標(biāo)約中間值)。如果 AGC 很小或很大,說(shuō)明磁場(chǎng)太弱或太強(qiáng)。
  2. 程序?qū)?OTP(Burn)非常謹(jǐn)慎:write 0x40 to 0xFF 會(huì)永久寫(xiě)入,次數(shù)有限。務(wù)必在確認(rèn)無(wú)誤后再做。
  3. 濾波設(shè)定:默認(rèn)有 slow/fast filter,能在精度與響應(yīng)間做折中;如果需要高速動(dòng)態(tài)測(cè)量請(qǐng)降低慢濾波系數(shù)/調(diào)整 FTH。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容