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;
}
运行与验证
- 将电机转子手动旋转至机械零位(可用治具或目测对齐)。
- 调用
AS5048_CalibrateZero()执行校准。 - 调用
AS5048_ReadAngle()读取角度,预期输出为0(允许±1 LSB误差)。 - 断电重启后再次读取,角度仍应为0,证明OTP烧录生效。
通过条件:校准后角度读数稳定在0附近(±1 LSB),且断电重启后偏移不丢失。
注意事项
- OTP烧录次数有限(约100次),调试阶段建议先只写RAM(不触发烧录命令),确认无误后再执行完整烧录。
- SPI通信时序需满足AS5048数据手册要求:CS低电平期间完成16位命令+16位数据读取,两次传输间CS需拉高至少100ns。
- 若读取角度始终跳变较大,检查SPI时钟极性(CPOL=1, CPHA=1)及接线屏蔽。