简介
AS5600 是一款易于编程的磁性旋转位置传感器,具有高分辨率 12 位模拟或 PWM 输出。 这种非接触式系统测量径向磁化轴上磁铁的绝对角度。 该 AS5600 专为非接触式电位计应用而设计,其坚固的设计消除了任何同质外部杂散磁场的影响。
引脚定义
I2C接口
- 7位设备地址为0x36(二进制表示为0110110)
- 支持标准模式和快速模式和高速模式
写数据
读数据
从指定的地址开始读数据
驱动程序
注意: 这里首先搞清楚一件事情,AS5600数据手册中给的7位地址(0x36)指的是原始的7位设备地址,而STM32库中指的设备地址为原始7位设备地址左移一位后得到的设备地址.
cubeMX配置
标准的I2C代码由cubeMX配置生成:
驱动程序
bsp_as5600.h
#ifndef __BSP_AS5600_H
#define __BSP_AS5600_H
#include "i2c.h"
#define AS5600_I2C_HANDLE hi2c1
#define I2C_TIME_OUT_BASE 10
#define I2C_TIME_OUT_BYTE 1
#define AS5600_RAW_ADDR 0x36
#define AS5600_ADDR (AS5600_RAW_ADDR << 1)
#define AS5600_WRITE_ADDR (AS5600_RAW_ADDR << 1)
#define AS5600_READ_ADDR ((AS5600_RAW_ADDR << 1) | 1)
#define AS5600_RESOLUTION 4096
#define AS5600_RAW_ANGLE_REGISTER 0x0C
void bsp_as5600Init(void);
uint16_t bsp_as5600GetRawAngle(void);
float bsp_as5600GetAngle(void);
#endif
bsp_as5600.c
#include "bsp_as5600.h"
#define abs(x) ((x)>0?(x):-(x))
#define _2PI 6.28318530718
static float angle_data_prev;
static float full_rotation_offset;
void bsp_as5600Init(void) {
full_rotation_offset = 0;
angle_data_prev = bsp_as5600GetRawAngle();
}
static int i2cWrite(uint8_t dev_addr, uint8_t *pData, uint32_t count) {
int status;
int i2c_time_out = I2C_TIME_OUT_BASE + count * I2C_TIME_OUT_BYTE;
status = HAL_I2C_Master_Transmit(&AS5600_I2C_HANDLE, dev_addr, pData, count, i2c_time_out);
return status;
}
static int i2cRead(uint8_t dev_addr, uint8_t *pData, uint32_t count) {
int status;
int i2c_time_out = I2C_TIME_OUT_BASE + count * I2C_TIME_OUT_BYTE;
status = HAL_I2C_Master_Receive(&AS5600_I2C_HANDLE, (dev_addr | 1), pData, count, i2c_time_out);
return status;
}
uint16_t bsp_as5600GetRawAngle(void) {
uint16_t raw_angle;
uint8_t buffer[2] = {0};
uint8_t raw_angle_register = AS5600_RAW_ANGLE_REGISTER;
i2cWrite(AS5600_ADDR, &raw_angle_register, 1);
i2cRead(AS5600_ADDR, buffer, 2);
raw_angle = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1];
return raw_angle;
}
float bsp_as5600GetAngle(void) {
float angle_data = bsp_as5600GetRawAngle();
float d_angle = angle_data - angle_data_prev;
if(abs(d_angle) > (0.8 * AS5600_RESOLUTION)) {
full_rotation_offset += (d_angle > 0 ? -_2PI : _2PI);
}
angle_data_prev = angle_data;
return (full_rotation_offset + (angle_data / (float)AS5600_RESOLUTION)*_2PI);
}
测试程序
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
bsp_as5600Init();
while (1)
{
angle_raw = bsp_as5600GetRawAngle();
angle = bsp_as5600GetAngle();
HAL_Delay(100);
}
}
参考资料
- Arduino FOC 库中AS5600的驱动代码
- AS5600 数据手册
|