Files
Motor_v2/Robot_V2/sys/run_inhibit.h
T
cbb 86ca7666fa feat(motor): 引入运行禁止机制重构电机控制安全系统
- 添加 run_inhibit.h/cpp 模块作为全局运行闸门,统一管理所有停机/唤醒逻辑
- 移除 FOC 控制器中的 5 个相互引用的开关机函数(shut_down/resume 等)
- 将 nFAULT 硬件故障检测从仅上报改为运行门控制,连续采样故障时申请禁止位
- 改进电压检测逻辑,欠压判定现在通过 run_inhibit 统一执行停机动作
- 修正 PB2(nFAULT) 引脚配置为内部上拉输入,避免浮空误读导致系统锁死
- 在 CAN 状态帧中新增 RunInhibit 位图(字节 36-39),实时反映禁止运行的故障源
- 电流采样失效、过热故障现在通过禁止位管理而非直接操作驱动状态
- 校准函数增加运行许可检查,防止在停机状态下意外唤醒驱动
2026-10-13 00:47:52 +08:00

78 lines
2.9 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/run_inhibit.h
* @brief 电机"禁止运行"闸门:唯一有权决定桥臂能不能输出的模块。
* @note 分层约定(新增故障必须照此办,不要在检测处写停机动作):
* - 故障检测方 只调 request(来源位) —— 申请禁止,不碰 PWM/使能脚
* - 故障解除方 只调 release(来源位) —— 撤销自己的申请,不查别人的位
* - 功率级动作 只发生在本模块 update() —— 由 50us 控制任务驱动
* 因此任何一处都不需要知道其它故障源的存在;"能不能运行"= 位图是否为空。
*/
#ifndef _RUN_INHIBIT_H
#define _RUN_INHIBIT_H
#include "config.h"
/**
* @brief 禁止来源位图(每一位一个独立申请方,可并存)
*/
enum InhibitSource : u32 {
INHIBIT_DRV_NFAULT = 1u << 0, // 门驱动 nFAULT(PB2) 有效:UVLO/热关断/OCP 锁存
INHIBIT_UNDERVOLTAGE = 1u << 1, // 母线跌幅超阈值或低于绝对下限
INHIBIT_THERMAL = 1u << 2, // 热模型过热(含温度采集正常时的电流热积累)
INHIBIT_ISENSE_FAIL = 1u << 3, // 三相电流采样持续失效(原先被并入"过热"上报)
// 上位机还没下发过非零模式:保持驱动睡眠。这不是故障,而是"未被使能",
// 放在同一张位图里是为了让功率级只有一个执行者。老板 v2 的 EN 有 10k 下拉、
// DRV8313 上电默认睡眠;若上电即唤醒,模式 0(drv_hold 恒 10% 占空比锁止)
// 会立刻给 A 相通流发热,而"上电先发模式 0 当静止待机"是现有上位机行为。
INHIBIT_NOT_ENABLED = 1u << 7,
};
/**
* @brief RunInhibit 类:禁止运行闸门
*/
class RunInhibit {
// 上电即禁止:等上位机首次下发非零模式解除(见 INHIBIT_NOT_ENABLED)
u32 bits = INHIBIT_NOT_ENABLED;
bool stopped = false; // 上一拍是否已施加停机(避免每 50us 重复翻转使能脚)
u8 wake_ticks = 0; // 唤醒建立倒计时(50us 节拍)
public:
/**
* @brief 申请禁止(幂等;同一位重复申请无副作用)
* @param[in] src InhibitSource 位
* @return void
*/
void request(u32 src);
/**
* @brief 撤销本来源的禁止申请;位图清空后才允许运行
* @param[in] src InhibitSource 位
* @return void
*/
void release(u32 src);
/**
* @brief 是否允许运行(只看位图,不看唤醒状态)
* @return bool true=允许
*/
bool permitted() const { return bits == 0U; }
/**
* @brief 允许运行且驱动唤醒建立已完成,控制函数可派发
* @return bool true=可派发
*/
bool ready() const { return bits == 0U && wake_ticks == 0U; }
/**
* @brief 当前禁止来源位图(上报/诊断用)
* @return u32 位图
*/
u32 sources() const { return bits; }
/**
* @brief 执行闸门:50us 控制任务每拍调用,唯一碰 PWM 与驱动使能的地方
* @return void
*/
void update(void);
};
extern RunInhibit run_inhibit;
#endif