打印
[其他ST产品]

STM32驱动AS5600磁性旋转位置传感器模块

[复制链接]
140|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
简介
AS5600 是一款易于编程的磁性旋转位置传感器,具有高分辨率 12 位模拟或 PWM 输出。 这种非接触式系统测量径向磁化轴上磁铁的绝对角度。 该 AS5600 专为非接触式电位计应用而设计,其坚固的设计消除了任何同质外部杂散磁场的影响。

引脚定义

I2C接口
  • 7位设备地址为0x36(二进制表示为0110110)
  • 支持标准模式和快速模式和高速模式



使用特权

评论回复
沙发
梅花香自123|  楼主 | 2024-3-30 16:07 | 只看该作者
写数据

使用特权

评论回复
板凳
梅花香自123|  楼主 | 2024-3-30 16:08 | 只看该作者
读数据

使用特权

评论回复
地板
梅花香自123|  楼主 | 2024-3-30 16:08 | 只看该作者
从指定的地址开始读数据

使用特权

评论回复
5
梅花香自123|  楼主 | 2024-3-30 16:08 | 只看该作者
驱动程序
注意: 这里首先搞清楚一件事情,AS5600数据手册中给的7位地址(0x36)指的是原始的7位设备地址,而STM32库中指的设备地址为原始7位设备地址左移一位后得到的设备地址.

使用特权

评论回复
6
梅花香自123|  楼主 | 2024-3-30 16:08 | 只看该作者
cubeMX配置
标准的I2C代码由cubeMX配置生成:

使用特权

评论回复
7
梅花香自123|  楼主 | 2024-3-30 16:08 | 只看该作者
驱动程序
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 */


使用特权

评论回复
8
梅花香自123|  楼主 | 2024-3-30 16:09 | 只看该作者
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);
}

使用特权

评论回复
9
梅花香自123|  楼主 | 2024-3-30 16:09 | 只看该作者
测试程序

/**
  * @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 */
}

使用特权

评论回复
10
梅花香自123|  楼主 | 2024-3-30 16:09 | 只看该作者
参考资料
Arduino FOC 库中AS5600的驱动代码
AS5600 数据手册

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

80

主题

1035

帖子

0

粉丝