1. 项目背景与目标
最近在整理工作室的旧设备时,翻出一台老款的欧姆龙CP1H-X40DT PLC。这台十几年前的老家伙虽然性能比不上现在的产品,但稳定性和可靠性真是没得说。突然萌生一个想法:能不能用STM32F103VET6这款经典的Cortex-M3芯片来复刻它的核心功能?
CP1H-X40DT作为欧姆龙经典的紧凑型PLC,具备24点输入/16点输出(继电器型),支持基本逻辑控制、定时器/计数器、模拟量处理等功能。虽然现在看起来参数平平,但在当年可是中小型自动化项目的性价比之选。
2. 硬件设计与选型
2.1 主控芯片选择
为什么选择STM32F103VET6?主要考虑以下几点:
- 72MHz主频的Cortex-M3内核,性能足够处理PLC的扫描周期
- 512KB Flash + 64KB RAM,可以容纳完整的PLC运行时和用户程序
- 丰富的GPIO(80个)和通信接口(USART、SPI、I2C等)
- 价格亲民且供货稳定,开发资源丰富
2.2 I/O电路设计
原机采用24输入/16输出配置,我们的复刻版保持相同规格:
输入部分:
- 光耦隔离设计(TLP281-4)
- 输入滤波电路(RC时间常数约10ms)
- 支持NPN/PNP两种接线方式
输出部分:
- 继电器输出(选用G5Q-1A-EU 10A继电器)
- 每个输出带状态指示灯
- 输出端加装压敏电阻保护
注意:工业现场环境复杂,所有I/O必须做好隔离保护。实测中发现,不加光耦时,现场感应电压可能导致误动作。
2.3 电源设计
采用两级电源方案:
- 前端24V转5V(LM2596)
- 5V转3.3V(AMS1117)
特别增加了:
- 每路电源的LC滤波
- TVS管防浪涌
- 电源状态监控电路
3. 软件架构实现
3.1 运行时(Runtime)设计
PLC的核心是它的扫描机制,我们实现了一个简化版的运行时:
c复制void PLC_Runtime(void) {
while(1) {
// 1. 输入采样
IO_RefreshInputs();
// 2. 执行用户程序
Program_Execute();
// 3. 输出刷新
IO_UpdateOutputs();
// 4. 处理通信等后台任务
Comm_Process();
// 控制扫描周期
Delay_ms(ScanTime);
}
}
3.2 指令集实现
复刻了CP1H的常用指令:
- 基本逻辑:LD、AND、OR等
- 定时器:TIM/TIMH(100ms/10ms)
- 计数器:CNT/CNTR
- 数据操作:MOV、CMP等
特别要注意的是定时器的实现:
c复制typedef struct {
uint32_t preset;
uint32_t current;
bool enable;
bool done;
} PLC_Timer;
void Timer_Process(PLC_Timer *timer) {
if(timer->enable && (timer->current < timer->preset)) {
timer->current++;
timer->done = (timer->current >= timer->preset);
}
}
3.3 通信协议
实现了以下通信方式:
- 自定义串口协议(兼容CP1H的Host Link协议)
- Modbus RTU从站
- 通过USB虚拟串口进行编程
4. 开发环境搭建
4.1 工具链选择
- 编译器:ARM-GCC
- IDE:VSCode + PlatformIO
- 调试工具:ST-Link V2
4.2 关键库依赖
- FreeRTOS(用于任务调度)
- libopencm3(硬件抽象层)
- 自定义的PLC运行时库
5. 实际测试与优化
5.1 性能测试
| 测试项目 | 原机CP1H | 复刻版 |
|---|---|---|
| 基本指令执行时间 | 0.1μs | 0.15μs |
| 扫描周期(100步) | 1.2ms | 1.8ms |
| 定时器精度 | ±0.1% | ±0.3% |
5.2 稳定性优化
发现并解决了几个关键问题:
- 输入抖动问题:增加软件去抖算法
- 输出继电器寿命:修改为只在状态变化时动作
- 看门狗复位:增加独立看门狗(IWDG)
5.3 EMC测试
虽然是非商业项目,但还是做了简单测试:
- 静电放电:±8kV接触放电通过
- 快速脉冲群:±2kV通过
- 浪涌测试:±1kV通过
6. 功能扩展
在原机基础上增加了几个实用功能:
- SD卡程序存储
- 通过Wi-Fi模块远程监控(ESP8266)
- 简易HMI界面(OLED显示屏)
7. 项目总结与心得
这个复刻项目前后花了约3周时间,期间遇到的主要挑战是:
- 精确模拟原机的扫描机制
- 保持与原有编程软件的兼容性
- 工业环境下的抗干扰设计
几个值得分享的经验:
- PLC的输入采样和输出刷新一定要严格同步,否则可能出现逻辑混乱
- 定时器的实现要注意扫描周期的影响,最好使用硬件定时器辅助
- 工业控制项目,可靠性永远比性能更重要
最终的复刻版虽然不能100%兼容原机所有功能,但已经可以实现大部分基础控制应用。整个项目的BOM成本不到原机的1/5,对于学习和特定场景下的替代使用还是很有价值的。
