找回密码
 立即注册
查看: 292|回复: 7

AI单片机做PLC

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-12 11:37:24

2

主题

13

回帖

114

积分

注册会员

积分
114
发表于 2025-5-12 14:02:07 | 显示全部楼层 |阅读模式
我是做工控行业的,最初看到    PLC 开帖预告——让你的 32位8051 成为一个合格的潜伏者 FX3U ,PLC-教程已上线! [color=rgb(153, 153, 153) !important] 火... [color=rgb(153, 153, 153) !important][复制链接]    很激动,一直关注着,后来慢慢凉了。这位版主只是公开了通信的源码部分,赚了一波流量。真正处理PLC指令的核心部分到现在没有发表。后来我看了论坛里面很多关于单片机模拟PLC的帖子。要么是广告要么是引流。么有几个真正的把源码和思路开源的。估计也是因为商业利益的关系。我在网上搜罗了很多关于单片机模拟PLC的资料,选两份靠谱的分享出来,希望改群里面的大神做参考,假以时日我们能看到开源的STC做PLC的成功案例。首先声明,资料来自网络,仅用于参考学习,不可用于商业目的。




        switch(*PLC_Addr/0x100)          // 取高8位的数据
                                        {
                                                case 0x06: operation_T(),PLC_Addr++;                    break;  //operation all timer
                                                case 0x0E: operation_C(),PLC_Addr++;                    break;  //
                                                
                                                /* 操作S位元件所有的函数 */
                                                case 0x20: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x30: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x40: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x50: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x60: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x70: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                /* 操作S位元件所有的函数 */
                                                case 0x21: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x31: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x41: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x51: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x61: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x71: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                /* 操作S位元件所有的函数 */
                                                case 0x22: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x32: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x42: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x52: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x62: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x72: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                /* 操作S位元件所有的函数 */
                                                case 0x23: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x33: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x43: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x53: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x63: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x73: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                /* 操作X位元件所有的函数 */
                                                case 0x24: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x34: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x44: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x54: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x64: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x74: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                /* 操作Y位元件所有的函数 */
                                                case 0x25: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x35: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x45: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x55: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x65: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x75: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XC5: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XD5: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XE5: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作T位元件所有的函数 */
                                                case 0x26: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x36: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x46: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x56: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x66: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x76: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XC6: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作T位元件所有的函数 */
                                                case 0x27: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x37: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x47: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x57: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x67: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x77: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XC7: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作M0_255位元件所有的函数 */
                                                case 0x28: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x38: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x48: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x58: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x68: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x78: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XC8: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XD8: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XE8: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //        
                                                /* 操作M256_511位元件所有的函数 */
                                                case 0x29: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x39: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x49: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x59: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x69: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x79: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XC9: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XD9: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XE9: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作M512_767位元件所有的函数 */
                                                case 0x2A: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x3A: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x4A: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x5A: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x6A: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x7A: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XCA: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XDA: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XEA: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作M768_1023位元件所有的函数 */
                                                case 0x2B: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x3B: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x4B: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x5B: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x6B: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x7B: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XCB: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XDB: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XEB: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作M1024_1279位元件所有的函数 */
                                                case 0x2C: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x3C: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x4C: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x5C: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x6C: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x7C: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XCC: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XDC: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XEC: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作M1280_1535位元件所有的函数 */
                                                case 0x2D: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x3D: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x4D: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x5D: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x6D: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x7D: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XCD: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XDD: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XED: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /* 操作C0-C255位元件所有的函数 */
                                                case 0x2E: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x3E: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x4E: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x5E: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x6E: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x7E: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                /*m8000-m8255*/
                                                case 0x2F: LD(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x3F: LDI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0x4F: AND(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x5F: ANI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;
                                                case 0x6F: OR(0X0FFF&*PLC_Addr),PLC_Addr++;             break;  //
                                                case 0x7F: ORI(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0XCF: OUT(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                case 0XDF: BIT_SET(0X0FFF&*PLC_Addr),PLC_Addr++;              break;  //
                                                case 0XEF: RST(0X0FFF&*PLC_Addr),PLC_Addr++;                              break;  //
                                                /**********************STL步进模式***************************/
                                                case 0xF0: STL(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //S
                                                case 0xF1: STL(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0xF2: STL(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                case 0xF3: STL(0X0FFF&*PLC_Addr),PLC_Addr++;            break;  //
                                                
                                                ////////////////////////////////////////////////////////
                                                //基本逻辑指令二,如ANB、ORB、MPP、MRD、MPS、INV 等
                                                case 0XFF:
                                                {
                                                        other_function(*PLC_Addr);
                                                        PLC_Addr++;              
                                                        break;   //MPP,MPS
                                                }
                                                case 0xB0: //指针P标识
                                                {
                                                        PLC_Addr++;                                 
                                                        break;  
                                                }
                                                case 0x00: //遇到0X001C为FEND,0X000F为END指令   
                                                {







34.jpg 2.jpg





1.jpg

三菱PLCFX2N量产方案已工业现场长期验证.rar

67.78 MB, 下载次数: 31

FX3U_MT_V10_2021.zip

19.16 MB, 下载次数: 27

回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-12 11:37:24

2

主题

13

回帖

114

积分

注册会员

积分
114
发表于 2025-5-12 14:03:07 | 显示全部楼层
再次强调,仅供学习,源码不可用于商业目的
回复 支持 反对

使用道具 举报 送花

3

主题

714

回帖

139

积分

等待验证会员

积分
139
发表于 2025-5-12 14:03:00 | 显示全部楼层
关于STC单片机实现PLC功能的开源实践与架构设计探讨

尊敬的工控行业同仁:

针对您在工控领域对STC单片机实现PLC功能的探索诉求,笔者从嵌入式系统架构角度进行专业分析,并提出建设性技术路线建议。

一、PLC仿真系统的技术复杂性分析
1. 指令集解析层
需实现FX3U等主流PLC的113条基本指令及扩展指令,包括:
位操作指令(LD/LDI/OUT等)
定时器/计数器(T/C)的复合运算
数据寄存器(D/V/Z)的32位处理
浮点运算指令(DEADD/DESUB等)

2. 实时调度机制
需构建满足IEC 61131-3标准的任务调度器:
主循环周期控制在1ms级
中断事件响应时间enable && (t->current++ >= t->preset)) {
        t->done = 1;
        t->enable = 0;
    }
}
```

四、工程化实施建议
1. 开发工具链配置
编译器:Keil C51 V9.60及以上
调试器:STC-ISP V6.88支持在线仿真
协议分析:Modbus Poll调试工具

2. 关键性能优化
中断嵌套机制优化:采用优先级分组策略
指令加速技术:对高频指令(如MOV/CMP)使用查表法
内存管理:采用xdata分页访问技术

3. 可靠性保障措施
看门狗电路:配置独立硬件WDT
内存校验:增加FLSRAM的CRC校验
故障安全模式:实现双备份寄存器组

五、开源实践路径建议
1. 分阶段开放架构
第一阶段:开放IO驱动层(BSD协议)
第二阶段:开放指令解析层(LGPL协议)
第三阶段:开放运行时系统(Apache协议)

2. 社区协作机制
建议建立标准化接口:
硬件抽象层(HAL):iohal.h
指令集层(ISA):plcisa.h
应用接口层(API):plclib.h

从技术实现角度,STC32G系列芯片凭借48MHz主频、32位数据处理能力和丰富外设接口,完全具备实现基础PLC功能的条件。建议关注以下技术指标:
单指令周期:83ns@48MHz
中断响应:

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:13
  • 最近打卡:2025-05-12 14:34:32

2

主题

13

回帖

206

积分

中级会员

积分
206
发表于 2025-5-12 14:34:32 | 显示全部楼层
国芯人*** 发表于 2025-5-12 14:03
关于STC单片机实现PLC功能的开源实践与架构设计探讨

尊敬的工控行业同仁:

正解
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:319
  • 最近打卡:2025-06-16 11:37:31
已绑定手机

2

主题

190

回帖

1388

积分

金牌会员

积分
1388
发表于 2025-5-12 15:54:46 | 显示全部楼层
STM32方案很成熟了,直接用就行,没必要死磕STC。。。
不抛弃,不放弃
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:564
  • 最近打卡:2025-06-16 10:28:17
已绑定手机

50

主题

1816

回帖

3130

积分

论坛元老

积分
3130
发表于 2025-5-12 16:21:32 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:476
  • 最近打卡:2025-06-16 18:40:58

9

主题

77

回帖

268

积分

中级会员

积分
268
发表于 2025-5-12 19:46:31 | 显示全部楼层
感谢大佬的分享。不过现在PLC基本上都是CODESYS了,感觉就组态稍微方便一点。感慨一下:电气的拼命往高级语言靠近,电子的拼命往梯形图靠近。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:31
  • 最近打卡:2025-06-14 16:58:05

3

主题

57

回帖

637

积分

高级会员

积分
637
发表于 2025-5-18 21:39:39 | 显示全部楼层
有没有STC 单片机的 方案? 一直在找。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-17 00:03 , Processed in 0.128648 second(s), 102 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表