文章目录[隐藏]
简介
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
/*
注意:AS5600的地址0x36是指的是原始7位设备地址,而ST I2C库中的设备地址是指原始设备地址左移一位得到的设备地址
*/
#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 //12bit Resolution
#define AS5600_RAW_ANGLE_REGISTER 0x0C
void bsp_as5600Init(void);
uint16_t bsp_as5600GetRawAngle(void);
float bsp_as5600GetAngle(void);
#endif /* __BSP_AS5600_H */
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) {
/* init i2c interface */
/* init var */
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);
}
测试程序
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
bsp_as5600Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// uint8_t buffer[2] = {0};
// uint8_t addr = 0x0c;
// HAL_I2C_Master_Transmit(&hi2c1, (0x36 << 1), &addr, 1, 10);
// HAL_I2C_Master_Receive(&hi2c1, (0x36 << 1)|1, buffer, 2, 10);
// angle_raw = buffer[0] << 8 | buffer[1];
angle_raw = bsp_as5600GetRawAngle();
angle = bsp_as5600GetAngle();
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
参考资料
- Arduino FOC 库中AS5600的驱动代码
- AS5600 数据手册
版权声明:本文为CSDN博主「顶点元」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaoyuanwuhui/article/details/118970127
暂无评论