文章目录
-
- 简介
- 引脚定义
- I2C接口
-
- 写数据
- 读数据
- 读取指定地址的数据
- 驱动程序
-
- cubeMX配置
- 驱动程序
-
- `bsp_as5600.h`
- `bsp_as5600.c`
- 测试程序
- 参考资料
简介
AS5600 编程方便位置传感器,具有。 径向磁化轴上上测量磁铁的绝对角度。 该 AS5600 专为非接触式电位计的应用而设计,其坚固的设计消除了任何同质外杂散磁场的影响。
引脚定义
I2C接口
- 7位设备地址为(二进制表示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 数据手册