1. 项目概述:当STM32遇上三菱PLC
去年在工控现场调试时,我遇到个头疼的问题——产线需要增加16个光电传感器,但FX3U的DI点数已经用尽。正当准备换PLC型号时,偶然发现国内有团队把三菱PLC的运行时系统移植到了STM32上。这套源码最吸引我的地方在于:使用STM32F407芯片就能完整运行FX3U的梯形图程序,甚至可以直接用GX Works2编程!
这个开源项目实现了三菱FX3U PLC的完整指令集,包括基础逻辑控制、数据处理和新增的120条扩展指令。通过动态内存分配技术,D寄存器可以扩展到8000字(传统FX3U最多只能到8000点),M辅助继电器也突破了三菱原厂的2048点限制。更关键的是支持MODBUS RTU/TCP协议栈和模拟量处理,实测在72MHz主频的STM32F103上就能流畅运行。
2. 核心架构解析
2.1 寄存器动态分配机制
传统PLC采用固定内存分区,而本项目用malloc动态分配寄存器空间:
c复制D_register = (uint16_t *)malloc(8000*2); // D寄存器区
M_register = (uint8_t *)malloc(2048); // M继电器区
这种设计的优势在于:
- 现场扩展时无需重新编译工程
- 不同项目可以灵活配置资源占用
- 节省内存空间(未使用的寄存器不占RAM)
注意:使用动态分配时,务必在STM32的启动文件中增大堆空间(建议至少16KB),否则可能引发HardFault。
2.2 指令执行引擎
梯形图编译后会被转换为函数指针数组:
c复制typedef void (*PLC_OP)(void);
const PLC_OP code_table[] = {
LD_X001, // 加载X001触点
AND_M10, // 与M10串联
OUT_Y005, // 输出到Y005
MOV_D100_D200 // 数据传输指令
};
运行时通过循环调用这些函数指针来模拟PLC扫描周期。实测在STM32F407(168MHz)上,单个扫描周期可处理超过2000条基本指令,满足大多数工业场景需求。
