← 都来码← 文档索引Ladder原文English

Ladder

梯形图(PLC)风格的前端 —— 它做不了手机界面程序。

这一路能用的是「编译与运行」本身,UI 那整套接口(开窗/绘图/输入)没有对应语法(没有「带字符串参数的函数调用」)。

在手机上怎么跑

vml run examples/ladder/test/sysinfo.ld

编译要等一会儿(C 那种要一两分钟,脚本类语言几秒)。程序跑起来后屏幕底部就是手柄,方向键 + 四个动作键都在;点右上角返回可以回到命令行。

写法要点

示例

文件演示什么
test/file_io.ld空测试(NOP)
test/sysinfo.ld占位 —— 这一路调不了 JSON 接口

同目录还有:demo/demo_std.ld、motor_control/main.ld、test/libdemo.dbf、test/libs.ld、tty/demo_tty.ld、ui/demo_ui.ld

实测踩过的坑


下面的内容是从 VML 源码里直接带的(third_party/vml/VMLPrepares/LadderCompiler/): README 讲这个前端支持什么、怎么编;语言规范 讲语法本身。上游一改,这里重新生成就是最新的。

语言规范

梯形图语言编译器规范说明

版本:v1.0 | 日期:2026-07-06 | 修订者:深圳市探索智能科技有限公司

规范标准

字段值
目标标准IEC 61131-3 子集 (2003)
发布年份2003
完成度~98%
MCU完成度~97%
测试0 (测试目录待创建)
更新2026-05-18: 更新定时器实现为 SYSCALL #53 实时时钟;修正代码生成器状态

关键字(指令)

触点: NO(常开) NC(常闭) POS(上升沿) NEG(下降沿) 线圈: OUT(输出) SET(置位) RST(复位) 定时器: TON(接通延时) TOF(断开延时) TP(脉冲) 计数器: CTU(加计数) CTD(减计数) CTUD(加减计数) 比较: EQ NE GT GE LT LE 算术: ADD SUB MUL DIV MOD 程序控制: JMP LBL RET END 其他: MOVE SEL MUX LIMIT

概述

本编译器实现 IEC 61131-3 标准的梯形图(Ladder Diagram)语言到 VML (Virtual Machine Language) 汇编的编译。梯形图是工业控制领域广泛使用的图形化编程语言,用于可编程逻辑控制器(PLC)编程。

语言特性

1. 梯形图基本元素
触点(Contacts)
线圈(Coils)
功能块(Function Blocks)
2. 数据类型(IEC 61131-3)
基本数据类型
派生数据类型
3. 程序结构
程序声明
PROGRAM MotorControl
VAR
    StartButton AT %IX0.0 : BOOL;
    StopButton AT %IX0.1 : BOOL;
    MotorRun AT %QX0.0 : BOOL;
    Timer1 : TON;
END_VAR
变量声明区域
I/O 映射
4. 梯形图梯级结构
简单梯级
     Start    Stop     Motor
     ─┤ ├─────┤/├──────( )─
       I0.0    I0.1      Q0.0
并联分支
     Button1     Lamp1
     ─┤ ├────┬───( )─
            │
     Button2│
     ─┤ ├────┘
串联分支
     Start     Timer1.PT := T#5s
     ─┤ ├──────[TON]─────
       I0.0     Timer1
                IN  Q
                PT  ET
功能块调用
     Start     MotorCtrl
     ─┤ ├──────[FB]─────
                EN  ENO
               Start Run
               Stop  Fault
               Speed ActualSpeed
5. 定时器和计数器
定时器(TON - 接通延时)
VAR
    Timer1 : TON;
    TimeValue : TIME := T#5s;
END_VAR

// 梯形图表示
     Start     Timer1
     ─┤ ├──────[TON]─────
                IN  Q
               PT  ET

功能: 当IN为TRUE时开始计时,经过PT时间后Q变为TRUE。ET显示已过时间。

计数器(CTU - 加计数器)
VAR
    Counter1 : CTU;
    PresetValue : INT := 10;
END_VAR

// 梯形图表示
     Pulse     Counter1
     ─┤P├──────[CTU]─────
                CU  Q
               PV  CV
                R

功能: 在CU上升沿计数,当CV >= PV时Q为TRUE,R信号复位计数器。

6. 指令列表(IL)支持

梯形图编译器也支持指令列表文本格式:

LD StartButton
ANDN StopButton
OUT MotorRun

LD MotorRun
TON Timer1, T#5s
7. 结构化文本(ST)支持

在梯形图中可以嵌入结构化文本:

IF StartButton AND NOT StopButton THEN
    MotorRun := TRUE;
    Timer1(IN:=TRUE, PT:=T#5s);
END_IF;
8. 标准函数
位操作函数
数学函数
比较函数
类型转换函数
字符串函数
9. VML 代码生成约定
位操作映射
梯形图触点: ─┤ ├─
VML代码:    MOVE R0, [I0.0_address]
            CMP R0, #1
            JNE skip_branch

梯形图线圈: ─( )─
VML代码:    MOVE R0, #1
            MOVE [Q0.0_address], R0
定时器实现(使用 SYSCALL #53 GetTick 实时时钟)

TON (接通延时定时器):

TOF (断开延时定时器):

TP (脉冲定时器):

CTUD (加减计数器):

计数器实现(含溢出保护)

CTU (加计数器):

CTD (减计数器):

CTUD (加减计数器):

10. I/O 内存映射
输入映像区
地址范围: 0x8000 - 0x80FF (256字节)
用途: 存储数字输入状态
访问: MOVE R0, [0x8000]  ; 读取第一个输入字节
输出映像区
地址范围: 0x8100 - 0x81FF (256字节)
用途: 存储数字输出状态
访问: MOVE [0x8100], R0  ; 写入第一个输出字节
保持寄存器区
地址范围: 0x8200 - 0x83FF (512字节)
用途: 存储中间变量、定时器、计数器等
特殊寄存器
地址: 0x8400 - 系统时间(毫秒)
地址: 0x8404 - 扫描周期
地址: 0x8408 - 错误代码
11. 扫描周期模型

梯形图程序按照扫描周期执行:

开始扫描
├── 读取物理输入到输入映像区
├── 执行用户程序(梯形图逻辑)
├── 写入输出映像区到物理输出
└── 处理系统任务(通信、诊断等)

VML实现:

LABEL main_scan_cycle
    ; 1. 读取输入
    CALL read_physical_inputs
    
    ; 2. 执行用户程序
    CALL user_program
    
    ; 3. 写入输出
    CALL write_physical_outputs
    
    ; 4. 更新系统时间
    CALL update_system_timer
    
    ; 5. 检查扫描周期时间
    MOVE R0, [current_time]
    SUB R0, [scan_start_time]
    CMP R0, [max_scan_time]
    JLE scan_ok
    
    ; 扫描超时错误
    MOVE R0, #1
    MOVE [scan_timeout_error], R0
    
scan_ok:
    ; 等待下一个扫描周期
    CALL delay_scan_cycle
    JMP main_scan_cycle
12. 示例程序
电机启停控制
PROGRAM MotorControl
VAR
    StartButton AT %IX0.0 : BOOL;
    StopButton AT %IX0.1 : BOOL;
    MotorRun AT %QX0.0 : BOOL;
    Overload AT %IX0.2 : BOOL;
    Timer1 : TON;
END_VAR

// 梯形图逻辑
     Start    Stop    Overload   Motor
     ─┤ ├─────┤/├─────┤/├──────( )─
       I0.0    I0.1    I0.2      Q0.0
     
     Motor     Timer1
     ─┤ ├──────[TON]─────
                IN  Q
               PT  ET
              T#5s
     
     Timer1.Q    Alarm
     ─┤ ├────────( )─
                     Q0.1
流水线控制
PROGRAM ConveyorControl
VAR
    Sensor1 AT %IX0.0 : BOOL;
    Sensor2 AT %IX0.1 : BOOL;
    Motor1 AT %QX0.0 : BOOL;
    Motor2 AT %QX0.1 : BOOL;
    Counter1 : CTU;
    PartsCount : INT;
END_VAR

// 产品计数
     Sensor1    Counter1
     ─┤P├──────[CTU]─────
                CU  Q
               PV  CV
               10
                R
     
     Counter1.Q   PartsCount := Counter1.CV
     ─┤ ├─────────────────[MOV]─────
     
// 流水线控制
     Sensor1    Sensor2    Motor1
     ─┤ ├───────┤/├────────( )─
     
     Sensor2           Motor2
     ─┤ ├──────────────( )─
浮点与64位编译模式

VML 工具链通过三个编译参数控制浮点和 64 位整数的处理策略:

参数可选值默认值说明
--float32hard / soft / nonehard32位浮点 (REAL) 处理模式
--float64hard / soft / nonesoft64位浮点处理模式
--int64hard / soft / nonesoft64位整数处理模式
32位浮点 (float32)

本语言中的 REAL 类型(32位单精度浮点)按以下模式编译:

64位浮点 (double)

VML 编译层支持 64 位双精度浮点运算。梯形图语言本身未定义 LREAL 对应类型,但编译器预留扩展支持。

64位整数 (int64)

梯形图语言 IEC 61131-3 中 DLONG / LINT 等 64 位整数类型按以下模式编译:

软件模拟库

以上软件模拟库均位于 Lib/shared/ 目录,使用 C 语言编写并由 C 编译器编译为 VML,所有语言共享:

库文件用途核心函数
softfloat.cQ15.16 定点数 32 位浮点模拟__vml_float_add/sub/mul/div/neg/abs/cmp、__vml_int2float/float2int
softdouble.cIEEE 754 双精度 64 位浮点模拟__vml_double_add/sub/mul/div/neg/abs/cmp、__vml_int2double/double2int、__vml_float2double/double2float
softint64.c64 位整数双寄存器模拟__vml_i64_add/sub/neg/and/or/xor/not/shl/shr
13. 编译限制和注意事项
当前实现状态
待实现功能
  1. 梯形图到VML指令的代码生成 — ⚠️ 基本完成
  2. 定时器、计数器功能块 — ✅ 已实现 (TON/TOF/TP/CTU/CTD/CTUD)
  3. I/O内存映射管理
  4. 扫描周期调度
  5. 标准函数库实现 (MOVE/SEL/MUX/LIMIT)
技术挑战
  1. 图形到文本转换: 梯形图是图形化语言,使用文本指令列表作为中间表示
  2. 实时性要求: PLC 程序有严格的实时性要求 — 定时器使用 SYSCALL #53 毫秒时钟
  3. 位操作: 触点/线圈需要高效位操作和边沿检测
  4. 保持性变量: 需要保持断电后的变量值
14. 与VML运行时集成

梯形图程序通过以下方式与VML运行时交互:

系统调用
15. 应用领域

梯形图编译器主要应用于:

通过将梯形图编译为VML代码,可以在VML虚拟机上运行传统的PLC程序,实现工业控制程序的跨平台移植和仿真测试。


🆕 字符串编码 (v1.65.19)

该语言编译器通过共享库 (Lib/shared/) 间接使用 VML 字符串体系。

伪指令宽度编码C 类型
.string8-bitUTF-8char*
.wstring16-bitUTF-16LEwchar_t*
.ustring32-bitUTF-32LEchar32_t*

MCU 模式 (默认): 字符串输出为 UTF-8 (.string) OS 模式: 可通过 VML_WSTRING 宏判断编码

共享库已提供宽字符串转换函数 (wchar.h/uchar.h),各语言编译器可按需使用。

编译器 README

梯形图 (IEC 61131-3 子集) 编译器

路径: VMLPrepares/LadderCompiler/ 完成度: ~98% | 🟢 生产可用 标准库: Lib/ladder/

功能

编译模式

MCU 模式(默认 --mode mcu)

MCU 模式针对单片机/裸机环境(Arduino/STM32/8051 等)优化,自动跳过不兼容操作系统的特性。

跳过(遇到这些语法不生成代码):

保留(由 BIOS 实现底层):

OS 模式(--mode os,预留)

OS 模式针对带操作系统环境(如 Linux 嵌入式、RTOS 等),届时支持全部语言特性(文件系统、多线程、异步、异常、反射等)。

RAM 级别
MCU 安全编码提示

使用

dotnet run --project VMLTool -- input.lad -o output.vml

测试

Test/La/ — 0 测试文件(测试目录待创建)