STM32G4-DRV8301-FOC/FOC_Related/ABZ/ABZ.c

236 lines
7.8 KiB
C
Raw Normal View History

2024-07-22 13:55:29 +08:00
#include "tim.h"
#include "ABZ.h"
#include "foc.h"
2024-07-26 14:51:23 +08:00
#include "math.h"
2024-07-27 22:33:57 +08:00
#include "LowPass_Filter.h"
#define RAD_TO_DEG (57.2957795131f) // 弧度转角度常量
#define FULL_ROTATION_RAD (6.28318530718f) // 2π
extern int DIR; // 无刷电机纠偏旋转方向
2024-07-22 13:55:29 +08:00
2024-07-26 14:51:23 +08:00
//此驱动按照AS5600驱动中的函数编写
2024-07-22 13:55:29 +08:00
2024-07-26 14:51:23 +08:00
// ABZ 正交编码器的每转脉冲数
#define ENCODER_PULSES_PER_REV 4096
// 定时器周期 (秒)
#define TIMER_PERIOD 1.0f
int realCnt = 0; // 真实编码器计数值
ABZ_Encoder encoderDef; //encoderDef结构体声明
2024-07-22 13:55:29 +08:00
// 变量声明
volatile int32_t ABZ_pulse_count = 0;
volatile int32_t ABZ_prev_pulse_count = 0;
volatile float ABZ_speed = 0.0f;
volatile float ABZ_angle = 0.0f;
2024-07-26 14:51:23 +08:00
/////////////////////////////////////////////////////////////////////
//此处适用的定时器时间戳计算速度
float ABZ_full_rotations; // 当前旋转圈数
unsigned long ABZ_angle_prev_ts; // 上次的运行时间
unsigned long ABZ_vel_angle_prev_ts; // 上次的运行时间
float ABZ_angle_prev_Velocity; // 上次角度(用于速度环)
float ABZ_vel_angle_prev_Velocity; // 上次角度(用于速度环)
2024-07-27 22:33:57 +08:00
float ABZ_encoder_count = 0; // 读取当前编码器计数值
float ABZ_prev_encoder_count = 0; // 读取上次编码器计数值
2024-07-22 13:55:29 +08:00
void TIM2_M1_ABZ(void)
{
// 启动编码器模式
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
2024-07-26 14:51:23 +08:00
// 启动索引中断,检测到ABZ编码器Z信号就重置计数器。
2024-07-22 13:55:29 +08:00
HAL_TIMEx_EnableEncoderIndex(&htim2);
}
void TIM3_M2_ABZ(void)
{
// 启动编码器模式
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
2024-07-26 14:51:23 +08:00
// 启动索引中断,检测到ABZ编码器Z信号就重置计数器。
2024-07-22 13:55:29 +08:00
HAL_TIMEx_EnableEncoderIndex(&htim3);
}
2024-07-26 14:51:23 +08:00
/**
* @brief
*
*/
2024-07-22 13:55:29 +08:00
void Count_M1_ABZ(void)
{
// Debug读取编码器计数值
volatile int32_t encoder_count = __HAL_TIM_GET_COUNTER(&htim2);
}
void Count_M2_ABZ(void)
{
// Debug读取编码器计数值
volatile int32_t encoder_count = __HAL_TIM_GET_COUNTER(&htim3);
}
2024-07-26 14:51:23 +08:00
// // 电机速度和角度计算
// void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
// {
// if (htim->Instance == TIM3)
// {
2024-07-26 14:51:23 +08:00
// // 获取当前脉冲计数
// ABZ_pulse_count = __HAL_TIM_GET_COUNTER(&htim3);
// // 计算脉冲增量
// int32_t pulse_delta = ABZ_pulse_count - ABZ_prev_pulse_count;
// // 计算速度 (PPS: 脉冲每秒)
// // 假设定时器周期为1秒则速度为脉冲增量
// ABZ_speed = (float)pulse_delta / TIMER_PERIOD;
// // 计算角度 (单位:度)
// // 角度 = 当前计数值 / 每转脉冲数 * 360度
// ABZ_angle = (float)((ABZ_pulse_count % ENCODER_PULSES_PER_REV + ENCODER_PULSES_PER_REV) % ENCODER_PULSES_PER_REV) / ENCODER_PULSES_PER_REV * 360.0f;
// // 更新上次脉冲计数
// ABZ_prev_pulse_count = ABZ_pulse_count;
// // 清除定时器更新中断标志
// __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE);
// }
// }
//定时器中断方法计算速度
// int UpdateEncoderCnt(void)
// {
// // 启动编码器模式
// HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
// // 启动索引中断
// HAL_TIMEx_EnableEncoderIndex(&htim3);
// // 获取电机读数
// encoderDef.cnt = (int32_t)__HAL_TIM_GET_COUNTER(&htim3);
// // 计算电机偏移量
// encoderDef.incCnt = ModifyIncCnt(encoderDef.cnt - encoderDef.preCnt);
// // 更新上次脉冲计数
// encoderDef.preCnt = encoderDef.cnt;
// // 获取真实的编码器计数值
// realCnt = encoderDef.cnt - encoderDef.offsetCnt;
// // 当计数值为负数时,加上一圈的计数数
// while (realCnt < 0)
// {
// realCnt += ENCODER_PULSES_PER_REV * 4;
// }
2024-07-26 14:51:23 +08:00
// // 计算真实的角度值
// encoderDef.angle = realCnt * 2 * PI / ENCODER_PULSES_PER_REV / 4;
// // 计算电角度
// encoderDef.elecAngle = _normalizeAngle(encoderDef.angle);
// // 返回编码器读数
// return encoderDef.cnt;
// }
2024-07-22 13:55:29 +08:00
2024-07-26 14:51:23 +08:00
// int16_t ModifyIncCnt(int16_t delta)
// {
// // 如果增量超过了一半计数范围,说明是溢出,需要进行调整
// if (delta > ENCODER_HALF_COUNT)
// {
// delta -= (ENCODER_MAX_COUNT + 1);
// }
// else if (delta < -ENCODER_HALF_COUNT)
// {
// delta += (ENCODER_MAX_COUNT + 1);
// }
// return delta;
// }
///////////////////////////////////////////////////////////////////////////////
// 把原始值解算成编码器360°值
2024-07-27 22:33:57 +08:00
//float ABZ_GetAngle360(void)
//{
// ABZ_encoder_count = __HAL_TIM_GET_COUNTER(&htim3);
// float ABZ_raw_angle = ABZ_encoder_count;
// return ABZ_raw_angle * 0.08789f; // 将原始值转换为0-360°的角度,4096*0.08789≈360°
//}
float debug_ABZ_encoder_count;//debug 参数
2024-07-26 14:51:23 +08:00
// 读取磁编码器归一化弧度值:(0-6.28)
float ABZ_GetAngle2PI(void)
{
2024-07-27 22:33:57 +08:00
//读取脉冲数
2024-07-26 14:51:23 +08:00
ABZ_encoder_count = __HAL_TIM_GET_COUNTER(&htim3);
2024-07-27 22:33:57 +08:00
//debug 参数
debug_ABZ_encoder_count = ABZ_encoder_count * 0.08789f / 57.32484f;
return ABZ_encoder_count * 0.08789f / 57.32484f; // 将原始值转换为0-2π的弧度
2024-07-22 13:55:29 +08:00
}
2024-07-27 22:33:57 +08:00
float ABZ_val; //Debug当前角度
float ABZ_current_angle;//当前角度变化值
float ABZ_full_rotations_Debug;//累计旋转角度
2024-07-26 14:51:23 +08:00
// 磁编码器弧度制角度累计计算:(0-∞)
float ABZ_GetAngle(void)
{
2024-07-27 22:33:57 +08:00
ABZ_val = ABZ_GetAngle2PI(); // 获取当前弧度
ABZ_current_angle = ABZ_val - ABZ_prev_encoder_count; // 计算角度变化
2024-07-26 14:51:23 +08:00
// 计算旋转的圈数
// 通过判断角度变化是否大于80%的一圈(0.8f*6.28318530718f)来判断是否发生了溢出
// 如果发生了溢出,则将full_rotations增加1(如果d_angle小于0)或减少1(如果d_angle大于0)
2024-07-27 22:33:57 +08:00
if (fabs(ABZ_current_angle) > (0.8f * 6.28318530718f))
ABZ_full_rotations += (ABZ_current_angle > 0) ? -1 : 1; // 根据角度变化方向调整旋转圈数
2024-07-22 13:55:29 +08:00
2024-07-27 22:33:57 +08:00
ABZ_prev_encoder_count = ABZ_val; // 更新上次角度
ABZ_full_rotations_Debug=ABZ_full_rotations * 6.28318530718f + ABZ_prev_encoder_count;
2024-07-26 14:51:23 +08:00
return (float)ABZ_full_rotations * 6.28318530718f + ABZ_prev_encoder_count; // 返回累计角度
}
2024-07-27 22:33:57 +08:00
float ABZ_Ts, ABZvel = 0.0f; // Ts为采样时间vel为速度
2024-07-26 14:51:23 +08:00
// 磁编码器速度计算:(0-∞)
float ABZ_GetVelocity(void)
2024-07-22 13:55:29 +08:00
{
2024-07-27 22:33:57 +08:00
//float Ts, vel = 0.0f; // Ts为采样时间vel为速度
2024-07-26 14:51:23 +08:00
// 计算采样时间
ABZ_angle_prev_ts = SysTick->VAL; // 获取当前时间戳
if (ABZ_angle_prev_ts < ABZ_vel_angle_prev_ts)
2024-07-27 22:33:57 +08:00
ABZ_Ts = (float)(ABZ_vel_angle_prev_ts - ABZ_angle_prev_ts); // 计算时间差
2024-07-26 14:51:23 +08:00
else
2024-07-27 22:33:57 +08:00
ABZ_Ts = (float)(0xFFFFFF - ABZ_angle_prev_ts + ABZ_vel_angle_prev_ts); // 处理时间戳溢出情况
2024-07-26 14:51:23 +08:00
// 快速修复微小溢出
2024-07-27 22:33:57 +08:00
if (ABZ_Ts == 0 || ABZ_Ts > 0.5f)
ABZ_Ts = 1e-3f; // 防止采样时间为0或过大
2024-07-26 14:51:23 +08:00
ABZ_angle_prev_Velocity = ABZ_GetAngle(); // 获取当前角度
2024-07-27 22:33:57 +08:00
ABZvel = (ABZ_angle_prev_Velocity - ABZ_vel_angle_prev_Velocity) / ABZ_Ts; // 计算速度
2024-07-26 14:51:23 +08:00
ABZ_vel_angle_prev_Velocity = ABZ_angle_prev_Velocity; // 更新上次角度
ABZ_vel_angle_prev_ts = ABZ_angle_prev_ts; // 更新上次时间戳
2024-07-27 22:33:57 +08:00
return ABZvel; // 返回速度
}
float ABZ_vel_M0_flit;
// 磁编码器速度低通滤波计算:(0-∞)
float ABZ_Get_Speed(void)
{
float vel_M0_ori = ABZ_GetVelocity(); // 速度原始数据采集
ABZ_vel_M0_flit = LowPass_Filter(DIR * vel_M0_ori); // 原始数据低通滤波
return ABZ_vel_M0_flit; // 返回滤波后的速度
2024-07-22 13:55:29 +08:00
}