命名规范

一致的命名规范提高代码可读性和可维护性。

标识符命名

元素 规范 示例
程序 (PROGRAM) PascalCase MotorControl, TempManager
功能块 (FUNCTION_BLOCK) PascalCase PIDController, TimerDelay
函数 (FUNCTION) PascalCase CalculateSpeed, ConvertToReal
变量 snake_case motor_speed, output_value
常量 UPPER_SNAKE MAX_SPEED, TIMEOUT_MS
输入参数 名词性前缀 enable, setpoint, mode
输出参数 状态性结束 done, error, value
类型别名 T_PascalCase T_SensorData, T_AxisConfig

IO 变量前缀

// 物理 IO 映射变量使用有意义的名称
sensor_1 AT %I* : BOOL;          // 数字量输入
motor_out AT %Q* : BOOL;         // 数字量输出
temp_value AT %IW* : INT;        // 模拟量输入
speed_ref AT %QW* : INT;         // 模拟量输出

代码结构

程序组织单元 (POU) 命名

功能_对象_修饰符
示例:
- Check_Temperature
- Control_Motor_Speed
- Monitor_Battery_Level

功能块设计原则

  1. 单一职责:每个功能块只完成一个逻辑功能
  2. 显式接口:所有输入/输出在 VAR_INPUT/VAR_OUTPUT 中声明
  3. 状态封装:内部状态使用 VAR 声明,不对外暴露
  4. 初始化安全:所有变量有明确的初始值
// 好的设计
FUNCTION_BLOCK ValveControl
VAR_INPUT
    open_command : BOOL;
    close_command : BOOL;
    feedback_open : BOOL;
    feedback_closed : BOOL;
END_VAR
VAR_OUTPUT
    control_signal : BOOL;
    state : INT := 0;
    error : BOOL := FALSE;
END_VAR
VAR
    timeout : INT := 0;
    prev_open : BOOL := FALSE;
END_VAR

程序模块化

MainProgram/
├── Main.st              # 主程序(调度入口)
├── MotorControl.st      # 电机控制
├── TempControl.st       # 温度控制
├── SafetyLogic.st       # 安全逻辑
├── Communication.st     # 通信模块
└── Diagnostics.st       # 诊断模块

代码风格

缩进与格式

PROGRAM WellFormatted
VAR
    input_value : INT := 0;
    output_value : INT := 0;
    counter : INT := 0;
END_VAR

// IF 语句使用 4 空格缩进
IF input_value > 100 THEN
    output_value := 100;
    counter := counter + 1;
ELSE
    output_value := input_value;
END_IF

// 嵌套结构
FOR i := 0 TO 10 BY 1 DO
    IF array[i] > threshold THEN
        result := result + array[i];
    END_IF
END_FOR

注释规范

// 1. 文件头部注释(每个 POU)
// ==========================================
// 功能: 电机速度 PID 控制器
// 作者: KVPAC Team
// 版本: 1.0
// 更新: 2026-06-04
// ==========================================

// 2. 行内注释
counter := counter + 1;  // 每周期计数递增

// 3. 段注释(逻辑块说明)
// === 启动逻辑 ===
// 顺序: 自检 → 预充电 → 启动

错误处理

防御性编程

// 1. 检查输入范围
IF input < 0 OR input > 10000 THEN
    error := TRUE;
    error_code := ERR_INVALID_INPUT;
    RETURN;  // 提前返回,避免无效操作
END_IF

// 2. 除数检查
IF divisor <> 0 THEN
    result := dividend / divisor;
ELSE
    result := 0;
    error := TRUE;
END_IF

// 3. 数组边界检查
IF index >= 0 AND index < ARRAY_SIZE THEN
    value := data_array[index];
ELSE
    value := 0;
    error := TRUE;
END_IF

状态机错误恢复

CASE state OF
    IDLE:
        IF start THEN state := INIT; END_IF
        
    INIT:
        IF init_done THEN
            state := RUNNING;
        ELSIF init_failed THEN
            state := ERROR;
        END_IF
        
    RUNNING:
        IF fault_detected THEN
            state := ERROR;
            error_time := CURRENT_TIME;
        END_IF
        
    ERROR:
        // 自动恢复
        IF (CURRENT_TIME - error_time) > T#5s THEN
            state := IDLE;
            error := FALSE;
        END_IF
END_CASE

性能优化

避免的写法

// ❌ 避免:不必要的中断执行流
WAIT 100;
// 使用定时器代替 WAIT

// ❌ 避免:大循环中的 IO 操作
WHILE index < 1000 DO
    // IO 操作很慢,不要在循环中频繁执行
    data := read_io(index);
    index := index + 1;
END_WHILE

// ❌ 避免:重复计算
result1 := (a + b) * c / d;
result2 := (a + b) * e / f;
// 改为:
temp := a + b;
result1 := temp * c / d;
result2 := temp * e / f;

// ❌ 避免:频繁的 IF 判断
IF mode = 1 THEN mode1_logic(); END_IF
// 使用 CASE 更高效
CASE mode OF
    1: mode1_logic();
END_CASE

推荐的写法

// ✅ 使用功能块封装可复用逻辑
// ✅ 避免 Main 程序过于庞大
// ✅ 使用 CONSTANT 而不是硬编码数字
// ✅ 优先使用 DINT 而非 INT(避免溢出)
// ✅ 循环中使用 FOR(固定次数)而非 WHILE(可能死循环)

版本控制

推荐的 .gitignore

build/
*.bin
*.out
logs/
node_modules/
.DS_Store

提交信息规范

feat: 添加 Modbus TCP 通信功能
fix: 修复定时器溢出导致的看门狗复位
refactor: 重构 IO 映射配置结构
docs: 更新 ST 语言语法参考文档
test: 添加 Modbus 通信测试用例

调试技巧

  1. 使用断言:在关键逻辑后添加调试输出变量
  2. 状态追踪:将所有状态机当前状态输出到调试变量
  3. 性能分析:测量各任务的执行周期时间
  4. 日志分级:ERROR > WARNING > INFO > DEBUG
// 调试输出示例
debug_current_state := state;
debug_cycle_time := cycle_end - cycle_start;
debug_memory_usage := GET_MEMORY_USAGE();

安全检查清单

  • 所有 IO 变量有默认值
  • 除法运算有除零保护
  • 数组访问有边界检查
  • 状态机有默认分支 (ELSE)
  • 看门狗配置合理
  • 错误状态可恢复
  • 紧急停止功能正常
  • 异常情况有日志输出