3. 零位校准与偏移设置

任务目标

实现AS5048磁编码器的零位校准:当电机转子处于机械零位时,通过写入零位寄存器(ZERO,地址0x16),使编码器输出的角度数据在该位置读数为0。校准完成后,断电重启仍保持该偏移设置(零位寄存器为OTP非易失存储)。

硬件与依赖

  • AS5048编码器模块(SPI接口,CS、SCK、MOSI、MISO连接MCU)
  • MCU:任意支持SPI的型号(示例使用STM32 HAL库)
  • 接线:CS→PB12,SCK→PB13,MISO→PB14,MOSI→PB15

工作原理

AS5048内部角度寄存器(0xFE/0xFF)输出14位原始角度(0~16383)。零位寄存器(0x16)存储一个偏移值,芯片内部自动将原始角度减去该偏移后输出。写入零位寄存器的值应等于当前机械零位处的原始角度读数。写入后需发送0x80命令触发烧录,将偏移永久保存至OTP。

关键完整代码

// as5048_zero_calib.c
#include <stdint.h>
#include "stm32f1xx_hal.h"

extern SPI_HandleTypeDef hspi1;
#define CS_LOW()  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define CS_HIGH() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)

// SPI读写16位(AS5048命令格式:bit15=0读/1写,bit14~0为地址或数据)
uint16_t AS5048_SPI_Transfer(uint16_t txData) {
    uint16_t rxData = 0;
    CS_LOW();
    HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)&txData, (uint8_t*)&rxData, 2, 10);
    CS_HIGH();
    return rxData;
}

// 读取14位原始角度(地址0xFE)
uint16_t AS5048_ReadRawAngle(void) {
    uint16_t cmd = 0x3FFF & 0xFE;  // 读命令:bit15=0,地址0xFE
    AS5048_SPI_Transfer(cmd);      // 发送命令,丢弃返回
    uint16_t resp = AS5048_SPI_Transfer(0x0000); // 读取数据
    return resp & 0x3FFF;          // 低14位有效
}

// 写入零位寄存器(地址0x16),并触发OTP烧录
void AS5048_WriteZero(uint16_t zeroValue) {
    uint16_t writeCmd = 0x8000 | (0x16 << 1) | ((zeroValue >> 8) & 0x01);
    uint16_t writeData = (zeroValue & 0xFF) << 8;
    AS5048_SPI_Transfer(writeCmd);
    AS5048_SPI_Transfer(writeData);

    // 触发烧录命令(0x80写入地址0x00)
    AS5048_SPI_Transfer(0x8000 | (0x00 << 1) | 0x01); // 写0x80到地址0x00
    AS5048_SPI_Transfer(0x0000);
    HAL_Delay(10); // 等待烧录完成
}

// 校准流程:将当前角度设为机械零位
void AS5048_CalibrateZero(void) {
    uint16_t raw = AS5048_ReadRawAngle();
    AS5048_WriteZero(raw);
}

// 验证:读取校准后的角度(应接近0)
uint16_t AS5048_ReadAngle(void) {
    uint16_t cmd = 0x3FFF & 0xFE;
    AS5048_SPI_Transfer(cmd);
    uint16_t resp = AS5048_SPI_Transfer(0x0000);
    return resp & 0x3FFF;
}

运行与验证

  1. 将电机转子手动旋转至机械零位(可用治具或目测对齐)。
  2. 调用AS5048_CalibrateZero()执行校准。
  3. 调用AS5048_ReadAngle()读取角度,预期输出为0(允许±1 LSB误差)。
  4. 断电重启后再次读取,角度仍应为0,证明OTP烧录生效。

通过条件:校准后角度读数稳定在0附近(±1 LSB),且断电重启后偏移不丢失。

注意事项

  • OTP烧录次数有限(约100次),调试阶段建议先只写RAM(不触发烧录命令),确认无误后再执行完整烧录。
  • SPI通信时序需满足AS5048数据手册要求:CS低电平期间完成16位命令+16位数据读取,两次传输间CS需拉高至少100ns。
  • 若读取角度始终跳变较大,检查SPI时钟极性(CPOL=1, CPHA=1)及接线屏蔽。