feat(adc): 添加三相电流零点配平并扩展初始化错误上报

- ADC: 新增 zero_calibrate() 函数,在上电后采集 200 帧计算各通道零点偏差
- ADC: 修改 current_adc_to_ma() 支持逐通道扣除配平后的零点偏移
- ADC: 调整电流采样引脚为模拟输入模式并优化采样时间至 13.5 周期
- CAN: STATUS 帧字节 32~35 新增 InitStatus 字段,反馈初始化错误位图
- main: 细化初始化错误检测,分别标记角度/ADC/CAN/Kalman/FOC/门驱动故障
- config.h: 新增 INIT_ERR_* 错误码定义及 CURRENT_ZERO_CAL_LIMIT 阈值
This commit is contained in:
cbb
2026-09-07 03:34:47 +08:00
parent 7c4aaa5ee6
commit 25ed2a2bde
7 changed files with 250 additions and 36 deletions
+16 -3
View File
@@ -783,8 +783,10 @@ u8 CAN_transmiter::CANFD_all_Send() {
u32 success_flag = 0;
// 打包 status 数据 - 只清零实际使用的 32 字节
memset(transmit_data, 0, 32);
// 打包 status 数据 - 只清零实际使用的 48 字节
// v0.74:字节 32~35 新增 InitStatus(初始化错误码位图,0=全部正常,
// 定义见 config.h INIT_ERR_*,含电流检测配平超限/无采样帧),36~47 预留
memset(transmit_data, 0, 48);
pack_u16_to_bytes(transmit_data, 0, mcu_temp);
pack_u16_to_bytes(transmit_data, 2, motor_temp);
pack_current_s16_to_bytes(transmit_data, 4, u_current_union.f);
@@ -802,9 +804,10 @@ u8 CAN_transmiter::CANFD_all_Send() {
transmit_data[29] = test_u16 & 0xFF;
transmit_data[30] = (test_u16 >> 8) & 0xFF;
transmit_data[31] = cpu_usage;
pack_u32_to_bytes(transmit_data, 32, (u32)init_error_flags);
// 使用节点 ID 构建发送 ID (高 16 位为节点 ID)
success_flag +=
CANFD_AsyncSend(build_can_id(CANFD_STATUS_ID), 32, transmit_data);
CANFD_AsyncSend(build_can_id(CANFD_STATUS_ID), 48, transmit_data);
// 打包 config 数据 - 只清零实际使用的 24 字节
memset(transmit_data, 0, 24);
@@ -972,6 +975,16 @@ void CAN_transmiter::handle_node_message(can_receive_message_struct &current_mes
void CAN_transmiter::handle_control_command(can_receive_message_struct &current_message) {
// 控制帧布局:模式、电压限制、目标电流/速度/角度、三组 P 参数。
/* 收到非零控制模式即视为驱动意图:v2 板 EN 经 R17 10k 下拉、DRV8313
* 上电默认睡眠(上电配平后也保持睡眠态),控制路径里没有其他唤醒点,
* 不在此唤醒则所有闭环控制都落在 Hi-Z 桥臂上永远无效。
* 模式 0(drv_hold 主动锁止,A 相恒 HOLD_PWM_DUTY)不唤醒:上位机
* 上电先发模式 0 当"静止待机"时不至于意外通电锁止发热;驱动已在
* 唤醒态时模式 0 仍是锁止。幂等;关机态(过流/过压/过热)不唤醒,
* 恢复仍由 power_manage / resume_from_thermal 统一管理。 */
if (current_message.rx_data[0] != 0U && !FOC.is_shut_down) {
motor_resume();
}
FOC.control_mode = current_message.rx_data[0];
FOC.limit_voltage = float(unpack_bytes_to_u16(current_message.rx_data, 1)) / 1000;
target_current_union.f = unpack_bytes_to_float(current_message.rx_data, 3).f;