STM32G4-DRV8301-FOC/FOC_Related/AS5600/AS5600.c
2024-07-27 22:33:57 +08:00

124 lines
3.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "AS5600.h"
#include "math.h"
#include "LowPass_Filter.h"
#include "foc.h"
extern int DIR; // 无刷电机纠偏旋转方向
float full_rotations; // 当前旋转圈数
float angle_prev; // 上次角度(用于位置环)
float vel_angle_prev; // 上次角度(用于速度环)
float angle_prev_Velocity; // 上次角度(用于速度环)
float vel_angle_prev_Velocity; // 上次角度(用于速度环)
unsigned long angle_prev_ts; // 上次的运行时间
unsigned long vel_angle_prev_ts; // 上次的运行时间
float raw_angle; // 传感器原始值
float angle; // 传感器角度缩减值
// 读取0x0c地址原始数据
HAL_StatusTypeDef AS5600_ReadRawAngle(I2C_HandleTypeDef *hi2c1, float *raw_angle)
{
uint8_t data[2]; // 用于存储读取的数据
HAL_StatusTypeDef ret; // 存储函数返回状态
// 从AS5600传感器的0x0c地址读取2字节数据
ret = HAL_I2C_Mem_Read(hi2c1, AS5600_I2C_ADDR << 1, AS5600_REG_RAW_ANGLE, I2C_MEMADD_SIZE_8BIT, data, 2, HAL_MAX_DELAY);
if (ret != HAL_OK)
{
return ret; // 如果读取失败,则返回错误状态
}
*raw_angle = (data[0] << 8) | data[1]; // 将读取的数据合成为一个16位数
return HAL_OK; // 返回成功状态
}
// 读取角度数据
HAL_StatusTypeDef AS5600_ReadAngle(I2C_HandleTypeDef *hi2c1, float *angle)
{
uint8_t data[2]; // 用于存储读取的数据
HAL_StatusTypeDef ret; // 存储函数返回状态
// 从AS5600传感器的0x0e地址读取2字节数据
ret = HAL_I2C_Mem_Read(hi2c1, AS5600_I2C_ADDR << 1, AS5600_REG_ANGLE, I2C_MEMADD_SIZE_8BIT, data, 2, HAL_MAX_DELAY);
if (ret != HAL_OK)
{
return ret; // 如果读取失败,则返回错误状态
}
*angle = (data[0] << 8) | data[1]; // 将读取的数据合成为一个16位数
return HAL_OK; // 返回成功状态
}
// 把原始值解算成编码器360°值
float AS5600_GetAngle360(void)
{
return raw_angle * 0.08789f; // 将原始值转换为0-360°的角度
}
float Debug_raw_angle;
// 读取磁编码器归一化弧度值:(0-6.28)
float AS5600_GetAngle2PI(void)
{
Debug_raw_angle = raw_angle * 0.08789f / 57.32484f;
return raw_angle * 0.08789f / 57.32484f; // 将原始值转换为0-2π的弧度
}
float val,d_angle;
// 磁编码器弧度制角度累计计算:(0-∞)
float AS5600_GetAngle(void)
{
val = AS5600_GetAngle2PI(); // 获取当前角度
d_angle = val - angle_prev; // 计算角度变化
// 计算旋转的圈数
// 通过判断角度变化是否大于80%的一圈(0.8f*6.28318530718f)来判断是否发生了溢出
// 如果发生了溢出,则将full_rotations增加1(如果d_angle小于0)或减少1(如果d_angle大于0)
if (fabs(d_angle) > (0.8f * 6.28318530718f))
full_rotations += (d_angle > 0) ? -1 : 1; // 根据角度变化方向调整旋转圈数
angle_prev = val; // 更新上次角度
return (float)full_rotations * 6.28318530718f + angle_prev; // 返回累计角度
}
float Ts, vel = 0.0f; // Ts为采样时间vel为速度
// 磁编码器速度计算:(0-∞)
float AS5600_GetVelocity(void)
{
//float Ts, vel = 0.0f; // Ts为采样时间vel为速度
// 计算采样时间
angle_prev_ts = SysTick->VAL; // 获取当前时间戳
if (angle_prev_ts < vel_angle_prev_ts)
Ts = (float)(vel_angle_prev_ts - angle_prev_ts); // 计算时间差
else
Ts = (float)(0xFFFFFF - angle_prev_ts + vel_angle_prev_ts); // 处理时间戳溢出情况
// 快速修复微小溢出
if (Ts == 0 || Ts > 0.5f)
Ts = 1e-3f; // 防止采样时间为0或过大
angle_prev_Velocity = AS5600_GetAngle(); // 获取当前角度
vel = (angle_prev_Velocity - vel_angle_prev_Velocity) / Ts; // 计算速度
vel_angle_prev_Velocity = angle_prev_Velocity; // 更新上次角度
vel_angle_prev_ts = angle_prev_ts; // 更新上次时间戳
return vel; // 返回速度
}
float vel_M0_flit;
// 磁编码器速度低通滤波计算:(0-∞)
float AS5600_Get_Speed(void)
{
float vel_M0_ori = AS5600_GetVelocity(); // 速度原始数据采集
vel_M0_flit = LowPass_Filter(DIR * vel_M0_ori); // 原始数据低通滤波
return vel_M0_flit; // 返回滤波后的速度
}