feat(FOC): 添加齿槽转矩补偿功能

- 实现齿槽转矩补偿算法,通过查表+线性插值方式计算补偿电压值
- 添加齿槽转矩校准功能,支持正转3次+反转3次的非阻塞校准状态机
- 在所有控制模式中集成齿槽转矩补偿,包括开环、角度、速度、电流和MIT模式
- 硬编码预校准的正反转补偿表数据
- 通过CAN命令支持运行时触发校准功能
- 添加相关配置参数和调试开关
This commit is contained in:
cbb
2026-05-19 01:26:42 +08:00
parent 9955132e0e
commit bec7c11b87
7 changed files with 322 additions and 109 deletions
+265 -66
View File
@@ -7,8 +7,11 @@
#include "config.h"
#include "motor.h"
#include "pid.h"
#include "systick.h"
#include <arm_math.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <gd32c10x.h>
FOC_Controller FOC; // FOC控制初始化
@@ -19,6 +22,207 @@ extern EncoderVelocityKalman Vel_kalman; // 速度滤波
extern CurrentKalman Current_kalman;
extern u16 adc_value[3]; // regular DMA缓冲区:MCU温度 / DRV温度 / VBUS
// 齿槽转矩补偿:查表 + 线性插值
// angle_el: 电角度(度)
// 返回: 补偿电压值 (V),叠加到 Uq 上
inline float FOC_Controller::get_cogging_compensation(float angle_el) {
if (!cogging_comp_enabled) return 0.0f;
// 归一化到 [0, 360)
float angle = fmodf(angle_el, 360.0f);
if (angle < 0.0f) angle += 360.0f;
// 线性插值查表
float index_f = angle / 360.0f * (float)COGGING_TABLE_SIZE;
u16 idx0 = (u16)index_f;
u16 idx1 = (idx0 + 1) % COGGING_TABLE_SIZE;
float frac = index_f - (float)idx0;
// 根据转向选择补偿表(带滞回,避免零速附近跳变)
static float *last_table = cogging_table;
if (rt_velocity < -0.5f) last_table = cogging_table_rev;
else if (rt_velocity > 0.5f) last_table = cogging_table;
float *table = last_table;
float comp = table[idx0] * (1.0f - frac) + table[idx1] * frac;
return -comp * cogging_comp_scale; // mA→V: 补偿电流(mA) × 换算系数(V/mA)
}
// === 齿槽转矩校准(DEBUG,平时不启用)===
// 启用方法:config.h 中 FOC_DEBUG 改为 1,通过 CAN 命令触发(RESET_ID bit4)
// 校准完成后把 C Array 硬编码到 init() 中,再改回 FOC_DEBUG 0
#if FOC_DEBUG
// 齿槽转矩校准静态数据
float FOC_Controller::cog_calib_run_data[6][COGGING_TABLE_SIZE] = {};
float FOC_Controller::cog_calib_accum[COGGING_TABLE_SIZE] = {};
u32 FOC_Controller::cog_calib_count[COGGING_TABLE_SIZE] = {};
/**
* @brief 齿槽转矩校准 - 非阻塞状态机
* 正转3次 + 反转3次,分开存储补偿表。
* 只打印最终平均数据和 C Array。
*/
void FOC_Controller::calibrate_cogging_tick(void) {
constexpr u32 SETTLE_TICKS = 16000; // 800ms / 50us
constexpr u32 STOP_TICKS = 10000; // 500ms / 50us
constexpr u32 TARGET_SAMPLES = 3 * COGGING_TABLE_SIZE * 8;
constexpr float SLOW_VEL = 1.0f; // 开环速度 rad/s
constexpr u32 SAMPLE_DIV = 20; // 1ms / 50us
constexpr u8 TOTAL_RUNS = 6; // 3正+3反
switch (cog_calib_state) {
case CogCalibState::IDLE:
if (!cogging_calib_request) return;
cogging_calib_request = false;
cog_calib_run = 0;
cog_calib_saved_mode = control_mode;
cog_calib_saved_vel = target_velocity;
cogging_comp_enabled = false;
memset(cog_calib_run_data, 0, sizeof(cog_calib_run_data));
printf("\r\n[COG] === Cogging Calibration: 3 fwd + 3 rev ===\r\n");
control_mode = 6;
target_velocity = SLOW_VEL;
cog_calib_settle_tick = 0;
cog_calib_state = CogCalibState::SETTLING;
return;
case CogCalibState::SETTLING:
cog_calib_settle_tick++;
if (cog_calib_settle_tick >= SETTLE_TICKS) {
cog_calib_state = CogCalibState::SAMPLING;
cog_calib_sample_count = 0;
memset(cog_calib_accum, 0, sizeof(cog_calib_accum));
memset(cog_calib_count, 0, sizeof(cog_calib_count));
}
return;
case CogCalibState::SAMPLING:
// 采样分频
static u32 sample_div = 0;
sample_div++;
if (sample_div < SAMPLE_DIV) return;
sample_div = 0;
{
float real_angle = KTH7823.getcurrent_sensorangle();
float angle_el = fmodf(real_angle * PP + KTH7823.calibration_angle, 360.0f);
if (angle_el < 0.0f) angle_el += 360.0f;
float iq = rt_current;
if (fabsf(iq) < 5000.0f) {
u16 idx = (u16)(angle_el / 360.0f * (float)COGGING_TABLE_SIZE);
if (idx >= COGGING_TABLE_SIZE) idx = COGGING_TABLE_SIZE - 1;
cog_calib_accum[idx] += iq;
cog_calib_count[idx]++;
}
cog_calib_sample_count++;
}
if (cog_calib_sample_count >= TARGET_SAMPLES) {
target_velocity = 0;
cog_calib_state = CogCalibState::STOPPING;
cog_calib_stop_tick = 0;
}
return;
case CogCalibState::STOPPING:
cog_calib_stop_tick++;
if (cog_calib_stop_tick >= STOP_TICKS) {
// 处理本轮数据:去直流
float dc = 0;
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
cog_calib_run_data[cog_calib_run][i] =
(cog_calib_count[i] > 0) ? cog_calib_accum[i] / (float)cog_calib_count[i] : 0.0f;
dc += cog_calib_run_data[cog_calib_run][i];
}
dc /= (float)COGGING_TABLE_SIZE;
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
cog_calib_run_data[cog_calib_run][i] -= dc;
}
printf("[COG] Run %d/%d done. DC=%.2f mA\r\n",
cog_calib_run + 1, TOTAL_RUNS, dc);
cog_calib_run++;
if (cog_calib_run < TOTAL_RUNS) {
// run 0~2 正转,run 3~5 反转
control_mode = 6;
target_velocity = (cog_calib_run < 3) ? SLOW_VEL : -SLOW_VEL;
cog_calib_state = CogCalibState::SETTLING;
cog_calib_settle_tick = 0;
} else {
cog_calib_state = CogCalibState::DONE;
}
}
return;
case CogCalibState::DONE:
// 正转平均 (run 0~2)
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
cogging_table[i] = (cog_calib_run_data[0][i] +
cog_calib_run_data[1][i] +
cog_calib_run_data[2][i]) / 3.0f;
}
// 反转平均 (run 3~5)
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
cogging_table_rev[i] = (cog_calib_run_data[3][i] +
cog_calib_run_data[4][i] +
cog_calib_run_data[5][i]) / 3.0f;
}
cogging_comp_enabled = true;
control_mode = cog_calib_saved_mode;
target_velocity = cog_calib_saved_vel;
// 打印正转平均
printf("\r\n[COG] === FWD Average ===\r\n");
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
float angle_deg = (float)i / (float)COGGING_TABLE_SIZE * 360.0f;
printf("[COG] %.2f, %.2f\r\n", angle_deg, cogging_table[i]);
fwdgt_counter_reload();
}
// 打印反转平均
printf("\r\n[COG] === REV Average ===\r\n");
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
float angle_deg = (float)i / (float)COGGING_TABLE_SIZE * 360.0f;
printf("[COG] %.2f, %.2f\r\n", angle_deg, cogging_table_rev[i]);
fwdgt_counter_reload();
}
// 打印正转 C Array
printf("\r\n[COG] --- FWD C Array ---\r\n");
printf("static const float COGGING_TABLE_FWD[COGGING_TABLE_SIZE] = {\r\n");
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
if (i % 8 == 0) printf(" ");
printf("%.2ff", cogging_table[i]);
if (i < COGGING_TABLE_SIZE - 1) printf(", ");
if (i % 8 == 7 || i == COGGING_TABLE_SIZE - 1) printf("\r\n");
fwdgt_counter_reload();
}
printf("};\r\n");
// 打印反转 C Array
printf("\r\n[COG] --- REV C Array ---\r\n");
printf("static const float COGGING_TABLE_REV[COGGING_TABLE_SIZE] = {\r\n");
for (int i = 0; i < COGGING_TABLE_SIZE; i++) {
if (i % 8 == 0) printf(" ");
printf("%.2ff", cogging_table_rev[i]);
if (i < COGGING_TABLE_SIZE - 1) printf(", ");
if (i % 8 == 7 || i == COGGING_TABLE_SIZE - 1) printf("\r\n");
fwdgt_counter_reload();
}
printf("};\r\n");
printf("\r\n[COG] === Done. ===\r\n");
cog_calib_state = CogCalibState::IDLE;
return;
}
}
#endif // FOC_DEBUG
// 初始变量及函数定义
#define _constrain(amt, low, high) \
((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
@@ -92,6 +296,47 @@ inline float FOC_Controller::cal_Iq_Id(float current_a, float current_b,
u8 FOC_Controller::init() {
motor_init(); // 电机驱动初始化
// 齿槽转矩补偿表(硬编码,3正+3反平均,用真实角度算Iq)
static const float COGGING_TABLE_FWD[COGGING_TABLE_SIZE] = {
29.28f, 28.84f, 28.26f, 28.83f, 29.79f, 30.26f, 29.52f, 28.77f,
28.23f, 27.68f, 26.65f, 25.19f, 23.92f, 22.59f, 19.61f, 16.77f,
13.32f, 10.40f, 7.64f, 3.51f, -0.83f, -4.96f, -8.19f, -11.11f,
-13.40f, -14.39f, -15.69f, -15.99f, -16.39f, -15.50f, -14.76f, -14.21f,
-13.76f, -13.88f, -13.22f, -11.18f, -10.65f, -10.54f, -10.62f, -10.23f,
-9.52f, -8.19f, -6.31f, -4.14f, -1.94f, -0.25f, 2.06f, 4.08f,
6.05f, 8.30f, 9.74f, 11.38f, 13.32f, 15.65f, 17.55f, 20.22f,
21.72f, 22.28f, 23.30f, 24.78f, 23.53f, 23.35f, 23.00f, 21.42f,
20.35f, 20.57f, 20.07f, 18.18f, 17.04f, 16.03f, 14.81f, 13.71f,
12.47f, 10.93f, 9.38f, 6.53f, 4.63f, 3.37f, 1.29f, -1.28f,
-5.08f, -11.11f, -16.35f, -21.00f, -24.61f, -28.30f, -31.11f, -33.48f,
-35.25f, -36.54f, -38.01f, -38.69f, -39.27f, -39.52f, -38.18f, -36.55f,
-34.96f, -33.14f, -31.92f, -31.45f, -31.32f, -30.25f, -29.60f, -28.72f,
-27.51f, -25.30f, -22.66f, -20.87f, -18.19f, -16.10f, -13.25f, -10.81f,
-8.00f, -4.67f, -2.28f, 0.87f, 3.83f, 7.25f, 10.56f, 13.70f,
17.70f, 19.90f, 22.14f, 23.62f, 24.53f, 26.03f, 26.96f, 27.95f,
};
static const float COGGING_TABLE_REV[COGGING_TABLE_SIZE] = {
22.45f, 24.95f, 26.05f, 26.01f, 26.11f, 25.87f, 26.20f, 26.23f,
26.19f, 25.87f, 25.97f, 26.09f, 24.77f, 24.22f, 23.71f, 22.10f,
19.84f, 17.60f, 15.36f, 12.99f, 9.54f, 5.35f, 1.71f, -1.94f,
-4.15f, -6.16f, -7.93f, -9.10f, -10.01f, -10.25f, -10.85f, -11.74f,
-11.98f, -10.78f, -9.65f, -8.89f, -8.14f, -6.85f, -5.94f, -5.37f,
-4.28f, -3.38f, -3.36f, -3.40f, -2.81f, -2.36f, -1.04f, -0.18f,
1.08f, 2.15f, 4.19f, 5.51f, 7.33f, 8.64f, 10.46f, 11.89f,
13.42f, 14.83f, 17.11f, 19.12f, 20.76f, 21.88f, 22.35f, 22.86f,
22.73f, 22.13f, 21.10f, 20.53f, 18.65f, 17.09f, 15.47f, 14.76f,
14.02f, 12.94f, 11.98f, 10.29f, 8.11f, 5.83f, 4.23f, 2.42f,
1.03f, -1.80f, -4.01f, -7.93f, -11.79f, -15.90f, -20.22f, -23.04f,
-25.66f, -28.80f, -30.45f, -32.11f, -33.17f, -33.97f, -34.68f, -34.26f,
-34.18f, -33.78f, -32.47f, -31.11f, -29.40f, -27.89f, -27.05f, -26.72f,
-25.59f, -24.86f, -23.61f, -22.97f, -22.89f, -21.81f, -20.78f, -19.23f,
-17.74f, -15.09f, -13.18f, -10.51f, -8.18f, -5.89f, -3.35f, -0.02f,
2.02f, 3.87f, 6.37f, 9.11f, 12.33f, 14.63f, 17.12f, 19.12f,
};
memcpy(cogging_table, COGGING_TABLE_FWD, sizeof(COGGING_TABLE_FWD));
memcpy(cogging_table_rev, COGGING_TABLE_REV, sizeof(COGGING_TABLE_REV));
cogging_comp_enabled = true;
FOC.cur_loop_p = DEFAULT_current_loop_p * 100 / limit_voltage;
FOC.cur_MIT_p = DEFAULT_current_MIT_p * 100 / limit_voltage;
FOC.vel_loop_p = DEFAULT_vel_loop_p * 100 / limit_voltage;
@@ -109,50 +354,6 @@ u8 FOC_Controller::init() {
*/
FOC_Controller::FOC_Controller() { ; }
// /**
// * @brief 设置电机输出
// *
// * @param Uq: q轴电压
// * @param Ud: d轴电压
// * @param angle_el: 电机轴角度
// */
// inline void FOC_Controller::setPhaseVoltage(float Uq, float Ud) {
// // 计算电气角度
// float angle_el = fmod(shaft_angle * PP, 360.0f);
// // 帕克逆变换 (直接计算,避免函数调用开销)
// float sin_el, cos_el;
// arm_sin_cos_f32(angle_el, &sin_el, &cos_el);
// float Ualpha = Ud * cos_el - Uq * sin_el;
// float Ubeta = Ud * sin_el + Uq * cos_el;
// // 克拉克逆变换 (使用预计算常量优化)
// Ua = Ualpha + v_half;
// Ub = SQRT3DV2 * Ubeta - 0.5f * Ualpha + v_half;
// Uc = -0.5f * Ualpha - SQRT3DV2 * Ubeta + v_half;
// if (Ua > v_safe)
// Ua = v_safe;
// else if (Ua < -v_safe)
// Ua = -v_safe;
// if (Ub > v_safe)
// Ub = v_safe;
// else if (Ub < -v_safe)
// Ub = -v_safe;
// if (Uc > v_safe)
// Uc = v_safe;
// else if (Uc < -v_safe)
// Uc = -v_safe;
// // 设置PWM输出
// float voltage_exchange = limit_voltage / v_safe;
// duty_a = Ua / voltage_power_supply * voltage_exchange;
// duty_b = Ub / voltage_power_supply * voltage_exchange;
// duty_c = Uc / voltage_power_supply * voltage_exchange;
// Set_3Pwm(duty_a, duty_b, duty_c);
// }
/**
* @brief 使用SVPWM算法设置电机输出
*
@@ -418,7 +619,9 @@ float FOC_Controller::velocity_open_loop() {
// 因为在开环控制中,Ud 始终为 0,只控制 Uq
const float Uq = _constrain(target_velocity * REDUCTION_RATIO * 0.005f,
2.0f, voltage_power_supply * 0.5f);
setSVPWM_PhaseVoltage(Uq, 0.0f);
// 齿槽转矩补偿
float angle_el_cog = fmodf(shaft_angle * PP + KTH7823.calibration_angle, 360.0f);
setSVPWM_PhaseVoltage(Uq + get_cogging_compensation(angle_el_cog), 0.0f);
return limit_voltage;
}
@@ -436,8 +639,10 @@ float FOC_Controller::angle_control() {
shaft_angle = KTH7823.getcurrent_sensorangle();
rt_current = cal_Iq_Id(sampler.get_current('U'), sampler.get_current('V'),
sampler.get_current('W'));
// 齿槽转矩补偿
float angle_el_cog = fmodf(shaft_angle * PP + KTH7823.calibration_angle, 360.0f);
// 设置相电压
setSVPWM_PhaseVoltage(Uq, 0.0f);
setSVPWM_PhaseVoltage(Uq + get_cogging_compensation(angle_el_cog), 0.0f);
return shaft_angle;
}
@@ -465,8 +670,10 @@ float FOC_Controller::velocity_control() {
// 获取电机轴角度
shaft_angle = KTH7823.getcurrent_sensorangle();
// 齿槽转矩补偿
float angle_el_cog = fmodf(shaft_angle * PP + KTH7823.calibration_angle, 360.0f);
// 设置相电压
setSVPWM_PhaseVoltage(Uq, 0.0f);
setSVPWM_PhaseVoltage(Uq + get_cogging_compensation(angle_el_cog), 0.0f);
rt_current = cal_Iq_Id(sampler.get_current('U'), sampler.get_current('V'),
sampler.get_current('W'));
@@ -487,8 +694,10 @@ float FOC_Controller::current_control() {
// 获取电机轴角度
shaft_angle = KTH7823.getcurrent_sensorangle();
CAN0_transmiter.testfloat_union.f = shaft_angle;
// 齿槽转矩补偿
float angle_el_cog = fmodf(shaft_angle * PP + KTH7823.calibration_angle, 360.0f);
// 设置相电压
setSVPWM_PhaseVoltage(Uq, 0.0f);
setSVPWM_PhaseVoltage(Uq + get_cogging_compensation(angle_el_cog), 0.0f);
return 1;
}
@@ -529,25 +738,17 @@ float FOC_Controller::angle_control_with_velocity_limit() {
last_velocity_error = velocity_error;
float Uq = vel_inVelAngloop(velocity_error)* DIR;
CAN0_transmiter.testfloat_union.f = Uq;
// // 实现力度控制:如果电流超过目标电流,则限制输出
// if (abs(rt_current) > abs(target_current)) {
// // 当实际电流超过目标电流时,减小输出以限制电流
// // 可以采用比例限制或直接限制输出电压的方式
// float current_ratio = abs(target_current) / abs(rt_current);
// if (current_ratio < 1.0f) {
// Uq *= current_ratio; // 按比例缩小输出电压
// }
// }
// 获取电机轴角度
shaft_angle = KTH7823.getcurrent_sensorangle();
CAN0_transmiter.testfloat_union.f = shaft_angle;
// 获取当前实际电流值
rt_current = cal_Iq_Id(sampler.get_current('U'), sampler.get_current('V'),
sampler.get_current('W'));
// 齿槽转矩补偿
float angle_el_cog = fmodf(shaft_angle * PP + KTH7823.calibration_angle, 360.0f);
// 设置相电压
setSVPWM_PhaseVoltage(Uq, 0.0f);
setSVPWM_PhaseVoltage(Uq + get_cogging_compensation(angle_el_cog), 0.0f);
return shaft_angle;
}
@@ -561,14 +762,12 @@ float FOC_Controller::angle_control_with_velocity_limit() {
*/
float FOC_Controller::MIT_Mode() {
// 第一层:角度环(外环)
// 根据目标角度和实际角度的差值,通过角度环PID控制器计算目标速度
float angle_error = target_angle - rt_angle;
ang_inMITloop.set_P(ang_MIT_p);
float target_velocity =
ang_inMITloop(angle_error); // 使用angle_loop作为角度到速度的映射
ang_inMITloop(angle_error);
// 第二层:速度环(中环)
// 根据目标速度和实际速度的差值,通过速度环PID控制器计算目标电流
float velocity_error = (target_velocity - rt_velocity)* DIR;
// 目标速度变化检测:target 大幅变化时清积分
@@ -582,11 +781,9 @@ float FOC_Controller::MIT_Mode() {
float target_current = vel_inMITloop(velocity_error);
// 第三层:电流环(内环)
// 计算当前实际电流
rt_current = cal_Iq_Id(sampler.get_current('U'), sampler.get_current('V'),
sampler.get_current('W'));
// 通过电流环PID控制器计算输出电压
float current_error = target_current - rt_current;
current_inMITloop.set_P(cur_MIT_p);
float Uq = current_inMITloop(current_error);
@@ -594,8 +791,10 @@ float FOC_Controller::MIT_Mode() {
// 获取电机轴角度
shaft_angle = KTH7823.getcurrent_sensorangle();
// 齿槽转矩补偿
float angle_el_cog = fmodf(shaft_angle * PP + KTH7823.calibration_angle, 360.0f);
// 设置相电压
setSVPWM_PhaseVoltage(Uq, 0.0f);
setSVPWM_PhaseVoltage(Uq + get_cogging_compensation(angle_el_cog), 0.0f);
return shaft_angle;
}
+32 -1
View File
@@ -70,7 +70,38 @@ class FOC_Controller {
void shut_down_thermal(void); // 过热关机
void resume_from_thermal(void); // 过热恢复
void fast_voltage_check(void); // 快速电压检测(100us周期调用)
// 齿槽转矩补偿
bool cogging_comp_enabled = false;
float cogging_comp_scale = COGGING_COMP_SCALE;
float cogging_table[COGGING_TABLE_SIZE] = {0}; // 齿槽补偿表-正转 (mA)
float cogging_table_rev[COGGING_TABLE_SIZE] = {0}; // 齿槽补偿表-反转 (mA)
inline float get_cogging_compensation(float angle_el);
// === 校准相关(DEBUG,平时不启用)===
// 启用方法:config.h 中 FOC_DEBUG 改为 1
#if FOC_DEBUG
volatile bool cogging_calib_request = false;
void calibrate_cogging_tick(void);
enum class CogCalibState : u8 {
IDLE = 0,
SETTLING,
SAMPLING,
STOPPING,
DONE
};
CogCalibState cog_calib_state = CogCalibState::IDLE;
u8 cog_calib_run = 0;
u32 cog_calib_sample_count = 0;
u32 cog_calib_settle_tick = 0;
u32 cog_calib_stop_tick = 0;
u8 cog_calib_saved_mode = 0;
float cog_calib_saved_vel = 0;
static float cog_calib_run_data[6][COGGING_TABLE_SIZE]; // 3正+3反
static float cog_calib_accum[COGGING_TABLE_SIZE];
static u32 cog_calib_count[COGGING_TABLE_SIZE];
#endif // FOC_DEBUG
// 此处默认值不作数
PIDController vel_loop =
PIDController{DEFAULT_vel_loop_p * 100 / limit_voltage, vel_loop_Ki,
-1
View File
@@ -25,7 +25,6 @@ project:
- file: device/adc.h
- file: device/Timer.cpp
- file: device/Timer.h
- file: device/test.cpp
- file: device/motor.cpp
- file: device/motor.h
- group: Algorithm
+6
View File
@@ -1153,6 +1153,12 @@ void CAN_transmiter::communication_check() {
Angle_kalman.init(0); // 角度滤波
Vel_kalman.init(0); // 角度滤波
}
// 齿槽转矩校准 (first_byte bit4) — DEBUG,平时不启用
#if FOC_DEBUG
if (first_byte >> 4 & 0x01) {
FOC.cogging_calib_request = true;
}
#endif
// 休眠
if (eigth_byte & 0x80 >> 7) {
app_prepare_deep_sleep(true);
-33
View File
@@ -1,33 +0,0 @@
#include "adc.h"
#include "config.h"
#include <cstdio>
// TEST 调试宏定义
#if TEST_DEBUG
#define TEST_DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define TEST_DEBUG_PRINT(fmt, ...) ((void)0)
#endif
constexpr int status_print = 0;
extern sampler sampler;
void test_1111() {
// 初始化 CAN 回环测试
// can_loopback_init();
// can_config();
if (status_print) {
/* value print */
TEST_DEBUG_PRINT(" the temperature data is %2.2f degrees Celsius\r\n",
sampler.get_mcu_temp());
TEST_DEBUG_PRINT(" the drv_temperature data is %2.2f degrees Celsius\r\n",
sampler.get_drv_temp());
TEST_DEBUG_PRINT(" the U current data is %2.2f mA\r\n", sampler.get_current('U'));
TEST_DEBUG_PRINT(" the V current data is %2.2f mA\r\n", sampler.get_current('V'));
TEST_DEBUG_PRINT(" the W current data is %2.2f mA\r\n", sampler.get_current('W'));
TEST_DEBUG_PRINT(" the VBUS is %2.2f V\r\n", sampler.get_vbus_voltage());
// TEST_DEBUG_PRINT(" the angle is %2.2f\r\n", tle5012b_read());
TEST_DEBUG_PRINT("\n----------------------------------------------------\n");
}
// can_loopback_test();
}
+7
View File
@@ -99,6 +99,7 @@ u8 hardware_init(void) {
void do_task(u32 currentTasks) {
busy_task_enter(); // DWT: 记录忙碌起始周期
cnt_test++;
// 按照优先级和重要性处理任务
if (currentTasks & (1 << TASK_CURRENT_UPDATE)) { // 更新电流采样值
sampler.update_current();
@@ -147,6 +148,12 @@ void do_task(u32 currentTasks) {
}
}
}
// 齿槽转矩校准 tick(DEBUG,平时不启用)
#if FOC_DEBUG
FOC.calibrate_cogging_tick();
#endif
if (currentTasks & (1 << TASK_MCU_TEMP_UPDATE)) { // 更新 mcu 温度传感器值
sampler.update_mcu_temp();
}
+12 -8
View File
@@ -6,18 +6,18 @@
// 如果使用 CMSIS DSP 库,需要定义 ARM_MATH_CM4
#define ARM_MATH_CM4
#define EEP_DEBUG 1
#define OTA_DEBUG 1
#define SLEEP_DEBUG 1
#define ANG_SENS_DEBUG 1
#define CAN_DEBUG 1
#define MAIN_DEBUG 1
#define TEST_DEBUG 1
#define EEP_DEBUG 0
#define OTA_DEBUG 0
#define SLEEP_DEBUG 0
#define ANG_SENS_DEBUG 0
#define CAN_DEBUG 0
#define MAIN_DEBUG 0
#define FOC_DEBUG 0
// 版本号定义 - 可根据实际项目进行调整
constexpr u16 SOFTWARE_VERSION_MAJOR = 26;
constexpr u16 SOFTWARE_VERSION_MINOR = 5;
constexpr u16 SOFTWARE_VERSION_PATCH = 17;
constexpr u16 SOFTWARE_VERSION_PATCH = 19;
constexpr u16 SOFTWARE_VERSION_BUILD = 2;
constexpr u16 HARDWARE_VERSION_MAJOR = 25;
@@ -232,6 +232,10 @@ constexpr int TIMER1_DEFAULT_PULSE = 0;
constexpr int TIMER1_CH3_COMPARE_VALUE =
(TIMER1_PERIOD + 1) * 0.41 - 1; // PWM 周期 41% 位置触发ADC采样
// 齿槽转矩补偿
constexpr u16 COGGING_TABLE_SIZE = 128; // 每电周期采样点数
constexpr float COGGING_COMP_SCALE = 0.005f; // 补偿换算系数 V/mA,40mA × 0.005 = 0.2V
// 电压检测参数(基于跌幅检测,不依赖固定额定电压)
// 快速检测层(fast_voltage_check,100us周期):
// - 使用峰值检测算法跟踪当前额定电压(vbus_reference)