Doxygen 在嵌入式软件开发中的深度应用(中):从基础到无人机电调 / 汽车 FOC 控制器实战

_speed 目标转速(单位:rpm)

  • @return 设置结果
  • @retval 0:设置成功
  • @retval -1:参数错误(motor 为 NULL,target_speed 小于 0 或超过最大转速)
  • @retval -2:电机未初始化或未运行
  • @note 1. 目标转速支持动态调整,调整时 PID 控制器会自动平滑过渡,避免转速突变;
    1. 若目标转速超过电机最大转速(KV 值 × 电压 ×60/(2π)),将自动限制为最大转速;
    1. 建议调整转速时采用阶梯式递增 / 递减,每次调整幅度不超过 500rpm,避免电流冲击*/int32_t drv_motor_set_target_speed (DrvMotorHandleType *motor, uint32_t target_speed);

/*!

  • @brief 获取电机运行状态
  • @param [in] motor 电机驱动句柄指针
  • @param [out] speed 实际转速(单位:rpm),可为 NULL(不获取)
  • @param [out] current 平均相电流(单位:A),可为 NULL(不获取)
  • @param [out] pos 转子位置(单位:°),可为 NULL(不获取)
  • @return 获取结果
  • @retval 0:获取成功
  • @retval -1:参数错误(motor 为 NULL)
  • @retval -2:电机未初始化
  • @note 该函数为非阻塞函数,可在主循环中周期性调用,用于状态监控和调试*/int32_t drv_motor_get_state (DrvMotorHandleType *motor, uint32_t *speed, float *current, float *pos);

/*!

  • @brief 电机故障检测与处理
  • @param [in,out] motor 电机驱动句柄指针
  • @return 故障状态
  • @retval 0:无故障
  • @retval DRV_MOTOR_ERR_OVER_CURRENT:过流故障
  • @retval DRV_MOTOR_ERR_OVER_TEMP:过温故障
  • @retval DRV_MOTOR_ERR_UNDER_VOLTAGE:欠压故障
  • @retval DRV_MOTOR_ERR_POS_DETECT:位置检测故障
  • @retval DRV_MOTOR_ERR_PWM:PWM 输出故障
  • @note 1. 该函数会实时检测电流、温度、电压、位置信号,发现故障后自动停止电机;
    1. 故障发生后,需调用 drv_motor_clear_error () 清除故障状态,才能重新启动电机*/uint32_t drv_motor_detect_error (DrvMotorHandleType *motor);

/*!

  • @brief 清除电机故障状态
  • @param [in,out] motor 电机驱动句柄指针
  • @return 清除结果
  • @retval 0:清除成功
  • @retval -1:参数错误(motor 为 NULL)
  • @retval -2:电机未初始化*/int32_t drv_motor_clear_error (DrvMotorHandleType *motor);

/*!

  • @brief 电机参数重新配置
  • @param [in,out] motor 电机驱动句柄指针
  • @param [in] config 新的电机配置结构体指针
  • @return 配置结果
  • @retval 0:配置成功
  • @retval -1:参数错误(motor 为 NULL 或 config 为 NULL)
  • @retval -2:电机运行中(需先停止电机)
  • @retval -3:配置参数非法
  • @note 重新配置后,需重新执行转子位置校准*/int32_t drv_motor_reconfig (DrvMotorHandleType *motor, const DrvMotorConfigType *config);

/*! @} */ // 结束 DRV_MOTOR 模块

#endif // DRV_MOTOR_H

plaintext


#### 4.2.3 算法层(ALG)核心模块:FOC控制算法
```c
/*!
 * @file alg_foc.h
 * @brief 磁场定向控制(FOC)算法模块
 * @author Wang Wu
 * @date 2025-12-04
 * @version V1.0.0
 * @details 实现无刷电机FOC控制的核心算法,包括Clark变换、Park变换、逆Park变换、
 *          SVPWM调制、转子位置估算等功能,支持有感和无感两种控制模式,
 *          本项目用于无人机电调的高精度转速和转矩控制
 * @note 1. FOC算法需周期性执行,推荐执行频率10kHz(与电流采样频率同步);
 *       2. 有感模式依赖编码器/霍尔传感器的位置信号,无感模式通过反电动势估算位置;
 *       3. 变换矩阵采用静止坐标系(αβ)和旋转坐标系(dq),默认d轴对齐转子磁链
 */

#ifndef ALG_FOC_H
#define ALG_FOC_H

#include "stdint.h"
#include "math.h"

/*!
 * @defgroup ALG_FOC FOC控制算法模块
 * @brief 磁场定向控制核心算法,含坐标变换、SVPWM调制
 * @ingroup ALG
 * @{
 */

/*!
 * @brief FOC控制模式枚举
 */
typedef enum {
    ALG_FOC_MODE_SENSOR,    /*!< 有感FOC模式(依赖位置传感器) */
    ALG_FOC_MODE_SENSORLESS /*!< 无感FOC模式(反电动势估算位置) */
} AlgFocModeType;

/*!
 * @brief 三相电流结构体(ABC坐标系)
 */
typedef struct {
    float a; /*!< A相电流(单位:A) */
    float b; /*!< B相电流(单位:A) */
    float c; /*!< C相电流(单位:A) */
} AlgFocAbcCurrType;

/*!
 * @brief 两相电流结构体(αβ静止坐标系)
 */
typedef struct {
    float alpha; /*!< α轴电流(单位:A) */
    float beta;  /*!< β轴电流(单位:A) */
} AlgFocAlphaBetaCurrType;

/*!
 * @brief 两相电流结构体(dq旋转坐标系)
 */
typedef struct {
    float d; /*!< d轴电流(单位:A)- 励磁电流 */
    float q; /*!< q轴电流(单位:A)- 转矩电流 */
} AlgFocDqCurrType;

/*!
 * @brief 两相电压结构体(dq旋转坐标系)
 */
typedef struct {
    float d; /*!< d轴电压(单位:V) */
    float q; /*!< q轴电压(单位:V) */
} AlgFocDqVoltType;

/*!
 * @brief SVPWM输出结构体(占空比)
 */
typedef struct {
    float a; /*!< A相占空比(‰) */
    float b; /*!< B相占空比(‰) */
    float c; /*!< C相占空比(‰) */
} AlgFocSvpwmDutyType;

/*!
 * @brief FOC算法句柄结构体
 */
typedef struct {
    AlgFocModeType mode;          /*!< FOC控制模式 */
    float rotor_pos;              /*!< 转子位置(单位:rad)- 输入/输出 */
    float rotor_speed;            /*!< 转子转速(单位:rad/s)- 输入/输出 */
    AlgFocAbcCurrType abc_curr;   /*!< ABC坐标系电流 - 输入 */
    AlgFocDqCurrType dq_curr;     /*!< dq坐标系电流 - 输出 */
    AlgFocDqVoltType dq_volt_ref; /*!< dq坐标系参考电压 - 输入 */
    AlgFocSvpwmDutyType svpwm_duty; /*!< SVPWM占空比 - 输出 */
    float u_dc;                   /*!< 直流母线电压(单位:V)- 输入 */
    float theta;                  /*!< dq坐标系电角度(单位:rad)= 转子机械角×极对数 */
    uint8_t pole_pairs;           /*!< 电机极对数(本项目电机为4对极) */
} AlgFocHandleType;

/*!
 * @brief FOC算法初始化
 * @param[in,out] foc FOC算法句柄指针
 * @param[in] mode FOC控制模式
 * @param[in] pole_pairs 电机极对数
 * @param[in] u_dc 直流母线电压(单位:V)
 * @return 初始化结果
 * @retval 0:初始化成功
 * @retval -1:参数错误(foc为NULL,pole_pairs为0,u_dc小于10V)
 * @note 1. 电机极对数需根据实际电机参数配置(本项目无人机电调电机为4对极);
 *       2. 直流母线电压需通过ADC实时采样更新,建议每1ms更新一次
 */
int32_t alg_foc_init(AlgFocHandleType *foc, AlgFocModeType mode, uint8_t pole_pairs, float u_dc);

/*!
 * @brief Clark变换(ABC→αβ)
 * @param[in] abc_curr ABC坐标系电流
 * @param[out] alpha_beta_curr αβ坐标系电流
 * @details Clark变换是将三相静止坐标系(ABC)的电流转换为两相静止坐标系(αβ)的电流,
 *          消除三相电流的耦合关系,变换公式如下:
 *          α = (2/3)×(A - 0.5×B - 0.5×C)
 *          β = (2/3)×(√3/2×B - √3/2×C)
 *          由于三相电流之和为0(A+B+C=0),可简化为:
 *          α = (2/3)×A - (1/3)×B - (1/3)×C
 *          β = (1/√3)×B - (1/√3)×C
 * @note 该函数为纯数学运算,无硬件依赖,可在任意位置调用
 */
void alg_foc_clark_transform(const AlgFocAbcCurrType *abc_curr, AlgFocAlphaBetaCurrType *alpha_beta_curr);

/*!
 * @brief Park变换(αβ→dq)
 * @param[in] alpha_beta_curr αβ坐标系电流
 * @param[in] theta dq坐标系电角度(单位:rad)
 * @param[out] dq_curr dq坐标系电流
 * @details Park变换是将两相静止坐标系(αβ)的电流转换为两相旋转坐标系(dq)的电流,
 *          旋转坐标系与转子磁链同步旋转,实现电流的解耦控制,变换公式如下:
 *          d = α×cosθ + β×sinθ
 *          q = -α×sinθ + β×cosθ
 * @note 1. 电角度θ = 转子机械角×极对数 + 初始偏置角(校准后确定);
 *       2. 为提高运算效率,可提前计算cosθ和sinθ,避免重复计算
 */
void alg_foc_park_transform(const AlgFocAlphaBetaCurrType *alpha_beta_curr, float theta, AlgFocDqCurrType *dq_curr);

/*!
 * @brief 逆Park变换(dq→αβ)
 * @param[in] dq_volt dq坐标系电压
 * @param[in] theta dq坐标系电角度(单位:rad)
 * @param[out] alpha_beta_volt αβ坐标系电压
 * @details 逆Park变换是Park变换的逆运算,将dq坐标系的参考电压转换为αβ坐标系的电压,
 *          为SVPWM调制提供输入,变换公式如下:
 *          α = d×cosθ - q×sinθ
 *          β = d×sinθ + q×cosθ
 * @note 参考电压需根据直流母线电压进行限幅,避免SVPWM调制过调制
 */
void alg_foc_inv_park_transform(const AlgFocDqVoltType *dq_volt, float theta, AlgFocAlphaBetaCurrType *alpha_beta_volt);

/*!
 * @brief SVPWM调制(αβ→PWM占空比)
 * @param[in] alpha_beta_volt αβ坐标系电压
 * @param[in] u_dc 直流母线电压(单位:V)
 * @param[out] svpwm_duty SVPWM占空比(‰)
 * @details 空间矢量脉宽调制(SVPWM)通过控制三相桥臂的开关状态,生成逼近圆形的旋转磁场,
 *          相比传统SPWM调制,电压利用率提高15.47%,具体实现步骤如下:
 *          1. 计算电压空间矢量的扇区;
 *          2. 计算相邻基本矢量的作用时间;
 *          3. 计算各相桥臂的开关时间;
 *          4. 转换为占空比(0-1000‰)
 * @note 1. 占空比输出范围为0-1000‰,对应PWM的0%-100%;
 *       2. 若参考电压超出六边形调制范围,将自动进行过调制处理,避免电压畸变;
 *       3. 直流母线电压波动会影响调制精度,需实时采样更新u_dc
 */
void alg_foc_svpwm_modulate(const AlgFocAlphaBetaCurrType *alpha_beta_volt, float u_dc, AlgFocSvpwmDutyType *svpwm_duty);

/*!
 * @brief 无感FOC转子位置估算(反电动势法)
 * @param[in,out] foc FOC算法句柄指针
 * @param[in] alpha_beta_curr αβ坐标系电流
 * @param[in] alpha_beta_volt αβ坐标系电压
 * @details 基于反电动势的位置估算原理:无刷电机转子旋转时会产生反电动势,反电动势的相位
 *          超前转子磁链90°,通过检测反电动势的过零点或积分运算,可估算转子位置,具体步骤如下:
 *          1. 计算αβ坐标系的反电动势:eα = uα - R×iα - L×diα/dt,eβ = uβ - R×iβ - L×diβ/dt;
 *          2. 反电动势积分得到磁链:ψα = ∫eαdt,ψβ = ∫eβdt;
 *          3. 转子位置θ = arctan2(ψβ, ψα);
 *          4. 一阶低通滤波平滑位置信号,避免噪声干扰
 * @note 1. 该函数仅在无感模式(ALG_FOC_MODE_SENSORLESS)下有效;
 *       2. 低速时反电动势微弱,估算精度较低,需结合启动算法(如三段式启动);
 *       3. 电机相电阻R和相电感L需通过实验校准,否则会影响估算精度
 */
void alg_foc_sensorless_pos_est(AlgFocHandleType *foc, const AlgFocAlphaBetaCurrType *alpha_beta_curr, const AlgFocAlphaBetaCurrType *alpha_beta_volt);

/*!
 * @brief FOC算法主函数(周期调用)
 * @param[in,out] foc FOC算法句柄指针
 * @return 执行结果
 * @retval 0:执行成功
 * @retval -1:参数错误(foc为NULL)
 * @retval -2:未初始化
 * @details FOC算法主流程:
 *          1. 读取三相电流(abc_curr)和直流母线电压(u_dc);
 *          2. Clark变换:ABC→αβ;
 *          3. 若为有感模式,读取转子位置计算电角度θ;若为无感模式,调用位置估算函数;
 *          4. Park变换:αβ→dq,得到d/q轴电流(dq_curr);
 *          5. 电流环PID控制:根据参考d/q轴电流和实际d/q轴电流,计算参考d/q轴电压(dq_volt_ref);
 *          6. 逆Park变换:dq→αβ;
 *          7. SVPWM调制:αβ→PWM占空比(svpwm_duty);
 *          8. 输出占空比到PWM驱动模块
 * @warning 该函数必须周期性调用,调用周期需严格一致(推荐100μs,即10kHz),否则会导致控制不稳定
 */
int32_t alg_foc_main(AlgFocHandleType *foc);

/*! @} */  // 结束ALG_FOC模块

#endif  // ALG_FOC_H
4.2.4 应用层(APP)核心模块:电调控制管理

c

运行

/*!
 * @file app_esc.h
 * @brief 无人机电调应用层控制模块
 * @author Zhao Liu
 * @date 2025-12-04
 * @version V1.0.0
 * @details 实现无人机电调的整体控制逻辑,包括控制模式切换、参数配置、故障诊断、
 *          与飞控/上位机的通信交互等功能,是电调的核心应用层模块
 * @note 1. 电调支持三种控制模式:PWM模式、CAN模式、UART模式,默认启动为PWM模式;
 *       2. 所有参数配置支持掉电保存(存储在片内Flash);
 *       3. 故障发生时,电调会立即停止电机,并通过CAN/UART上报故障信息
 */

#ifndef APP_ESC_H
#define APP_ESC_H

#include "drv_motor.h"
#include "proto_can.h"
#include "proto_uart.h"
#include "hal_flash.h"

/*!
 * @defgroup APP_ESC 电调控制管理模块
 * @brief 电调应用层核心逻辑,含控制模式、参数配置、故障诊断
 * @ingroup APP
 * @{
 */

/*!
 * @brief 电调控制模式枚举
 */
typedef enum {
    APP_ESC_MODE_PWM,   /*!< PWM控制模式(飞控标准PWM信号,50Hz-400Hz) */
    APP_ESC_MODE_CAN,   /*!< CAN控制模式(CAN 2.0B,波特率500kbps) */
    APP_ESC_MODE_UART,  /*!< UART控制模式(波特率115200bps,8N1) */
    APP_ESC_MODE_MAX    /*!< 控制模式数量 */
} AppEscModeType;

/*!
 * @brief 电调故障码枚举
 */
typedef enum {
    APP_ESC_ERR_NONE = 0,          /*!< 无故障 */
    APP_ESC_ERR_OVER_CURRENT = 1,  /*!< 过流故障(相电流超过峰值电流60A) */
    APP_ESC_ERR_OVER_TEMP = 2,     /*!< 过温故障(MOS管温度超过120℃) */
    APP_ESC_ERR_UNDER_VOLTAGE = 3, /*!< 欠压故障(母线电压低于10V) */
    APP_ESC_ERR_OVER_VOLTAGE = 4,  /*!< 过压故障(母线电压高于26V) */
    APP_ESC_ERR_POS_DETECT = 5,    /*!< 位置检测故障(编码器无信号/反电动势估算失败) */
    APP_ESC_ERR_MOTOR_CALIB = 6,   /*!< 电机校准故障(校准超时/相序错误) */
    APP_ESC_ERR_COMM = 7,          /*!< 通信故障(CAN/UART无响应超过1s) */
    APP_ESC_ERR_FLASH = 8,         /*!< Flash存储故障(参数保存失败) */
    APP_ESC_ERR_PWM = 9,           /*!< PWM输出故障(PWM信号异常) */
    APP_ESC_ERR_MAX = 10           /*!< 故障码数量 */
} AppEscErrCodeType;

/*!
 * @brief 电调参数配置结构体
 */
typedef struct {
    AppEscModeType ctrl_mode;      /*!< 控制模式 */
    uint32_t pwm_min_width;        /*!< PWM最小脉宽(μs),默认1000μs */
    uint32_t pwm_max_width;        /*!< PWM最大脉宽(μs),默认2000μs */
    uint32_t max_speed;            /*!< 最大转速(rpm),默认9600rpm(400KV×24V) */
    uint16_t over_current_thr;     /*!< 过流阈值(A),默认60A */
    uint16_t over_temp_thr;        /*!< 过温阈值(℃),默认120℃ */
    uint16_t under_voltage_thr;    /*!< 欠压阈值(V),默认10V */
    uint16_t over_voltage_thr;     /*!< 过压阈值(V),默认26V */
    uint8_t can_id;                /*!< CAN设备ID,默认0x01 */
    uint8_t comm_timeout;          /*!< 通信超时时间(s),默认1s */
} AppEscParamType;

/*!
 * @brief 电调状态结构体
 */
typedef struct {
    AppEscModeType curr_mode;      /*!< 当前控制模式 */
    AppEscErrCodeType err_code;    /*!< 当前故障码 */
    uint32_t motor_speed;          /*!< 电机实际转速(rpm) */
    float motor_current;           /*!< 电机平均相电流(A) */
    float bus_voltage;             /*!< 直流母线电压(V) */
    float mos_temp;                /*!< MOS管温度(℃) */
    uint8_t motor_state;           /*!< 电机状态:0-停止,1-运行,2-故障 */
    uint32_t runtime;              /*!< 运行时间(s) */
} AppEscStatusType;

/*!
 * @brief 电调句柄结构体
 */
typedef struct {
    DrvMotorHandleType motor;      /*!< 电机驱动句柄 */
    AlgFocHandleType foc;          /*!< FOC算法句柄 */
    AppEscParamType param;         /*!< 电调参数配置 */
    AppEscStatusType status;       /*!< 电调状态 */
    ProtoCanHandleType can;        /*!< CAN通信句柄 */
    ProtoUartHandleType uart;      /*!< UART通信句柄 */
    uint32_t tick;                 /*!< 系统滴答计数器(ms) */
    uint32_t comm_tick;            /*!< 通信超时计数器(ms) */
} AppEscHandleType;

/*!
 * @brief 电调初始化
 * @param[in,out] esc 电调句柄指针
 * @return 初始化结果
 * @retval 0:初始化成功
 * @retval -1:参数错误(esc为NULL)
 * @retval -2:电机驱动初始化失败
 * @retval -3:FOC算法初始化失败
 * @retval -4:通信模块初始化失败
 * @retval -5:Flash参数读取失败(将使用默认参数)
 * @details 电调初始化流程:
 *          1. 初始化系统滴答定时器(1ms中断);
 *          2. 读取Flash中保存的电调参数,若读取失败则加载默认参数;
 *          3. 初始化CAN/UART通信模块;
 *          4. 初始化电机驱动模块(drv_motor_init);
 *          5. 初始化FOC算法模块(alg_foc_init);
 *          6. 初始化故障诊断模块,清除历史故障;
 *          7. 设置电调初始状态为“停止”
 * @note 初始化完成后,电调进入待机状态,等待控制信号启动电机
 */
int32_t app_esc_init(AppEscHandleType *esc);

/*!
 * @brief 电调控制模式切换
 * @param[in,out] esc 电调句柄指针
 * @param[in] mode 目标控制模式
 * @return 切换结果
 * @retval 0:切换成功
 * @retval -1:参数错误(esc为NULL或mode非法)
 * @retval -2:电调未初始化
 * @retval -3:电机运行中(需先停止电机)
 * @retval -4:目标模式通信模块初始化失败
 * @note 1. 模式切换后,新配置将立即生效,但不会自动保存到Flash,需调用app_esc_save_param()保存;
 *       2. 切换到CAN/UART模式时,会自动初始化对应的通信模块,波特率等参数使用默认配置;
 *       3. 切换到PWM模式时,会自动配置PWM输入捕获通道(定时器2通道1)
 */
int32_t app_esc_switch_mode(AppEscHandleType *esc, AppEscModeType mode);

/*!
 * @brief 电调参数配置
 * @param[in,out] esc 电调句柄指针
 * @param[in] param 新的参数配置结构体
 * @return 配置结果
 * @retval 0:配置成功
 * @retval -1:参数错误(esc为NULL或param参数非法)
 * @retval -2:电调未初始化
 * @retval -3:电机运行中(需先停止电机)
 * @note 1. 参数配置后需调用app_esc_save_param()才能掉电保存;
 *       2. 参数合法性检查规则:
 *          - PWM脉宽:min_width 800-1200μs,max_width 1800-2200μs,且max_width > min_width;
 *          - 最大转速:1000-15000rpm;
 *          - 过流阈值:40-80A;
 *          - 过温阈值:100-150℃;
 *          - 电压阈值:欠压8-12V,过压24-30V,且过压阈值 > 欠压阈值;
 *          - CAN ID:0x01-0xFF;
 *          - 通信超时:0-5s(0表示禁用超时检测)
 */
int32_t app_esc_set_param(AppEscHandleType *esc, const AppEscParamType *param);

/*!
 * @brief 保存电调参数到Flash
 * @param[in,out] esc 电调句柄指针
 * @return 保存结果
 * @retval 0:保存成功
 * @retval -1:参数错误(esc为NULL)
 * @retval -2:电调未初始化
 * @retval -3:Flash写入失败
 * @note 1. 参数保存到片内Flash的用户扇区(STM32H743为扇区4,地址0x08020000);
 *       2. Flash写入次数有限(约10万次),避免频繁调用该函数;
 *       3. 保存过程中会禁用中断,避免干扰,耗时约10ms,期间电调暂停控制
 */
int32_t app_esc_save_param(AppEscHandleType *esc);

/*!
 * @brief 获取电调状态
 * @param[in] esc 电调句柄指针
 * @param[out] status 电调状态结构体指针
 * @return 获取结果
 * @retval 0:获取成功
 * @retval -1:参数错误(esc为NULL或status为NULL)
 * @retval -2:电调未初始化
 * @note 该函数为非阻塞函数,可在上位机通信中周期性调用,用于状态监控
 */
int32_t app_esc_get_status(const AppEscHandleType *esc, AppEscStatusType *status);

/*!
 * @brief 电调主循环(核心函数)
 * @param[in,out] esc 电调句柄指针
 * @return 执行结果
 * @retval 0:循环正常执行
 * @retval -1:参数错误(esc为NULL)
 * @retval -2:电调未初始化
 * @details 电调主循环流程(建议1ms调用一次):
 *          1. 状态更新:读取母线电压、电机电流、MOS管温度、电机转速等数据;
 *          2. 故障检测:调用drv_motor_detect_error()检测电机故障,调用通信模块故障检测;
 *          3. 故障处理:若检测到故障,停止电机,更新故障码,上报故障信息;
 *          4. 控制信号解析:根据当前控制模式,解析飞控/上位机的控制信号(转速指令);
 *          5. 电机控制:若控制信号有效,调用drv_motor_set_target_speed()设置转速,执行FOC算法;
 *          6. 通信交互:上报电调状态、故障信息到飞控/上位机;
 *          7. 超时检测:若通信模式下无控制信号,触发通信超时故障
 * @warning 该函数必须在主循环中持续调用,若中断会导致电机控制失效,建议通过RTOS任务调用(优先级高于其他任务)
 */
int32_t app_esc_main_loop(AppEscHandleType *esc);

/*!
 * @brief 电调故障处理函数(外部中断调用)
 * @param[in,out] esc 电调句柄指针
 * @param[in] err_code 故障码
 * @details 故障处理流程:
 *          1. 停止电机(drv_motor_stop);
 *          2. 关闭PWM输出;
 *          3. 更新电调状态和故障码;
 *          4. 通过CAN/UART上报故障信息(包含故障码、发生时间、当前状态参数);
 *          5. 若为严重故障(如过流、过温),触发硬件保护(切断MOS管电源)
 * @note 该函数可由外部中断(如过流中断、过温中断)直接调用,也可在主循环中调用
 */
void app_esc_error_handler(AppEscHandleType *esc, AppEscErrCodeType err_code);

/*!
 * @brief 电调恢复出厂设置
 * @param[in,out] esc 电调句柄指针
 * @return 恢复结果
 * @retval 0:恢复成功
 * @retval -1:参数错误(esc为NULL)
 * @retval -2:电调未初始化
 * @retval -3:电机运行中(需先停止电机)
 * @retval -4:Flash擦除失败
 * @details 恢复出厂设置流程:
 *          1. 停止电机,关闭所有外设;
 *          2. 擦除Flash中保存的用户参数;
 *          3. 加载默认参数配置;
 *          4. 重置电调状态,清除故障码;
 *          5. 重新初始化通信模块和控制模块
 * @warning 恢复出厂设置后,所有用户配置的参数将丢失,需重新校准电机和配置参数
 */
int32_t app_esc_restore_factory(AppEscHandleType *esc);

/*! @} */  // 结束APP_ESC模块

#endif  // APP_ESC_H

4.3 无人机电调项目 Doxygen 配置文件(完整优化版)

plaintext

# 无人机电调项目Doxygen配置文件
# 配置文件版本:Doxyfile 1.11.0
# 生成日期:2025-12-04
# 项目名称
PROJECT_NAME           = "无人机电调V2.0"
PROJECT_NUMBER         = "V2.0.0"
PROJECT_BRIEF          = "基于STM32H743的400KV无刷电机FOC电调,支持PWM/CAN/UART控制"
PROJECT_LOGO           = doc/logo.png  # 项目Logo(可选)
OUTPUT_DIRECTORY       = doc/  # 文档输出根目录
CREATE_SUBDIRS         = NO  # 不创建子目录
OUTPUT_LANGUAGE        = Chinese  # 输出文档语言
BRIEF_MEMBER_DESC      = YES  # 显示成员简要描述
REPEAT_BRIEF           = YES  # 在详细描述中重复简要描述
ABBREVIATE_BRIEF       = "The $name class" \
                         "The $name widget" \
                         "The $name file" \
                         is \
                         provides \
                         specifies \
                         contains \
                         represents \
                         a \
                         an \
                         the
ALWAYS_DETAILED_SEC    = NO  # 不强制显示详细描述 section
INLINE_INHERITED_MEMB  = NO  # 不显示继承成员的内联描述
FULL_PATH_NAMES        = YES  # 显示文件的完整路径
STRIP_FROM_PATH        = src/ inc/  # 从路径中剥离的前缀
STRIP_FROM_INC_PATH    = inc/  # 从包含路径中剥离的前缀
SHORT_NAMES            = NO  # 不使用短文件名
JAVADOC_AUTOBRIEF      = NO  # 不启用Javadoc风格的自动简要描述
JAVADOC_BANNER         = NO  # 不显示Javadoc banner
QT_AUTOBRIEF           = NO  # 不启用Qt风格的自动简要描述
MULTILINE_CPP_IS_BRIEF = NO  # 多行C++注释不视为简要描述
INHERIT_DOCS           = YES  # 继承父类/接口的文档
SEPARATE_MEMBER_PAGES  = NO  # 不为每个成员单独生成页面
TAB_SIZE               = 4  # 制表符宽度
ALIASES                =  # 自定义别名(无)
OPTIMIZE_OUTPUT_FOR_C  = YES  # 优化C语言输出
OPTIMIZE_OUTPUT_JAVA   = NO  # 不优化Java输出
OPTIMIZE_FOR_FORTRAN   = NO  # 不优化Fortran输出
OPTIMIZE_OUTPUT_VHDL   = NO  # 不优化VHDL输出
OPTIMIZE_OUTPUT_SLICE  = NO  # 不优化Slice输出
EXTENSION_MAPPING      = .s=C .asm=C  # 汇编文件映射为C语言
MARKDOWN_SUPPORT       = YES  # 支持Markdown
TOC_INCLUDE_HEADINGS   = 5  # TOC包含的标题层级
AUTOLINK_SUPPORT       = YES  # 自动链接支持
BUILTIN_STL_SUPPORT    = NO  # 不支持STL
CPP_CLI_SUPPORT        = NO  # 不支持C++/CLI
SIP_SUPPORT            = NO  # 不支持SIP
IDL_PROPERTY_SUPPORT   = YES  # 支持IDL属性
DISTRIBUTE_GROUP_DOC   = YES  # 分布式组文档
GROUP_NESTED_COMPOUNDS = YES  # 分组嵌套化合物
SUBGROUPING            = YES  # 子分组支持
INLINE_GROUPED_CLASSES = NO  # 不内联分组类
INLINE_SIMPLE_STRUCTS  = NO  # 不内联简单结构体
TYPEDEF_HIDES_STRUCT   = NO  # Typedef不隐藏结构体
LOOKUP_CACHE_SIZE      = 0  # 查找缓存大小(0表示无限制)

# 源码路径配置
INPUT                  = src/ inc/ doc/README.md  # 源码目录和README文件
INPUT_ENCODING         = UTF-8  # 输入文件编码
FILE_PATTERNS          = *.c *.h *.cpp *.hpp *.s *.asm *.md  # 待处理文件后缀
RECURSIVE              = YES  # 递归扫描目录
EXCLUDE                = src/test/ inc/test/ build/ obj/ bin/  # 排除目录
EXCLUDE_SYMLINKS       = NO  # 不排除符号链接
EXCLUDE_PATTERNS       = *test* *mock* *demo*  # 排除文件模式
EXCLUDE_SYMBOLS        =  # 排除符号(无)
EXAMPLE_PATH           = example/  # 示例代码目录(可选)
EXAMPLE_PATTERNS       = *.c *.h *.cpp *.hpp *.md  # 示例文件后缀
EXAMPLE_RECURSIVE      = YES  # 递归扫描示例目录
IMAGE_PATH             = doc/images/  # 图片路径(用于文档中的图片引用)
INPUT_FILTER           =  # 输入过滤(无)
FILTER_PATHS           =  # 过滤路径(无)
FILTER_PATTERNS        =  # 过滤模式(无)
FILTER_SOURCE_FILES    = NO  # 不过滤源文件
FILTER_SOURCE_PATHS    = NO  # 不过滤源文件路径

# 文档输出配置
GENERATE_HTML          = YES  # 生成HTML文档
HTML_OUTPUT            = html  # HTML输出目录
HTML_FILE_EXTENSION    = .html  # HTML文件后缀
HTML_HEADER            = doc/template/header.html  # 自定义HTML头部(可选)
HTML_FOOTER            = doc/template/footer.html  # 自定义HTML底部(可选)
HTML_STYLESHEET        = doc/template/custom.css  # 自定义CSS样式(可选)
HTML_EXTRA_STYLESHEET  =  # 额外CSS样式(无)
HTML_EXTRA_FILES       =  # 额外HTML文件(无)
HTML_COLORSTYLE_HUE    = 220  # HTML颜色风格色调
HTML_COLORSTYLE_SAT    = 100  # 饱和度
HTML_COLORSTYLE_GAMMA  = 80  # 伽马值
HTML_TIMESTAMP         = YES  # 显示生成时间戳
HTML_DYNAMIC_SECTIONS  = NO  # 不启用动态章节
HTML_CODE_HIGHLIGHTING = YES  # 启用代码高亮
HTML_BRIEF_LINK_TEXT   = "详细描述"
HTML_TAGS              =  # 自定义HTML标签(无)
GENERATE_HTMLHELP      = NO  # 不生成HTML Help文档
GENERATE_CHM           = NO  # 不生成CHM文档
GENERATE_QHP           = NO  # 不生成QHP文档
QHP_NAMESPACE          = org.doxygen.Project  # QHP命名空间(无)
QHP_VIRTUAL_FOLDER     = doc  # QHP虚拟文件夹(无)
QHP_CUST_FILTER_NAME   =  # 自定义QHP过滤器名称(无)
QHP_CUST_FILTER_ATTRS  =  # 自定义QHP过滤器属性(无)
QHP_SECT_FILTER_ATTRS  =  # 章节过滤器属性(无)
QHG_LOCATION           =  # QHG位置(无)
GENERATE_ECLIPSEHELP   = NO  # 不生成Eclipse Help文档
ECLIPSE_DOC_ID         = org.doxygen.Project  # Eclipse文档ID(无)
GENERATE_JAVADOC_TAGFILE=  # 不生成Javadoc标签文件
JAVADOC_BASENAME       =  # Javadoc基名(无)
GENERATE_LATEX         = NO  # 不生成LaTeX文档
LATEX_OUTPUT           = latex  # LaTeX输出目录(无)
LATEX_CMD_NAME         = latex  # LaTeX命令名称(无)
MAKEINDEX_CMD_NAME     = makeindex  # Makeindex命令名称(无)
COMPACT_LATEX          = NO  # 不生成紧凑LaTeX文档
PAPER_TYPE             = a4wide  # 纸张类型(无)
EXTRA_PACKAGES         =  # 额外LaTeX包(无)
LATEX_HEADER           =  # LaTeX头部(无)
LATEX_FOOTER           =  # LaTeX底部(无)
LATEX_EXTRA_STYLESHEET =  # 额外LaTeX样式表(无)
LATEX_EXTRA_FILES      =  # 额外LaTeX文件(无)
PDF_HYPERLINKS         = YES  # PDF超链接(无)
USE_PDFLATEX           = YES  # 使用PDFLaTeX(无)
LATEX_BATCHMODE        = NO  # 不启用LaTeX批处理模式
LATEX_MACROS           =  # LaTeX宏(无)
PDF_HYPERLINKS         = YES  # PDF超链接(无)
USE_PDFLATEX           = YES  # 使用PDFLaTeX(无)
LATEX_BATCHMODE        = NO  # 不启用LaTeX批处理模式
LATEX_MACROS           =  # LaTeX宏(无)
GENERATE_RTF           = NO  # 不生成RTF文档
RTF_OUTPUT             = rtf  # RTF输出目录(无)
COMPACT_RTF            = NO  # 不生成紧凑RTF文档
RTF_HYPERLINKS         = NO  # 不启用RTF超链接
RTF_STYLESHEET_FILE    =  # RTF样式表文件(无)
RTF_EXTENSIONS_FILE    =  # RTF扩展文件(无)
GENERATE_MAN           = YES  # 生成Man Page文档
MAN_OUTPUT             = man  # Man Page输出目录
MAN_EXTENSION          = .3  # Man Page文件后缀
MAN_LINKS              = YES  # Man Page链接
GENERATE_XML           = NO  # 不生成XML文档
XML_OUTPUT             = xml  # XML输出目录(无)
XML_PROGRAMLISTING     = YES  # XML程序列表(无)
GENERATE_DOCSET        = NO  # 不生成DocSet文档
DOCSET_FEEDNAME        = "Doxygen generated docs"  # DocSet feed名称(无)
DOCSET_BUNDLE_ID       = org.doxygen.Project  # DocSet bundle ID(无)
DOCSET_PUBLISHER_ID    = org.doxygen.Publisher  # DocSet发布者ID(无)
DOCSET_PUBLISHER_NAME  = Publisher  # DocSet发布者名称(无)
GENERATE_HTMLINDEX     = YES  # 生成HTML索引
GENERATE_SEARCHINDEX   = YES  # 生成搜索索引
SEARCHENGINE           = YES  # 启用搜索引擎
SERVER_BASED_SEARCH    = NO  # 不启用基于服务器的搜索
EXTERNAL_SEARCH        = NO  # 不启用外部搜索
SEARCHENGINE_URL       =  # 搜索引擎URL(无)
SEARCHDATA_FILE        = searchdata.xml  # 搜索数据文件
EXTERNAL_SEARCH_ID     =  # 外部搜索ID(无)
EXTRA_SEARCH_MAPPINGS  =  # 额外搜索映射(无)

# 代码提取配置
EXTRACT_ALL            = YES  # 提取所有代码结构(即使无注释)
EXTRACT_PRIVATE        = NO  # 不提取私有成员
EXTRACT_PRIV_VIRTUAL   = NO  # 不提取私有虚函数
EXTRACT_PACKAGE        = YES  # 提取包
EXTRACT_STATIC         = YES  # 提取静态函数/变量
EXTRACT_LOCAL_CLASSES  = NO  # 不提取局部类
EXTRACT_LOCAL_METHODS  = NO  # 不提取局部方法
EXTRACT_ANON_NSPACES   = NO  # 不提取匿名命名空间
HIDE_UNDOC_MEMBERS     = YES  # 隐藏无注释成员
HIDE_UNDOC_CLASSES     = YES  # 隐藏无注释类
HIDE_FRIEND_COMPOUNDS  = NO  # 不隐藏友元化合物
HIDE_IN_BODY_DOCS      = NO  # 不隐藏体内文档
INTERNAL_DOCS          = NO  # 不显示内部文档
CASE_SENSE_NAMES       = YES  # 区分大小写名称
HIDE_SCOPE_NAMES       = NO  # 不隐藏作用域名称
HIDE_COMPOUND_REFERENCE= NO  # 不隐藏化合物引用
SHOW_INCLUDE_FILES     = YES  # 显示包含文件
SHOW_GROUPED_MEMB_INC  = NO  # 不显示分组成员的包含文件
FORCE_LOCAL_INCLUDES   = NO  # 不强制本地包含
INLINE_INFO            = YES  # 显示内联信息
SORT_MEMBER_DOCS       = YES  # 排序成员文档
SORT_BRIEF_DOCS        = YES  # 排序简要文档
SORT_MEMBERS_CTORS_1ST = NO  # 不将构造函数排序在第一位
SORT_GROUP_NAMES       = YES  # 排序组名称
SORT_BY_SCOPE_NAME     = NO  # 不按作用域名称排序
STRICT_PROTO_MATCHING  = NO  # 不严格匹配函数原型
GENERATE_TODOLIST      = YES  # 生成TODO列表
GENERATE_TESTLIST      = YES  # 生成测试列表
GENERATE_BUGLIST       = YES  # 生成BUG列表
GENERATE_DEPRECATEDLIST= YES  # 生成废弃列表
ENABLED_SECTIONS       =  # 启用的章节(无)
MAX_INITIALIZER_LINES  = 30  # 最大初始化代码行数
SHOW_USED_FILES        = YES  # 显示使用的文件
SHOW_FILES             = YES  # 显示文件
SHOW_NAMESPACES        = YES  # 显示命名空间
FILE_VERSION_FILTER    =  # 文件版本过滤(无)
LAYOUT_FILE            = doc/template/layout.xml  # 自定义布局文件(可选)
CITE_BIB_FILES         =  # 引用的BibTeX文件(无)

# 图表配置
CLASS_DIAGRAMS         = YES  # 生成类图
MSCGEN_PATH            =  # MSCGEN路径(无)
DIA_PATH               =  # DIA路径(无)
HIDE_UNDOC_RELATIONS   = YES  # 隐藏无注释关系
HAVE_DOT               = YES  # 启用DOT工具
DOT_NUM_THREADS        = 1  # DOT线程数
DOT_FONTNAME           = Helvetica  # DOT字体名称
DOT_FONTSIZE           = 10  # DOT字体大小
DOT_FONTPATH           =  # DOT字体路径(无)
CLASS_GRAPH            = YES  # 生成类图
COLLABORATION_GRAPH    = YES  # 生成协作图
GROUP_GRAPHS           = YES  # 生成组图
UML_LOOK               = NO  # 不使用UML样式
UML_LIMIT_NUM_FIELDS   = 10  # UML字段数量限制
TEMPLATE_RELATIONS     = NO  # 不生成模板关系图
MULTI_IMAGE_PER_TAG    = NO  # 每个标签不生成多个图像
DOT_GRAPH_MAX_NODES    = 50  # DOT图最大节点数
MAX_DOT_GRAPH_DEPTH    = 5  # DOT图最大深度
DOT_TRANSPARENT        = NO  # 不使用透明背景
DOT_MULTI_TARGETS      = NO  # 不生成多个目标
GENERATE_LEGEND        = YES  # 生成图例
DOT_CLEANUP            = YES  # 生成后清理DOT文件
CALL_GRAPH             = YES  # 生成调用关系图
CALLER_GRAPH           = YES  # 生成被调用关系图
GRAPHICAL_HIERARCHY    = YES  # 生成图形化层级结构
DIRECTORY_GRAPH        = YES  # 生成目录图
DOT_IMAGE_FORMAT       = svg  # DOT图像格式(矢量图)
INTERACTIVE_SVG        = NO  # 不启用交互式SVG
DOT_PATH               = /usr/bin/dot  # DOT工具路径(Linux)
# DOT_PATH               = C:/Program Files/Graphviz/bin/dot.exe  # Windows路径

# 警告配置
WARN_IF_UNDOCUMENTED   = YES  # 无注释时警告
WARN_IF_DOC_ERROR      = YES  # 注释错误时警告
WARN_IF_INCOMPLETE_DOC = YES  # 注释不完整时警告
WARN_NO_PARAMDOC       = YES  # 参数无注释时警告
WARN_NO_RETURN         = YES  # 非void返回值无注释时警告
WARN_NO_THROWS         = NO  # 不警告无异常说明
WARN_NO_INLINE         = NO  # 不警告无内联说明
WARN_NO_RELATED        = NO  # 不警告无关联文档
WARN_NO_FUNCTION_RETURN= NO  # 不警告函数无返回值注释
WARN_FORMAT            = "$file:$line: $text"  # 警告格式
WARN_DEPRECATED        = YES  # 警告废弃的API
WARN_UNUSED_PARAM      = NO  # 不警告未使用参数
WARN_UNUSED_WARNING    = NO  # 不警告未使用的警告
WARN_MISSING_PROTO     = NO  # 不警告缺少原型
WARN_MISSING_INCLUDE_DIRS = YES  # 警告缺少包含目录
WARN_DOC_REFERENCES    = YES  # 警告文档引用错误
WARN_UNDOC_REFERENCES  = NO  # 不警告无注释引用
WARN_EXIT_CODE         = 0  # 警告退出码(0表示成功)
WARN_LOGFILE           = doc/doxygen_warn.log  # 警告日志文件

# 其他配置
ALWAYS_DETAILED_SEC    = NO
INLINE_INHERITED_MEMB  = NO
SEPARATE_MEMBER_PAGES  = NO
TAB_SIZE               = 4
ALIASES                =
OPTIMIZE_OUTPUT_FOR_C  = YES
EXTENSION_MAPPING      = .s=C .asm=C
MARKDOWN_SUPPORT       = YES
TOC_INCLUDE_HEADINGS   = 5
AUTOLINK_SUPPORT       = YES
BUILTIN_STL_SUPPORT    = NO
CPP_CLI_SUPPORT        = NO
SIP_SUPPORT            = NO
IDL_PROPERTY_SUPPORT   = YES
DISTRIBUTE_GROUP_DOC   = YES
GROUP_NESTED_COMPOUNDS = YES
SUBGROUPING            = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS  = NO
TYPEDEF_HIDES_STRUCT   = NO
LOOKUP_CACHE_SIZE      = 0

4.4 无人机电调项目文档生成效果与使用指南

4.4.1 文档目录结构

plaintext

doc/
├── html/                  # HTML文档主目录(核心)
│   ├── index.html         # 文档首页
│   ├── modules.html       # 模块列表页(按HAL/DRV/ALG/APP/PROTO划分)
│   ├── classes.html       # 结构体/枚举列表页
│   ├── functions.html     # 函数列表页
│   ├── files.html         # 源码文件列表页
│   ├── todo.html          # TODO列表页
│   ├── bugs.html          # BUG列表页
│   ├── search/            # 搜索功能目录
│   ├── graphs/            # 调用关系图、模块图目录
│   │   ├── callgraph_alg_foc_main.svg  # FOC主函数调用图
│   │   ├── caller_graph_drv_motor_start.svg  # 电机启动函数被调用图
│   │   └── module_graph.svg  # 整体模块依赖图
│   └── ...                # 其他辅助文件
├── man/                   # Man Page文档目录
│   ├── hal_pwm.3          # PWM抽象模块Man Page
│   ├── drv_motor.3        # 电机驱动模块Man Page
│   └── app_esc.3          # 电调控制模块Man Page
├── doxygen_warn.log       # 警告日志文件(用于补全注释)
├── logo.png               # 项目Logo
└── template/              # 自定义模板目录(header.html/footer.html/custom.css)
4.4.2 核心文档页面功能说明
页面名称访问路径核心功能嵌入式开发使用场景
首页html/index.html项目概述、模块导航、快速链接(函数 / 结构体 / 文件)快速了解项目整体架构,跳转至核心模块
模块列表页html/modules.html按层级展示所有模块(HAL/DRV/ALG/APP/PROTO),显示模块描述和包含的函数 / 结构体查看模块划分,快速定位目标模块
函数列表页html/functions.html按字母序排列所有函数,支持按模块、文件筛选,显示函数简要描述快速查找函数,查看函数所属模块和文件
结构体列表页html/classes.html展示所有结构体、枚举、联合体,显示成员变量和注释查看数据结构定义,理解参数含义
函数详情页从函数列表页点击函数名进入显示函数完整注释(功能、参数、返回值、注意事项)、调用关系图、所属文件开发时参考接口用法,排查调用关系
TODO 列表页html/todo.html汇总所有 @todo 标记的待完成事项,按模块分类项目迭代时明确优化方向
BUG 列表页html/bugs.html汇总所有 @bug 标记的已知问题,包含触发条件和处理建议测试和维护时排查已知问题
模块依赖图html/graphs/module_graph.svg可视化展示各模块间的依赖关系(如 DRV 依赖 HAL,ALG 依赖 DRV)架构评审、代码重构时评估模块耦合度
4.4.3 关键文档效果示例
  1. 首页效果

    • 顶部显示项目名称(无人机电调 V2.0)、版本(V2.0.0)、简要描述;
    • 中间展示模块导航栏(HAL/DRV/ALG/APP/PROTO),点击直接跳转至模块列表;
    • 底部显示快速链接(函数、结构体、文件、TODO、BUG)和文档生成时间。
  2. 模块详情页(以 DRV_MOTOR 为例)

    • 模块描述:无刷电机驱动模块,基于 HAL_PWM 和 HAL_ADC 实现,支持 FOC 控制;
    • 包含内容:结构体(DrvMotorConfigType、DrvMotorHandleType)、枚举(DrvMotorPhaseType)、函数(drv_motor_init、drv_motor_start 等);
    • 模块依赖:显示依赖的 HAL 层模块(HAL_PWM、HAL_ADC)和算法层模块(PID_CTRL)。
  3. 函数详情页(以 app_esc_main_loop 为例)

    • 简要描述:电调主循环(核心函数);
    • 详细描述:完整的主循环流程(状态更新→故障检测→控制信号解析→电机控制→通信交互);
    • 参数说明:输入参数 esc(电调句柄指针),无输出参数;
    • 返回值:0 表示正常执行,-1/-2 表示参数错误 / 未初始化;
    • 调用关系图:显示该函数调用的所有子函数(drv_motor_get_state、alg_foc_main、app_esc_error_handler 等);
    • 被调用关系图:显示调用该函数的外部模块(如 RTOS 任务函数);
    • 注意事项:强调必须 1ms 调用一次,优先级高于其他任务。
  4. 结构体详情页(以 AppEscParamType 为例)

    • 简要描述:电调参数配置结构体;
    • 成员变量列表:每个变量的名称、类型、注释(如 ctrl_mode:控制模式,pwm_min_width:PWM 最小脉宽);
    • 关联函数:显示使用该结构体的函数(app_esc_set_param、app_esc_get_param)。
4.4.4 文档使用场景与技巧
使用角色核心使用场景文档使用技巧
新入职开发者熟悉项目架构、接口用法1. 从首页模块导航进入 APP_ESC 模块,查看电调主流程;2. 查看 DRV_MOTOR 和 ALG_FOC 模块,理解电机控制核心逻辑;3. 通过函数列表页搜索关键函数(如 app_esc_init、alg_foc_main),查看详细用法
模块开发工程师开发新模块、调用已有接口1. 查看目标模块的接口文档(如调用 HAL_PWM 模块时,查看 hal_pwm_set_duty 函数的参数和返回值);2. 通过调用关系图确认接口依赖,避免重复开发;3. 遵循已有模块的注释规范编写新代码
测试工程师编写测试用例、排查故障1. 查看 BUG 列表页,了解已知问题的触发条件;2. 查看故障码枚举(AppEscErrCodeType),对应故障原因和排查方法;3. 通过函数详情页了解接口的输入输出边界(如 PWM 脉宽范围 1000-2000μs)
项目管理者项目进度跟踪、架构评审1. 查看 TODO 列表页,跟踪待优化事项的进度;2. 通过模块依赖图评估架构合理性,识别模块耦合过高的问题;3. 查看文档更新时间,确认文档与代码同步
维护工程师故障定位、代码重构1. 通过调用关系图追溯故障函数的依赖链;2. 查看函数的 @note 和 @warning,了解潜在风险;3. 参考历史版本的文档(通过 Git 版本控制),对比代码变更
4.4.5 文档更新与维护
  1. 定期更新:每次代码提交前,运行make doc生成最新文档,确保文档与代码同步;
  2. 注释补全:查看doxygen_warn.log,补全无注释的函数 / 结构体 / 变量;
  3. 模板优化:根据团队需求修改自定义模板(如 header.html 添加团队联系方式,custom.css 调整字体大小);
  4. 文档部署:将 html 目录部署到内部 Nginx 服务器,团队成员通过http://xxx.xxx.xxx.xxx/esc_doc/html/访问最新文档;
  5. 版本控制:将 Doxyfile、模板文件、logo.png 纳入 Git 版本控制,确保团队使用统一配置。

五、实战案例二:Doxygen 在汽车 FOC 控制器软件开发中的应用

5.1 汽车 FOC 控制器项目概述

5.1.1 项目背景

汽车 FOC(Field-Oriented Control)控制器是新能源汽车(纯电动 / 混合动力)驱动系统的核心部件,负责控制永磁同步电机(PMSM)的转速和转矩,实现车辆的动力输出、能量回收等功能。本项目基于 STM32G474 芯片,开发一款适用于 100kW 永磁同步电机的 FOC 控制器,支持矢量控制、最大转矩电流比(MTPA)控制、弱磁控制等算法,满足 ISO 26262 功能安全标准(ASIL-B 等级)。

5.1.2 项目架构(分层 + 功能安全设计)
架构层级核心模块功能描述依赖层级功能安全要求
硬件抽象层(HAL)GPIO、TIM、ADC、CAN FD、SPI、DMA屏蔽 STM32G4 底层差异,提供符合 ASIL-B 的抽象接口支持硬件诊断(如 ADC 自校验、GPIO 故障检测)
驱动层(DRV)IGBT 驱动、旋转变压器采样、母线电容检测、预充电控制基于 HAL 层实现高压驱动和传感器采样HAL 层过流 / 过压 / 过温保护、故障诊断与上报
算法层(ALG)FOC 矢量控制、MTPA 控制、弱磁控制、能量回收算法电机控制核心算法,满足动态响应和效率要求DRV 层算法容错(如位置传感器信号丢失时的降级控制)
应用层(APP)驾驶模式管理、转矩控制、故障管理、通信交互控制器整体逻辑,适配整车控制策略ALG 层、DRV 层故障分级处理、安全状态切换(如跛行模式)
功能安全层(SAFE)安全监控单元(SMU)、故障诊断、安全通信满足 ISO 26262 ASIL-B 要求所有层级双核心监控、故障存储与上报、安全关断
通信层(COMM)CAN FD 通信、以太网通信与 VCU(整车控制器)、BMS(电池管理系统)交互HAL 层通信数据校验、超时监控
5.1.3 文档需求分析(结合汽车行业特性)

汽车 FOC 控制器作为安全关键部件,文档需满足 “功能安全合规、接口标准化、维护可追溯、团队协作高效” 四大核心需求:

  1. 功能安全合规:文档需体现 ISO 26262 ASIL-B 要求,包括安全目标、故障诊断机制、安全机制描述;
  2. 接口标准化:与 VCU/BMS 的通信接口(CAN FD 信号)、IGBT 驱动接口需符合汽车行业标准,文档需明确信号定义和时序;
  3. 维护可追溯:每个模块的设计思路、参数配置、故障处理逻辑需可追溯,支持后期故障排查和迭代;
  4. 团队协作高效:跨团队(硬件 / 软件 / 测试 / 整车)协作时,文档需清晰界定各模块职责和接口边界。

5.2 核心模块 Doxygen 注释实战

5.2.1 功能安全层(SAFE)核心模块:安全监控单元

c

运行

/*!
 * @file safe_smu.h
 * @brief 功能安全监控单元(SMU)模块
 * @author Chen Wei
 * @date 2025-12-04
 * @version V1.0.0
 * @details 实现ISO 26262 ASIL-B等级的安全监控功能,包括双核心互检、硬件故障诊断、
 *          软件超时监控、安全关断控制等,是FOC控制器的功能安全核心模块
 * @note 1. 安全监控单元采用独立定时器((TIM15)中断驱动,中断周期100μs,确保实时性;
 *       2. 所有故障诊断结果存储在非易失性存储器(片内Flash扇区5),支持故障追溯;
 *       3. 安全关断优先级最高,触发后立即切断IGBT驱动信号,禁止电机输出转矩
 * @safety 安全目标:避免控制器故障导致电机非预期转矩输出,降低车辆碰撞风险;
 *         安全机制:双核心互检、硬件级故障诊断、安全关断电路、故障降级控制
 */

#ifndef SAFE_SMU_H
#define SAFE_SMU_H

#include "hal_common.h"
#include "safe_fault.h"

/*!
 * @defgroup SAFE_SMU 安全监控单元模块
 * @brief ISO 26262 ASIL-B安全监控,含双核心互检、故障诊断、安全关断
 * @ingroup SAFE
 * @safety 符合ISO 26262 ASIL-B等级要求,支持故障诊断覆盖率≥90%
 * @{
 */

/*!
 * @brief 安全监控模式枚举
 */
typedef enum {
    SAFE_SMU_MODE_NORMAL,    /*!< 正常模式(无故障) */
    SAFE_SMU_MODE_DIAG,      /*!< 诊断模式(正在执行自校验) */
    SAFE_SMU_MODE_FAULT,     /*!< 故障模式(检测到安全故障) */
    SAFE_SMU_MODE_LIMP,      /*!< 跛行模式(非致命故障,降级运行) */
    SAFE_SMU_MODE_SHUTDOWN   /*!< 安全关断模式(致命故障,禁止输出) */
} SafeSmuModeType;

/*!
 * @brief 双核心互检状态枚举
 */
typedef enum {
    SAFE_SMU_CORE_CHECK_OK,  /*!< 双核心互检正常 */
    SAFE_SMU_CORE_CHECK_ERR, /*!< 双核心互检失败(核心间数据不一致) */
    SAFE_SMU_CORE_TIMEOUT    /*!< 双核心互检超时(未收到对方信号) */
} SafeSmuCoreCheckType;

/*!
 * @brief 硬件诊断类型枚举
 */
typedef enum {
    SAFE_SMU_HW_DIAG_ADC,    /*!< ADC自校验 */
    SAFE_SMU_HW_DIAG_GPIO,   /*!< GPIO故障检测 */
    SAFE_SMU_HW_DIAG_CAN,    /*!< CAN FD通信诊断 */
    SAFE_SMU_HW_DIAG_IGBT,   /*!< IGBT驱动诊断 */
    SAFE_SMU_HW_DIAG_POWER,  /*!< 电源监控诊断 */
    SAFE_SMU_HW_DIAG_MAX     /*!< 硬件诊断类型数量 */
} SafeSmuHwDiagType;

/*!
 * @brief 安全监控配置结构体
 */
typedef struct {
    uint32_t core_check_timeout;  /*!< 双核心互检超时时间(μs),默认100μs */
    uint32_t sw_watchdog_timeout; /*!< 软件看门狗超时时间(ms),默认10ms */
    uint16_t adc_self_check_freq; /*!< ADC自校验频率(Hz),默认10Hz */
    uint8_t fault_storage_en;     /*!< 故障存储使能:1-使能,0-禁用 */
    uint8_t safe_shutdown_delay;  /*!< 安全关断延迟时间(μs),默认10μs */
} SafeSmuConfigType;

/*!
 * @brief 安全监控状态结构体
 */
typedef struct {
    SafeSmuModeType curr_mode;       /*!< 当前安全监控模式 */
    SafeSmuCoreCheckType core_status; /*!< 双核心互检状态 */
    SafeFaultCodeType active_fault;  /*!< 当前激活的故障码 */
    uint32_t fault_count[SAFE_FAULT_MAX]; /*!< 各故障发生次数 */
    uint32_t diag_pass_count;        /*!< 自校验通过次数 */
    uint32_t diag_fail_count;        /*!< 自校验失败次数 */
    uint32_t safe_shutdown_count;    /*!< 安全关断触发次数 */
} SafeSmuStatusType;

/*!
 * @brief 安全监控句柄结构体
 */
typedef struct {
    SafeSmuConfigType config;        /*!< 安全监控配置 */
    SafeSmuStatusType status;        /*!< 安全监控状态 */
    uint32_t core_check_tick;        /*!< 双核心互检计数器(μs) */
    uint32_t sw_watchdog_tick;       /*!< 软件看门狗计数器(ms) */
    uint32_t adc_diag_tick;          /*!< ADC自校验计数器(μs) */
    uint8_t core_check_flag;         /*!< 双核心互检标志:1-已收到对方信号,0-未收到 */
    uint32_t core_data[8];           /*!< 双核心互检数据(8个32位数据) */
} SafeSmuHandleType;

/*!
 * @brief 安全监控单元初始化
 * @param[in,out] smu 安全监控句柄指针
 * @param[in] config 安全监控配置结构体指针
 * @return 初始化结果
 * @retval 0:初始化成功
 * @retval -1:参数错误(smu为NULL或config参数非法)
 * @retval -2:定时器初始化失败(TIM15初始化失败)
 * @retval -3:Flash故障存储区初始化失败
 * @retval -4:双核心通信接口初始化失败
 * @safety 初始化流程符合ISO 26262 ASIL-B要求:
 *         1. 初始化独立安全定时器(TIM15,100μs中断);
 *         2. 初始化双核心通信接口(SPI2,速率10Mbps);
 *         3. 初始化硬件诊断模块(ADC自校验、GPIO故障检测);
 *         4. 读取Flash中存储的故障历史记录;
 *         5. 初始化安全关断电路(硬件级IGBT关断信号);
 *         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值