Files
Motor_v2/Robot_V2/sys/config.h
T
cbb 7c4aaa5ee6 feat(FOC): 优化FOC控制算法并修复多个控制环路问题
- 重构cal_Iq_Id函数,移除电角度参数传递,改用预计算的sin/cos值
  以避免重复三角函数计算,提升性能约15-300周期
- 修复角度同步Uq前馈学习中的运动方向判断逻辑,解决反转时的
  震荡问题和正转正常反转震荡的根本原因
- 实现低速缩放因子函数get_mode3_velocity_scale,改进静摩擦
  hunting抑制效果
- 优化电压检测逻辑,将阻塞式ADC读取改为连续模式零等待,
  提升实时性能
- 修复初始化期间电压分母为零的问题,添加下限保护防止P增益
  无穷大
- 实现PID控制器测量微分功能,消除目标阶跃时的微分冲击
- 改进积分抗饱和策略,添加外部饱和泄放功能,优化到位稳定
  性能

perf(Filter): 优化中值滤波算法性能

- 针对ADC_FILTER_SIZE=6的固定场景实现最优排序网络,
  用12次比较替代通用std::nth_element算法,显著提升性能
- 保留通用回退路径处理其他尺寸情况
2026-09-01 02:46:25 +08:00

366 lines
19 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.
/**
* @file sys/config.h
* @brief 系统服务与平台支持源文件
* @note 本文件仅补充 Doxygen 文档注释,不改变代码逻辑。
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include "gd32c10x_eval.h"
#include <cstdint>
// 项目级定宽类型别名(u8/u16/u32 等):整个工程统一从这里取,
// 重复 typedef 同一类型在 C++ 中合法,包含多次无副作用
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef volatile uint8_t vu8;
typedef volatile uint16_t vu16;
typedef volatile uint32_t vu32;
// 如果使用 CMSIS DSP 库,需要定义 ARM_MATH_CM4
#define ARM_MATH_CM4
#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
// ===================== 版本号定义 =====================
// 软件版本 = 编译日期自动生成(年.月.日)+ 当天构建小版本号(手动递增)
// __DATE__ 形如 "Mmm dd yyyy"(如 "Aug 29 2026"):2026-08-29 当天第一次
// 构建得到 26.8.29.1;同一天多次出固件时把 SOFTWARE_VERSION_BUILD +1
#define CFG_VER_YEAR \
((__DATE__[7] - '0') * 1000 + (__DATE__[8] - '0') * 100 + \
(__DATE__[9] - '0') * 10 + (__DATE__[10] - '0'))
#define CFG_VER_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
#define CFG_VER_IS_FEB (__DATE__[0] == 'F' && __DATE__[1] == 'e' && __DATE__[2] == 'b')
#define CFG_VER_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
#define CFG_VER_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p' && __DATE__[2] == 'r')
#define CFG_VER_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
#define CFG_VER_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
#define CFG_VER_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
#define CFG_VER_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u' && __DATE__[2] == 'g')
#define CFG_VER_IS_SEP (__DATE__[0] == 'S' && __DATE__[1] == 'e' && __DATE__[2] == 'p')
#define CFG_VER_IS_OCT (__DATE__[0] == 'O' && __DATE__[1] == 'c' && __DATE__[2] == 't')
#define CFG_VER_IS_NOV (__DATE__[0] == 'N' && __DATE__[1] == 'o' && __DATE__[2] == 'v')
#define CFG_VER_IS_DEC (__DATE__[0] == 'D' && __DATE__[1] == 'e' && __DATE__[2] == 'c')
#define CFG_VER_MONTH \
(CFG_VER_IS_JAN ? 1 \
: CFG_VER_IS_FEB ? 2 \
: CFG_VER_IS_MAR ? 3 \
: CFG_VER_IS_APR ? 4 \
: CFG_VER_IS_MAY ? 5 \
: CFG_VER_IS_JUN ? 6 \
: CFG_VER_IS_JUL ? 7 \
: CFG_VER_IS_AUG ? 8 \
: CFG_VER_IS_SEP ? 9 \
: CFG_VER_IS_OCT ? 10 \
: CFG_VER_IS_NOV ? 11 \
: CFG_VER_IS_DEC ? 12 \
: 0)
/* 日字段两位,个位数时首字符为空格(如 "Aug 5 2026") */
#define CFG_VER_DAY \
((__DATE__[4] == ' ') ? (__DATE__[5] - '0') \
: ((__DATE__[4] - '0') * 10 + (__DATE__[5] - '0')))
constexpr u16 SOFTWARE_VERSION_MAJOR = CFG_VER_YEAR % 100; // 年后两位,如 26
constexpr u16 SOFTWARE_VERSION_MINOR = CFG_VER_MONTH; // 月
constexpr u16 SOFTWARE_VERSION_PATCH = CFG_VER_DAY; // 日
constexpr u16 SOFTWARE_VERSION_BUILD = 1; // 当天第几次构建,手动递增
// 硬件版本:全手写,仅在 PCB 改版时修改(编译 APP 不影响)
constexpr u16 HARDWARE_VERSION_MAJOR = 25;
constexpr u16 HARDWARE_VERSION_MINOR = 12;
constexpr u16 HARDWARE_VERSION_PATCH = 1;
constexpr u16 HARDWARE_VERSION_BUILD = 0;
// BOOT 版本:全手写,仅在 bootloader 更新时修改(APP 编译不影响)
constexpr u16 BOOT_VERSION_MAJOR = 26;
constexpr u16 BOOT_VERSION_MINOR = 1;
constexpr u16 BOOT_VERSION_PATCH = 12;
constexpr u16 BOOT_VERSION_BUILD = 0;
// ===================== 功率级门驱动芯片选择 =====================
// 1 = 新板 DRV8323RS(外置 WSD6035DN33):使能前经 SPI 配置 3x PWM 模式、
// CSA 增益、VDS 过流门限;3 路 PWM 接 INHA/B/C(CH2/CH1/CH0,
// 固件内已做通道重映射);PB12(DRVSLP) 同时是使能脚与 INLA/B/C 电平
// (高=正常运转,低=三相 Hi-Z 睡眠滑行)。
// 0 = 老板 DRV8313(集成 FET 三半桥):无 SPI,保持原使能时序与相序。
#define GATE_DRIVER_DRV8323 0
#if GATE_DRIVER_DRV8323
// DRV8323 片上 CSA 增益(V/V),经 SPI 写入 0x06[7:6],仅 5/10/20/40 有效。
// 双极性量程 = ±1.655V/(G×Rshunt):G=10、R=10mΩ 时约 ±16.5A。
// 修改后电流换算系数 CURRENT_FACTOR(ADC.cpp)自动跟随,但软件限流标定需复核。
constexpr float DRV8323_CSA_GAIN_VV = 10.0f;
constexpr float DRV8323_SHUNT_OHM = 0.010f;
#endif
// 编译时间(AC6 编译器自动生成)
#define APP_BUILD_DATE __DATE__
#define APP_BUILD_TIME __TIME__
// Flash 分区配置
constexpr u32 BOOTLOADER_START_ADDR = 0x08000000; // BOOT 起始地址
constexpr u32 APPLATEST_START_ADDR = 0x08012000; // APP 起始地址
constexpr u32 APPBACK_START_ADDR = 0x08006000; // APPBACK 起始地址
constexpr u32 APP_MAX_SIZE = 0xC000; // 48KB
constexpr u32 FMC_PAGE_SIZE = 0x400; // 1KB
constexpr u32 SLEEP_CONFIG_START = 0x0801E400; // 睡眠配置起始地址
constexpr u32 SLEEP_CONFIG_END = 0x0801E800; // 睡眠配置结束地址
constexpr u32 FLASH_EMPTY = 0xFFFFFFFF; // 空数据
constexpr u32 SLEEP_ENABLE = 0x11111111; // 睡眠使能
// 节点 ID 配置 (用于多电机 CAN 总线隔离)
// 使用 CAN ID 高 16 位 (bits 31-16) 存储节点 ID,低 16 位 (bits 15-0) 存储基础 ID
// 格式:[节点 ID(16 位)][基础 ID(16 位)],例如:node_id=1, base_id=0x0200 → 0x00010200
//
// 节点 ID 存储方案:
// - 使用独立 Flash 页存储节点 ID,与EEPROM完全隔离
// - 采用双重备份机制:主备份与备用备份分属两个独立 1KB 页,
// 擦写其一不影响另一份,掉电时至少保留一份有效数据
// - 写入采用乒乓方式:总是写入"非最新"的那一页,另一页全程保有旧值
// - 使用魔数 (NODE_ID_MAGIC) 验证数据有效性,防止位翻转导致错读
// - 使用写入计数器区分最新数据(计数器跳过 0,比较用有符号差值容忍回绕)
constexpr u32 NODE_ID_PAGE_ADDR = 0x0801E800; // 节点 ID 主存储页 (1KB,独立区域)
constexpr u32 NODE_ID_PRIMARY_ADDR = 0x0801E800; // 主备份地址
constexpr u32 NODE_ID_BACKUP_ADDR = 0x0801EC00; // 备用备份地址(独立 1KB 页)
constexpr u32 NODE_ID_MAGIC = 0x4E4F4445; // 魔数 'NODE' 用于验证数据有效性
constexpr u16 DEFAULT_NODE_ID = 1; // 默认节点 ID
constexpr u16 BROADCAST_NODE_ID = 0x1FFF; // 广播 ID (所有节点响应)
constexpr u16 MAX_NODE_ID = 0x1FFE; // 最大有效节点 ID (0~0x1FFE)
constexpr u16 SETTABLE_NODE_ID_MAX = 0x00FF; // SET_NODE_ID 命令允许设置的上限 (1~0xFF)
// 节点 ID 存储结构 (主备份/备用备份各一份,每份 16 字节,位于各自页首)
// 地址偏移 0x00: 魔数 (0x4E4F4445 = 'NODE')
// 地址偏移 0x04: 节点 ID (u16)
// 地址偏移 0x06: 保留 (u16,填充为0xFFFF)
// 地址偏移 0x08: 写入计数器 (u32,用于区分最新数据)
// 地址偏移 0x0C: CRC32 校验 (u32)
constexpr u8 NODE_ID_MAGIC_OFFSET = 0x00; // 魔数偏移
constexpr u8 NODE_ID_VALUE_OFFSET = 0x04; // 节点ID值偏移
constexpr u8 NODE_ID_COUNTER_OFFSET = 0x08; // 写入计数器偏移
constexpr u8 NODE_ID_CRC_OFFSET = 0x0C; // CRC偏移
// BOOT 相关
// 版图/页大小核验:以下 6 个 OTA 标志位共处 0x0801E000 所在的 1KB Flash 页。
// OTA_SET 会整页擦除该页,故必须保证 FMC 页大小为 1KB(0x400),否则会连带擦除
// 相邻的 SLEEP_CONFIG(0x0801E400)/NODE_ID(0x0801E800)。GD32C103CB 实测页大小为
// 1KB(睡眠/节点 ID/EEPROM 分居相邻 1KB 页且互不影响即为佐证),与 FMC_PAGE_SIZE 一致。
constexpr u32 OTA_CONFIG_NUM = 6;
constexpr u32 n_APP_LATEST_AVAL_ADDR = 0x0801E000; // 最新 APP 可用地址
constexpr u32 n_APP_BACKUP_AVAL_ADDR = 0x0801E004; // 备份 APP 可用地址
constexpr u32 n_APP_LATEST_EN_ADDR = 0x0801E008; // 最新 APP 激活
constexpr u32 n_APP_BACKUP_EN_ADDR = 0x0801E00C; // 备份 APP 激活
constexpr u32 n_APP_LATEST_CHECK_ADDR = 0x0801E010; // 最新 APP 校验
constexpr u32 n_APP_BACKUP_CHECK_ADDR = 0x0801E014; // 备份 APP 校验
constexpr u32 OTA_NOT_AVAL = 0xFFFFFFFF;
constexpr u32 OTA_AVAL = 0x00000000; // 全零表示可用
// 参数配置
constexpr u8 PP = 11;
constexpr float DIR = 1.0f; // 默认方向:-1.0f 反转,1.0f 正转
constexpr u16 REDUCTION_RATIO = 25;
constexpr float CURRENT_OFFSET = -3.31f / 2.0f; // 当前电流传感器的零点偏移
constexpr float HOLD_PWM_DUTY = 0.1f;
constexpr u16 ANGLESENS_OFFSET = 0;
constexpr float ANGLESENS_CALIBRATION_ANGLE = 83.0f;
// 电角度零位校准:施加的对齐占空比与稳定等待时间
constexpr float ALIGN_PWM_DUTY = 0.25f;
constexpr u32 ALIGN_SETTLE_MS = 1000;
constexpr float CALIB_MAX_SPEED = 5.0f; // 输出级速度阈值(deg/s),超过则拒绝校准
constexpr float KE_FACTOR = 0.0f;
// 角度/速度 α-β 观测器参数
constexpr float ANGLE_KALMAN_INITIAL_STATE = 0.0f;
constexpr float ANGLE_KALMAN_INITIAL_COVARIANCE = 0.0f;
constexpr float ANGLE_KALMAN_PROCESS_NOISE_Q = 0.0f;
constexpr float ANGLE_KALMAN_MEASUREMENT_NOISE_R = 0.0f;
constexpr float ANGLE_OBSERVER_ALPHA = 0.75f; // 角度校正增益,越大越跟测量
constexpr float ANGLE_OBSERVER_BETA = 0.002f; // 速度校正增益,原0.001微调至0.002
// 旧速度 Kalman 参数保留用于接口兼容;主速度输出现在直接来自 α-β 观测器
constexpr float VELOCITY_KALMAN_INITIAL_STATE = 0.0f;
constexpr float VELOCITY_KALMAN_INITIAL_COVARIANCE = 1e-3f;
constexpr float VELOCITY_KALMAN_PROCESS_NOISE_Q =
5e-4f; // 略增大,减少拖尾
constexpr float VELOCITY_KALMAN_MEASUREMENT_NOISE_R =
0.05f; // 明显小于旧值,避免压得太死
// 电流卡尔曼滤波器参数
constexpr float CURRENT_KALMAN_INITIAL_STATE = 0.0f;
constexpr float CURRENT_KALMAN_INITIAL_COVARIANCE = 100.0f; // 增大初始协方差
constexpr float CURRENT_KALMAN_PROCESS_NOISE_Q = 10.0f; // 降低过程噪声
constexpr float CURRENT_KALMAN_MEASUREMENT_NOISE_R = 5e-5f; // 增大测量噪声
// PID 配置
constexpr float DEFAULT_current_loop_p = 0.1f / 100 * 12; // 电流 P
constexpr float current_loop_Ki = 0.55f; // 电流 P
// 电流反馈噪声大(CurrentKalman 稳态增益≈1,几乎无滤波),D 项只放大噪声,置零
constexpr float current_loop_Kd = 0.0f;
constexpr float DEFAULT_vel_loop_p = 0.005f / 100 * 12; // 速度 P
constexpr float vel_loop_Ku = 3.600000e-03 * 0.7 * 100 / 12;
constexpr float vel_loop_Tu = 17.0f * 1e-3f;
constexpr float vel_loop_Ki = 1.2 * vel_loop_Ku / vel_loop_Tu;
// 速度 D 恢复(提供加速度阻尼);现走"测量微分+1ms低通"路径,无目标阶跃踢、
// 噪声被低通抑制,比旧的裸误差微分安全
constexpr float vel_loop_Kd = 0.075 * vel_loop_Ku * vel_loop_Tu * 2;
// PID 抗饱和与微分滤波(负载稳定性优化,2026-08)
// 抗饱和主体为条件积分(饱和方向冻结,见 pid.cpp);此增益仅用于
// bleed_integral() 外部饱和泄放(前馈叠加超限时),且带同号保护不过零
constexpr float ANTI_WINDUP_GAIN = 0.3f; // 外部饱和泄放比例
constexpr float DERIV_LPF_TAU = 0.001f; // 微分项一阶低通时间常数 (s)
constexpr float MIN_LIMIT_VOLTAGE = 0.1f; // P 增益换算分母下限,防 limit_voltage=0 除零
// mode2 角度同步 Uq 前馈补偿:固定 Uq 下的真实速度波动不应从反馈中滤掉,
// 而应按物理 360° 提前补偿负载/阻力差异,降低速度 PID 的周期性纠偏量。
constexpr bool MODE2_UQ_FF_ENABLE = true;
constexpr bool MODE2_UQ_FF_LEARN_ENABLE = true;
constexpr u16 MODE2_UQ_FF_TABLE_SIZE = 180;
constexpr float MODE2_UQ_FF_LEARN_ALPHA = 0.01f; // 越小越慢,避免误学瞬态
constexpr float MODE2_UQ_FF_MIN_TARGET = 1.5f; // 目标速度过低时不学习
constexpr float MODE2_UQ_FF_GAIN = 0.003f; // 速度误差(deg/s)到前馈电压(V)的学习比例
constexpr float MODE2_UQ_FF_MAX = 3.5f; // 前馈补偿电压限幅(V)
constexpr float MODE2_UQ_FF_STOP_SPEED = 2.0f; // 目标/实际速度低于该值时不输出前馈
constexpr float MODE2_UQ_FF_BRAKE_ERR = 3.0f; // 明显超速/刹车时不输出前馈,单位同 velocity_error
constexpr float MODE2_UQ_FF_LEARN_ERR_MAX = 375.0f; // 速度误差带内才学习(≈15°/s×25),防启停瞬态污染表
// mode3 角度同步 Uq 前馈补偿:单独建表,避免和 mode2 互相污染。
constexpr bool MODE3_UQ_FF_ENABLE = true;
constexpr bool MODE3_UQ_FF_LEARN_ENABLE = true;
constexpr u16 MODE3_UQ_FF_TABLE_SIZE = 180;
constexpr float MODE3_UQ_FF_LEARN_ALPHA = 0.01f;
constexpr float MODE3_UQ_FF_MIN_TARGET = 2.5f; // mode3 内部目标速度过低时不学习
constexpr float MODE3_UQ_FF_GAIN = 0.3f; // mode3 速度误差未乘减速比,故增益独立于 mode2
constexpr float MODE3_UQ_FF_MAX = 3.5f;
constexpr float MODE3_UQ_FF_STOP_SPEED = 2.0f; // mode3 内部目标/实际速度低于该值时不输出前馈
constexpr float MODE3_UQ_FF_BRAKE_ERR = 3.0f; // 明显超速/刹车时不输出前馈,单位同 velocity_error
constexpr float MODE3_UQ_FF_LEARN_ERR_MAX = 15.0f; // 速度误差带内(°/s)才学习,防启停瞬态污染表
constexpr float DEFAULT_vel_angloop_p = 0.4f / 100; // 速度 速度 - 角度 P
constexpr float vel_angloop_Ki = 5.0f; // 速度 速度 - 角度 I
constexpr float vel_angloop_Kd = 5e-05f; // 速度 速度 - 角度 D(恢复,走测量微分+低通)
// mode3 低速/静止附近速度内环增益调度(D 保持满值):
// P/I 各自独立地板——I 地板更低,停止瞬间积分充电速率仅为全速的 15%,
// 与静摩擦相互作用(到位 hunting:停下瞬间小幅来回抖动)的能量被大幅压缩;
// P 地板保持足够刚度,减小突破静摩擦所需的误差。
constexpr bool MODE3_LOW_SPEED_P_SCALE_ENABLE = true;
constexpr float MODE3_LOW_SPEED_P_MIN_SCALE = 0.5f;
constexpr float MODE3_LOW_SPEED_I_MIN_SCALE = 0.15f;
constexpr float MODE3_LOW_SPEED_P_LOW = 1.0f;
constexpr float MODE3_LOW_SPEED_P_FULL = 8.0f;
constexpr float DEFAULT_angle_angloop_p =
150.0f / 100 * 12; // 角度 速度 - 角度 P
constexpr float ang_angloop_Ki = 0.00f; // 角度 速度 - 角度 I
constexpr float ang_angloop_Kd = 8e-04f; // 角度 速度 - 角度 D
constexpr float DEFAULT_angle_loop_p = 60.0f / 100 * 12; // 角度 P
constexpr float DEFAULT_angle_MIT_p = 100.0f / 100 * 12; // 角度 MIT P
constexpr float angle_MIT_Ki = 0.0f;
constexpr float angle_MIT_Kd = 8e-04f;
constexpr float DEFAULT_vel_MIT_p = 5.0f / 100; // 速度 MIT P
constexpr float vel_MIT_Ki = 15.0f;
constexpr float vel_MIT_Kd = 1e-04f; // 速度 MIT D(恢复,走测量微分+低通)
constexpr float DEFAULT_current_MIT_p = 0.2f / 100 * 12; // 电流 MIT P
constexpr float current_MIT_Ki = 0.1f;
constexpr float current_MIT_Kd = 0.0f; // 电流 MIT D(置零,同 current_loop_Kd)
// 常量定义
constexpr u8 SIZE_FLOAT = sizeof(float);
constexpr u8 SIZE_U32 = sizeof(uint32_t);
constexpr float ADC_MAX = 65536.0f;
constexpr float PI = 3.14159265358979323846f;
constexpr float _1_SQRT3 = 0.57735026919f; // 1/sqrt(3)
constexpr float SQRT3DV2 = 0.8660254037844386f; // sqrt(3)/2
constexpr float DEG2RAD = 1.0f / 180.0f * PI;
constexpr u8 DEFAULT_VALUE = 0;
constexpr u8 CONFIG_SAVED_NUM = 6;
// CAN 相关
// 注意:以下为 CAN 基础 ID(只保留低 16 位),实际发送/接收时会自动叠加节点 ID
// 到高 16 位 格式:[节点 ID(16 位)][基础 ID(16 位)] 例如:节点 ID=1,发送命令
// ID = (1 << 16) | CANFD_CMD_ID = 0x00010200
// 反馈基础 ID
constexpr u16 CANFD_STATUS_ID = 0x0100; // 状态反馈基础 ID
constexpr u16 CANFD_CONFIG_ID = 0x0101; // 配置信息基础 ID
constexpr u16 CANFD_VERSION_ID = 0x00FF; // 版本信息基础 ID
// 命令基础 ID
constexpr u16 CANFD_CMD_ID = 0x0200; // 控制命令基础 ID
constexpr u16 CANFD_RESET_ID = 0x0301; // 重置命令基础 ID
// 节点 ID 管理基础 ID
constexpr u16 CANFD_SET_NODE_ID = 0x0400; // 设置节点 ID 基础 ID
constexpr u16 CANFD_GET_NODE_ID = 0x0401; // 查询节点 ID 基础 ID
// OTA 相关基础 ID 不受到node ID影响
constexpr u16 CANFD_BOOT_ID = 0x0000; // BOOT 模式基础 ID (进入 BOOT 使用此 ID)
constexpr u16 CANFD_OTA_ACK_ID = 0x0102; // OTA 确认基础 ID
// ADC
constexpr u8 ADC_FILTER_SIZE = 6;
constexpr float ERROR_ADC_VAL = 255.0f;
constexpr float MAX_TEMP = 150.0f;
constexpr float MIN_TEMP = -40.0f;
constexpr float MAX_CURRENT = 40.0f;
constexpr float MIN_CURRENT = -40.0f;
constexpr float MAX_VCC = 65.0f;
constexpr float MIN_VCC = -0.1f;
// ang_sensor
constexpr u16 DEFAULT_COMMAND = 0x0000;
constexpr u16 FAULT_RECEIVE = 0xFFFF;
constexpr float ANGLE_WRAP_THRESHOLD = 300.0f;
constexpr float ANGLE_WRAP_VALUE = 360.0f;
constexpr float ANGLESENS_FACTOR = 1.0f / ADC_MAX * 360.0f;
// TIMER2-任务调度
constexpr int TIMER2_PRESCALER = 119; // 120MHz / 120 = 1MHz
constexpr int TIMER2_PERIOD = 49; // 1 / 1MHz * 50 = 50us
constexpr int MOTOR_PERIOD = 1; // 控制每50us执行一次,无分频
constexpr float TIME_SLICE =
(TIMER2_PERIOD + 1) * (TIMER2_PRESCALER + 1) / 120000000.0f; // 周期
constexpr float MOTOR_FREQUENCY = 1 / TIME_SLICE / MOTOR_PERIOD; // 频率
// TIMER1-PWM
constexpr int TIMER1_PRESCALER = 0; // 不分频,计数器时钟为 120MHz
constexpr int TIMER1_PERIOD = 2999; // 120MHz / (0+1) / (2999+1) = 40kHz计数, 中心对齐实际PWM 20kHz
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)
// - 当电压相对于基准电压下跌超过 VBUS_DROP_THRESHOLD → 关机
// - 当电压低于绝对下限 VBUS_ABSOLUTE_MIN → 关机
// 慢速管理层(power_manage,~10ms周期):
// - 执行Flash保存
// - 状态恢复判断(电压恢复到基准电压的90%以上)
constexpr float VBUS_DROP_THRESHOLD = 5.0f; // 电压跌幅阈值 (V)
constexpr float VBUS_ABSOLUTE_MIN = 12.0f; // 绝对最低电压 (V)
constexpr u32 VBUS_DEBOUNCE_COUNT = 5; // 快速检测:防抖计数 (5次×100us = 500us)
constexpr float VBUS_RECOVERY_RATIO = 0.9f; // 恢复比例(基准电压的90%)
#endif