51单片机DIY做PLC编程精编版

合集下载

PLC+单片机

PLC+单片机

AN2103 AN2103 基于GUTTA一步一步实现一个最小PLC系统COPYRIGHT © 2008 2009/03/25写在前面的话 (4)为什么要做自己的PLC系统 (4)这里实现了什么样的PLC系统 (4)第1章前期准备 (5)电脑 (5)CPU-EC20 (8051)仿真器 (5)安装8051的C编译器SDCC (6)安装软件GUTTA Ladder Editor (6)ISP下载软件STC-ISP (7)第2章规划 (7)内存系统 (7)指令系统 (8)运行模式 (10)通讯系统 (15)第3章添加CPU类型 (16)配置类型(PlcType.XML) (17)配置变量系统(ManagerVar.XML) (19)配置指令集(ManagerFun.XML) (22)CPU类型的测试 (22)第4章完成仿真器固件 (22)熟悉我们的编译器 (22)编译单个文件 (23)Intel Hex文件的对齐 (23)编译多个文件 (23)命令行参数 (24)变量空间分配的扩展 (25)基本定义 (26)硬件系统 (30)内存 (30)I/O操作 (32)闪存管理 (36)时钟节拍 (40)串口通讯 (43)软件系统 (49)通讯协议 (49)指令集支持 (58)运行系统 (66)第5章完成CPU类型的配置 (72)完成文件CompileInfor.XML (73)<Param> (74)<Dictation> (74)<Command> (74)完成文件swap_auto.h (76)第6章综合调试 (78)编译系统固件 (78)下载系统固件 (80)最简单的程序 (81)逻辑指令的测试 (81)定时器指令的测试 (81)计数器指令的测试 (82)写在前面的话为什么要做自己的PLC系统实现一个自己的PLC其实不难(当然要实现一个功能全面的商业化的PLC还是有难度的),只要你懂C语言、掌握一种单片机的应用、熟悉基本的I/O电路、同时有这方面的兴趣(这个最关键)。

51单片机c语音 rrc汇编写法

51单片机c语音 rrc汇编写法

近年来,随着物联网和嵌入式系统的快速发展,对嵌入式系统的需求也日益增长。

51单片机作为一种经典的嵌入式系统芯片,一直以来都备受工程师和科技爱好者的喜爱。

在嵌入式系统中,51单片机的C语言和汇编语言编程是必不可少的技能。

本文将介绍51单片机C语言和RRC汇编编程的技巧和方法。

1. 51单片机C语言编程51单片机的C语言编程是一种相对简单易学的编程方法。

通过C语言,可以实现对于51单片机的各种功能进行控制和操作。

在进行51单片机C语言编程时,首先需要熟悉51单片机的C语言编程环境和开发工具。

常用的51单片机C语言编程环境有Keil C51、SDCC等。

在选择合适的开发环境后,就可以开始进行51单片机C语言编程。

在编写C语言程序时,需要注意对51单片机的外设进行正确的配置和初始化,以及对硬件资源的合理利用。

另外,对于一些特殊的应用,可能需要对中断、定时器、串口等进行特殊的处理。

2. 51单片机RRC汇编编程在嵌入式系统中,汇编程序通常被用于对特定的硬件进行底层控制和优化。

对于51单片机来说,RRC汇编语言是一种常用的低级语言。

在进行51单片机RRC汇编编程时,需要对51单片机的指令集和寄存器进行深入的了解。

通过RRC汇编语言,可以直接对51单片机的硬件进行操作,实现对于特定硬件资源的高效控制。

在进行RRC汇编编程时,需要注意对内存和寄存器的管理,以及对51单片机的中断和外设的处理。

3. 51单片机C语言和RRC汇编编程的应用通过学习51单片机C语言和RRC汇编编程,可以实现对于各种应用的快速开发和优化。

在工业控制、通信系统、自动化设备等领域,都可以广泛应用51单片机C语言和RRC汇编编程技术。

通过合理的软件设计和编程,可以实现对51单片机硬件资源的高效利用,提高系统的稳定性和可靠性。

另外,通过C语言和RRC汇编的结合使用,可以实现对于嵌入式系统应用的灵活性和高性能要求。

4. 总结通过对51单片机C语言和RRC汇编编程的初步介绍,可以看出这两种编程方法对于嵌入式系统的开发和优化具有重要的意义。

用51单片机做简易PLC

用51单片机做简易PLC

用51单片机做简易PLC
最近在51hei单片机论坛上下载了一个PMW-HEX的软件,这个软件可以将三菱PLC编程软件编写的梯形图转换成HEX文件,再将这个HEX文件烧录到51 单片机上,这样51单片机就有了梯形图所编程的功能了。

我觉得蛮有意思的,虽然该软件并不能兼容PLC的所有功能,甚至说很多功能不能兼容,但基本的一些指令和少量的软元件已经足够做一些简单控制功能了。

基于这个我就想着自己动手做一个4入4出的简易PLC来玩玩吧,PMW-HEX的下载地址是:51hei/bbs/dpj-19820-1.html 想了就动手吧,否则以前学的一些电子知识就要荒废了。

因为手上只有AT89S52的单片机,那么就拿这款单片机来设计电路吧。

第一步,先设计供电电路。

按三菱PLC的模式,输入端的公共(COM)是DC24V的地(GND),所以就把DC24V电源作为供电电源。

单片机需要5V 供电,手上的继电器是DC12V的供电,所以这个供电电路就是24V转成12V再转成5V。

因为只是测试的用途所以仅用最简单的转换方法(目前还算可以用吧)。

 第二步,设计单片机的最小系统。

也就是用12M晶振配合谐振电容
(30P)电路和上电自动复位电路构成。

 第三步,设计开关量输入电路。

这里将仿效三菱PLC的输入,用DC24V
的GND作公共端,经开关返回。

这样就需要使用光耦521-4将DC24V的信号与单片机输入端的5V信号进行隔离转换。

 第四步,设计输出到继电器的电路。

由于我使用的是DC12V的继电器,所以也用了光耦521-4进行隔离转换,然后驱动三极管(9013),用三极管来驱动。

单片机原理及接口技术(C51编程)单片机各种应用设计

单片机原理及接口技术(C51编程)单片机各种应用设计

unsigned long freq;
//定义频率
unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,
0x7d,
0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};
//共阴数码管段码表
void delay_1ms(unsigned int z) { //函数功能:延时约1ms
#define out P2
sbit pos=P0^0;
//定义检测正转控制位P0.0
sbit neg=P0^1;
//定义检测反转控制位P0.1
void delayms(uint);
uchar code
turn[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03};
步进电机是将脉冲信号转变为角位移或线位移的开环控 制元件。
非超载的情况下,电机转速、停止位置只取决于脉冲信 号的频率和脉冲数,而不受负载变化的影响,给电机加一脉 冲信号,电机则转过一个步距角。因而步进电机只有周期性 误差而无累积误差,在速度、位置等控制领域有较为广泛的 应用。
12.1 单片机控制步进电机的设计
12.2 单片机控制直流电机
2. 电路设计与编程
当P3.6=1时,P3.7发送PWM波,直流电机正转。且 可通过“INC”和“DEC”两个按键来增大和减少直流电机 转速。反之,P3.6=0时,P3.7发送PWM信号,直流电机反 转。
因此,增大和减小电机转速,实际上是通过按下 “INC”或“DEC”按键来改变输出PWM信号占空比,控 制直流电机转速。图12-4中驱动电路使用了NPN低频、低 噪声小功率达林顿管 2SC2547。

编写简单PLC程序示例

编写简单PLC程序示例

编写简单PLC程序示例•PLC基本概念与原理•编写简单PLC程序步骤•示例一:电机启停控制程序•示例二:灯光闪烁控制程序目录•示例三:温度控制程序•总结与展望PLC基本概念与原理PLC (Programmable Logic Cont…可编程逻辑控制器,一种专为工业环境应用而设计的数字运算操作电子系统。

要点一要点二发展历程从最初的替代继电器控制系统,到现如今的复杂自动化控制系统,PLC 经历了多个发展阶段,功能不断扩展,性能不断提升。

PLC 定义及发展历程PLC工作原理及组成部分工作原理PLC采用循环扫描的工作方式,即按照用户程序存储器的顺序,逐条执行用户程序,直到程序结束,然后重新返回第一条指令,开始下一轮新的扫描。

组成部分主要包括中央处理单元(CPU)、存储器、输入/输出模块、电源模块、通信接口等部分。

PLC编程语言与规范编程语言PLC的编程语言主要有梯形图(LD)、指令表(IL)、功能块图(FBD)、顺序功能图(SFC)和结构化文本(ST)五种。

编程规范在编写PLC程序时,需要遵循一定的编程规范,如合理命名变量和程序段、使用注释说明程序功能、避免使用未经初始化的变量等。

同时,还需要注意程序的可读性和可维护性,以便后续的调试和修改。

02编写简单PLC程序步骤明确控制需求与功能确定被控对象及其工艺流程了解被控对象的类型、工作原理和工艺流程,明确需要实现的控制功能。

分析控制要求根据工艺流程,分析被控对象的输入、输出信号,以及它们之间的逻辑关系和时间顺序等控制要求。

选择合适PLC型号及硬件配置选择PLC型号根据控制需求和功能,选择合适的PLC型号,包括CPU类型、I/O点数、存储容量等。

配置硬件根据选定的PLC型号,配置相应的电源、输入/输出模块、通信模块等硬件设备。

03分配内部资源根据需要,为PLC 内部寄存器、定时器、计数器等资源进行合理分配。

01设计输入信号确定PLC 需要接收的输入信号类型、数量和来源,为每个输入信号分配一个唯一的地址。

51单片机汇编程序范例

51单片机汇编程序范例

51单片机汇编程序范例(总14页)本页仅作为文档封面,使用时可以删除This document is for reference only-rar21year.March16位二进制数转换成BCD码的的快速算法-51单片机2010-02-18 00:43在做而论道上篇博文中,回答了一个16位二进制数转换成BCD码的问题,给出了一个网上广泛流传的经典转换程序。

程序可见:中的HEX2BCD子程序。

.说它经典,不仅是因为它已经流传已久,重要的是它的编程思路十分清晰,十分易于延伸推广。

做而论道曾经利用它的思路,很容易的编写出了48位二进制数变换成16位BCD码的程序。

但是这个程序有个明显的缺点,就是执行时间太长,转换16位二进制数,就必须循环16遍,转换48位二进制数,就必须循环48遍。

上述的HEX2BCD子程序,虽然长度仅仅为26字节,执行时间却要用331个机器周期。

.单片机系统多半是用于各种类型的控制场合,很多时候都是需要“争分夺秒”的,在低功耗系统设计中,也必须考虑因为运算时间长而增加系统耗电量的问题。

为了提高整机运行的速度,在多年前,做而论道就另外编写了一个转换程序,程序的长度为81字节,执行时间是81个机器周期,(这两个数字怎么这么巧!)执行时间仅仅是经典程序的1/4!.近来,在网上发现了一个链接:,也对这个经典转换程序进行了改进,话是说了不少,只是没有实质性的东西。

这篇文章提到的程序,一直也没有找到,也难辩真假。

这篇文章好像是选自某个著名杂志,但是在术语的使用上,有着明显的漏洞,不像是专业人员的手笔。

比如说文中提到的:“使用51条指令代码,但执行这段程序却要耗费312个指令周期”,就是败笔。

51条指令代码,真不知道说的是什么,指令周期是因各种机型和指令而异的,也不能表示确切的时间。

.下面说说做而论道的编程思路。

;-----------------------------------------------------------------------;已知16位二进制整数n以b15~b0表示,取值范围为0~65535。

一种用51单片机仿真PLC控制的方法

一种用51单片机仿真PLC控制的方法
例如当p06输出信号为低电平使u1初级导通二极管d1点亮光耦初级的电信号转换成光信号再由光信号感应耦合器的次级导通然后次级回?去驱动继电器再由继电器去驱动执?机构
科技创新导报 2010 NO.05 Science and Technology Innovation Herald 一种用 5 1 单片机仿真 P L C 控制的方法
科技创新导报 Science and Technology Innovation Herald
119
本文提出了一种新的用Atmel89c51仿真 PLC控制的方法,允许用户先按梯形图编程, 这对继电器控制较为熟悉的电气技术人员来 说比较方便。由于该仿真电路板价格低廉并 且体积小,可以被开发成产品,也适合于PLC 控制的演示实验。
1 Atmel89c51 单片机仿真 PLC电路原理 1.1 仿真电路板的电路原理分析
为更好的提升本刊的信息技术全面性,我刊现面向各级科技与教育管理部门的领导、科教领域管理人员、 科技教育人员、各类院校的广大师生征集优秀稿件。
投稿须知 1.稿 件 应 具 有 科 学 性 、先 进 性 和 实 用 性,论 点 鲜 明 、论 据 充 分 、数 据 真 实 、逻 辑 严 谨 、文 字 准 确 、语 句 通
光耦初级的电信号转换成光信号,再由光信号 感应耦合器的次级导通,然后次级回路去驱动 继 电 器 ,再 由 继 电 器 去 驱 动 执 行 机 构 。反 之 , 当P0.6输出高电平时,光电耦合器初级截止, 发光二极管熄灭,耦合器次级断开,从而继电 器K1也 不 得 电 。当 P1.0输 出 低 电 平 时 ,耦合 器U1初级导通,使发光二极管D1点亮熄灭动 作与继电器的通断状态是一致的,所以可以将 发光二极管作为反映输出机构状态的指示。 二极管D2并接在继电器线圈旁边,起到保护耦 合器的作用。因为根据继电器的工作特性,其 瞬间关断时在线圈内产生大的感应电动势,所 以 并 接 二 极 管 起 到 续 流 作 用 。P 0 . 7 的 输 出 电 路 由 R 8 ~ R 1 0 、发 光 二 极 管 D 2 、光 电 耦 合 器 U2和继电器K2组成,其工作原理的分析也是 一 样 的 。不 过 图 1中 只 用 了 P 0 . 6和 P0.7 两 个 口 线,留下的P0.0~P0.5还可以接6个输出驱动 电路,如果需要的话,可以参照图1进行扩充。 1.2 仿真电路板与被仿真 PLC 的输入 / 输出端 口之间的对应关系

51单片机100例程序设计(可编辑)

51单片机100例程序设计(可编辑)

51单片机100例程序设计100例程序设计范例汇总第一章 4【实例1】使用累加器进行简单加法运算:4【实例2】使用B寄存器进行简单乘法运算: 4【实例3】通过设置RS1,RS0选择工作寄存器区1: 4【实例4】使用数据指针DPTR访问外部数据数据存储器: 4 【实例5】使用程序计数器PC查表: 4【实例6】if语句实例: 4【实例7】switch-case语句实例: 4【实例8】for语句实例: 4【实例9】while语句实例: 5【实例10】do…while语句实例: 5【实例11】语句形式调用实例:5【实例12】表达式形式调用实例: 5【实例13】以函数的参数形式调用实例: 5【实例14】函数的声明实例: 5【实例15】函数递归调用的简单实例:5【实例16】数组的实例:6【实例17】指针的实例:6【实例18】数组与指针实例: 6【实例19】P1口控制直流电动机实例 6第二章8【实例20】用74LS165实现串口扩展并行输入口8【实例21】用74LS164实现串口扩展并行输出口10【实例22】P0 I/O扩展并行输入口 12【实例23】P0 I/O扩展并行输出口 12【实例24】用8243扩展I/O端口12【实例25】用8255A扩展I/O口14【实例26】用8155扩展I/O口19第三章26【实例29】与AT24系列EEPROM接口及驱动程序26【实例30】EEPROM X5045 接口及驱动程序30【实例31】与铁电存储器接口及驱动程序33【实例32】与双口RAM存储器接口及应用实例35【实例33】与NANDFLASH(K9F5608)接口及驱动程序35 第四章43【实例34】独立键盘控制43【实例35】矩阵式键盘控制44【实例36】改进型I/O端口键盘46【实例37】PS/2键盘的控制 49【实例38】LED显示53【实例39】段数码管(HD7929)显示实例54 【实例40】16×2字符型液晶显示实例 55【实例41】点阵型液晶显示实例61【实例42】LCD显示图片实例63第五章70【实例43】简易电子琴的设计70【实例44】基于MCS-51单片机的四路抢答器71 【实例45】电子调光灯的制作76【实例46】数码管时钟的制作81【实例47】LCD时钟的制作96【实例48】数字化语音存储与回放103【实例49】电子标签设计112第六章120【实例50】指纹识别模块121【实例51】数字温度传感器121第七章124【实例53】超声波测距124【实例54】数字气压计125【实例55】基于单片机的电压表设计132【实例56】基于单片机的称重显示仪表设计133 【实例57】基于单片机的车轮测速系统136第八章138【实例58】电源切换控制138【实例59】步进电机控制140【实例60】单片机控制自动门系统141【实例61】控制微型打印机144【实例62】单片机控制的EPSON微型打印头144 【实例63】简易智能电动车145【实例64】洗衣机控制器149第九章152【实例65】串行A/D转换152【实例66】并行A/D转换153【实例67】模拟比较器实现A/D转换154【实例68】串行D/A转换155【实例69】并行电压型D/A转换156【实例70】并行电流型D/A转换156【实例71】接口的A/D转换157【实例72】接口的D/A转换161第十章164【实例73】单片机间双机通信164【实例74】单片机间多机通信方法之一166【实例75】单片机间多机通信方法之二171【实例76】 PC与单片机通信176【实例77】红外通信接口178【实例79】单片机实现PWM信号输出180【实例80】实现基于单片机的低频信号发生器182 【实例81】软件滤波方法183【实例82】FSK信号解码接收186【实例83】单片机浮点数运算实现187【实例84】神经网络在单片机中的实现192【实例85】信号数据的FFT变换194第十二章198【实例86】总线接口的软件实现198【实例87】SPI总线接口的软件实现200【实例88】1-WIRE总线接口的软件实现205 【实例89】单片机外挂CAN总线接口207【实例90】单片机外挂USB总线接口210【实例91】单片机实现以太网接口214【实例92】单片机控制GPRS传输221【实例93】单片机实现TCP/IP协议223第十三章229【实例94】读写U盘229【实例95】非接触IC卡读写234【实例96】SD卡读写 238【实例97】高精度实时时钟芯片的应用242【实例98】智能手机充电器设计247【实例99】单片机控制门禁系统248第一章【实例1】使用累加器进行简单加法运算:MOV A,#02H ;A←2ADD A,#06H ;A←A+06H【实例2】使用B寄存器进行简单乘法运算:MOV A,#02H ; A←2MOV B,#06H ; B←6MUL AB ; BA←A*B 6*2【实例3】通过设置RS1,RS0选择工作寄存器区1:CLR PSW.4 ; PSW.4←0SETB PSW.5 ; PSW.5←1【实例4】使用数据指针DPTR访问外部数据数据存储器:MOV DPTR, #data16 ; DPTR←data16MOVX A, @ DPTR ; A← DPTRMOVX @ DPTR, A ; DPTR ←A【实例5】使用程序计数器PC查表:MOV A, #data ;A←dataMOVC A, @ A+DPTR ; PC← PC +1 ,A← A + PC 【实例6】if语句实例:void mainint a,b,c,min;printf "\n please input three number:" ;scanf "%d%d%d ",&a,&b,&c ;if a b&&a c printf "min %d\n",a ;else if b a&&b c printf "min %d\n",b ;else if c a&&c c printf "min %d\n",c ;else printf "There at least two numbers are equal\n" ;【实例7】switch-case语句实例:void mainint num; printf "input one number:" ;scanf "%d",& num ;switch numcase 1: printf "num %d\n", num ;break;case 2: printf "num %d\n", num ;break;case 3: printf "num %d\n", num ;break;case 4: printf "num %d\n", num ;break;default: printf "The number is out of the range\n", num ;【实例8】for语句实例:void mainfor int a 10;n 0;a --printf "%d",a ;【实例9】while语句实例:void mainint i 0;while i 10 i++;【实例10】do…while语句实例:void mainint i 0;do i++;while i 10 ;【实例11】语句形式调用实例:void mainint i 0; while i 10 i++; … … Sum ; /*函数调用*/【实例12】表达式形式调用实例:void mainint a,b,i 0; while i 10 i++; … …i 4*Sum a,b ; /*函数调用*/【实例13】以函数的参数形式调用实例:void mainint a,b,c,i 0; while i 10 i++; … …i c,Sum a,b ; /*函数调用*/【实例14】函数的声明实例:void mainint int x,int y ; /*函数的声明*/ int a,b,c,i 0; while i 10 i++; … … i c,Sum a,b ; /*函数调用*/【实例15】函数递归调用的简单实例:void funint a 1, result,i;for i 0;i 10;i a+I;result fun ; /*函数调用*/return result;【实例16】数组的实例:void mainchar num[3] [3] ’’,’#’,’’ , ’#’,’’,’#’ , ’’,’#’,’’ ; /*定义多维数组*/int i 0,j 0;for ;i 3;i++for ;j 3;j++ printf “%c”,num[i][j] ;printf “/n” ;【实例17】指针的实例:void mainint a 3,*p;p &a; /*将变量a的地址赋值给指针变量p*/printf “%d,%d”,a,*p ; /*输出二者的数值进行对比*/【实例18】数组与指针实例:void mainint i 3,num[3] 1,2,3 ,*p;p num; /*将数组num[]的地址赋值给指针变量p*/result p,3 ; /*函数调用,计算数组的最大值*/【实例19】P1口控制直流电动机实例sfr p1 0x90;sbit p10 p1^0;sbit p11 p1^1;void mainint i, m;int j 100;int k 20;// 正快转for i 0; i 100; i++P10 1;for j 0; j 50; j++m 0;P10 0;for j 0; j 10; j++//正慢转for i 0; i 100; i++P10 1;for j 0; j 10; j++ m 0p10 0;for j 0; j 50; j++ m 0// 负快转for i 0; i 100; i++p11 1;for j 0; j 50; j++p11 0;for j 0; j 10; j++m 0;// 负慢转for i 0; i 100; i++p11 1;for j 0;j 10;j++m 0;p11 0for j 0; j 50; j++ m 0;第二章【实例20】用74LS165实现串口扩展并行输入口(1)函数声明管脚定义//#includesbit LOAD P1^7;//用P1^7控制SH/ 管脚(2)串口初始化函数UART_init//// 函数名称:UART_init// 功能说明:串口初始化,设定串口工作在方式0 //void UART_init voidSCON 0x10;//设串行口方式0,允许接收,启动接收过程ES 0;//禁止串口中断(3)数据接收函数PA//// 函数名称:PA// 输入参数:无// 输出参数:返回由并口输入的数据// 功能说明:接收八位串行数据//unsigned char PA voidunsigned char PA_data;LOAD 0;//当P1.7输出低电平,74LS165将并行数据装入寄存器//当中LOAD 1;//当P1.7输出高电平,74LS165在时钟信号下进行移位UART_init ;//74LS165工作在时钟控制下的串行移位状态while RI 0 ;//循环等待RI 0;PA_data SBUF;return PA_data;//返回并行输入的数据(1)函数声明管脚定义//#includesbit a7 ACC^7;sbit simuseri_CLK P1^6;//用P1^6模拟串口时钟sbit simuseri_DATA P1^5;//用P1^5模拟串口数据sbit drive74165_LD P1^7;//用P1^7控制SH/ 管脚(2)数据输入函数in_simuseri//// 函数名称:in_simuseri// 输入参数:无// 输出参数:data_buf// 功能说明:8位同位移位寄存器,将simuseri_DATA串行输入的数据按从低位到// 高位// 保存到data_buf//unsigned char in_simuseri voidunsigned char i;unsigned char data_buf;i 8;doACC ACC 1;for ;simuseri_CLK 0; ;a7 simuseri_DATA;for ;simuseri_CLK 1; ;while --i! 0 ;simuseri_CLK 0;data_buf ACC;return data_buf ;(3)数据输出函数PAs//// 函数名称:PAs// 输入参数:无// 输出参数:PAs _buf,返回并行输入74LS165的数据// 功能说明:直接调用,即可读取并行输入74LS165的数据,不需要考虑74LS165的// 工作原理//unsigned char PAs voidunsigned char PAs_buf;drive74165_LD 0;drive74165_LD 1;PAs_buf in_simuseri ;return PAs_buf ;【实例21】用74LS164实现串口扩展并行输出口单片机串口驱动74LS164的程序主要包括函数声明管脚定义部分、串口初始化函数以及数据发送函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51单片机DIY做PLC编程
有朋友想定制一个净水机控制器,有一些独特的功能要增加,但是商品控制板没有这样的功能,问我能否做一个,我觉得单片机完全能满足这种简单的控制需要,上手开始编程序时候突然感到,用PLC逻辑编这种功能是非常简单轻松的,而如果用汇编或C编却感觉有点棘手,编程效率不高,所以想为何不在单片机上实现PLC的逻辑呢?
上网搜索尝试看能否找到合适的程序下载来稍微改改就能用的呢?方案几年前就有了,实际上是利用三菱的低档PLC编程软件编辑好梯形图,存盘后用专用的格式转换工具转换成HEX单片机烧写文件烧进去,尝试下载三菱PLC工具软件,但是在我的WIN7-64位系统上不能正常工作,好容易换了系统装好开发工具,但是初次上手这款开发工具,界面挺复杂的,懒得研究各个按钮的使用,由于是单片机的硬件,对于程序的编制和转换有很多限制条件,否则是转换不成功的,嫌麻烦,放弃!
某宝倒是有百元PLC板出售,但是为了这么个简单的东西专门买个全功能板子有点浪费,而且其编程软件仍然是三菱的盗版软件,算了,再想办法把。

由于工作中经常接触PLC程序,对其工作原理也略知一二,网上也有相关的说明介绍,其实就是三个主要步骤,第一步扫描IO输入,第二步执行逻辑,第三步输出逻辑到IO,很简单的,最早PLC也是用单片机实现的,我为何不用汇编在51上搭建一个架构,简单的逻辑编制进去就能运转呢?
其中逻辑执行步骤还是有点意思的,需要把PLC逻辑翻译成单片机的汇编语言执行,这块开始也没有把握,后来搜索到一篇百度文章,介绍了一下三菱PLC逻辑是如何翻译成汇编的,我看了下估计其实是利用反汇编工具把HEX反编译成的ASM代码,并不清晰明了,而且还带着反汇编时候的行号,仅供参考了。

搜索结果中也有几篇论文,涉及到在51单片机上实现PLC逻辑的内容,但是那些论文都是充数的,仅仅几个IO逻辑,没有什么定时器,计数器功能的体现,哎!仅供参考!
看来这个PLC系统还是需要自己写了!OK!既然决定自己重写,那就开工吧!利用春节休假时间,编制了如下ASM51汇编PLC代码:
代码主要架构如下:
1、IO定义部分:根据所使用的单片机IO口数量,任意指定多少个I多少个O,那几个脚是I,哪几个是O都可以任意指定,在这个51系统里面设计了最大32个I,32个O,占用64个位寻址区域,其实用不到那么多,也可以分配给其它需要的标志位用,因为51系统总可位寻址地址只有128位,需要仔细分配.
2、位寻址变量定义(包括各类标志位,临时变量寄存器等等)目前设计了8个计时器的Timer DN, Timer EN,共16位,8个计数器的counter reset 和counter DN 标志位共16个,专用于上升沿下降沿检测的标志位4对,占用8个,剩余用于临时变量,这些地址分配在这块变量
定义区域可以根据需要任意调整
3、内存规划,包括堆栈区的设置,定时器,计数器的累加值和预设值地址等等,目前初步定义8个计数器的当前计数值和预设值,8个计时器的当前计数值和预设值,共占用32个内存地址,也可根据需要调整,51单片机片内总的用户可用内存地址包括堆栈区只有128个,实际去除位寻址区和堆栈区可用的估计只有80个左右,不过对于小程序应该够用的。

没必要去增加成本扩展RAM
4、上电初始化,包括0.01秒微定时器设置,内存清零,中断设置,如果想增加串口功能也是可以的,51本来就有两个定时器,无非多写一个串口中断服务程序就是了。

5、微定时器中断服务程序编写,单片机每0.01秒定时中断时执行,进行内存时基标志位刷新,用于提醒主程序相应时间到了,基本的时基设计了0.01秒,0.1秒,1秒,10秒,1分钟,1小时,1天,1周八个时间标志位,其实真没必要,不过自己编写架构就是好玩,想设计几个就设计几个哈哈!
6、下面是主要PLC逻辑,执行时是不停扫描循环执行的,与真实的PLC运行结构是一样的,当然咱们编的就要简单许多了,没有那么多的功能。

而且用汇编编写执行效率要比C 高,目前1K代码的汇编程序可以写好多,而如果用C写再编译就会大许多,很多时候廉价
小单片机就装不下了。

7、扫描开始是对定时器计数器处理,如果某计时器的相应时基标志位置位,则处理对应程序用定时器的状态判断与设置,计数器内存累加,状态判断与设置,用于主逻辑执行部分执行;对于计数器主要是判断是否有计数器复位请求以及进行当前计数值与预设值是否相等判
断,置位相应标志位.
8、输入扫描,这块很简单,就是把输入IO口复制到内存相应区域内;
9正式逻辑执行:这块直接就是按照梯形图行的概念,每一个梯形图行,就是一段汇编代码,为了翻译时候方便,直接把逻辑就在注释行内形象的用符号画出来。

逻辑的翻译还是有点技巧,实现了基本IO输入,与或非逻辑,定时器以及计数器功能,外加上升沿下降沿判断等功能,这些基本的PLC功能都能在这个小架构里面实现,尽管不是十分完美例如定时器状态更新的时效性由于架构问题还不能达到每次扫描更新,对于上升下降沿的判断需要更多的内存和语句实现等等,但是对于简单的应用还是没有问题的.
10逻辑输出,这块也很简单,就是把对应的逻辑运算结果输出到单片机的IO口即可.
11后期操作部分,也就是每次扫描运算结束后还有余力进行其它需要功能的输出,这块在真正PLC里面也是很重要的,应该会进行逻辑效验,远程通讯等功能,咱这个就都简化掉了,仅仅为了测试扫描时间对一个内存变量进行增一操作而已,可以调用看看扫描周期时间是否超过
了最小定时器时间等等辅助功能. 实测12M时钟0.01秒执行了这个小逻辑多达70多遍!
架构有了,具体逻辑要怎么写,最好还是在PLC模拟器上先试着编写一下,功能没问题了
再抄到我们的单片机里面来,进行逐句翻译,因为单片机汇编语言的调试还是很麻烦的,毕
竟不直观,还是在PLC模拟器里面做好了再搬进来比较好。

Keil里面编译成HEX文件后可以直接刷写进单片机使用了,真正用之前最好还是要根据单片机的晶振时钟,再调整一下微定时器的定时参数,尽量符合0.01秒的要求,不要偏差太大,还有一种方法是利用proteus软件仿真硬件运行也是不错的。

通过反复修改汇编程序,通过仿真测试到目前为止我们只是完成了PLC芯片逻辑的软件编写,下面就可以烧写进51内核的单片机内实际运行了,这里我使用的是STC的国产单片机,15W408系列,DIP20替换AT89C2051还能多增加几个IO脚,仅仅几元,价格便宜,1T内核,性能强劲(之前写的0.01秒扫描70多次是在仿真环境下,12T的89C2051达到的性能,如果使用STC的1T系列要注意实际运行速度会增加12倍,达到0.01秒扫700多次,有时候太快了也会引起烦恼呵呵),IO可以设定为强推挽,驱动力强,串口直接下载程序,编程方便,对于非专业应用,给DIYer做点小东西还是很合适的.使用STC专用下载线(仅仅十几块,比别的芯片下载编程器可便宜多了,甚至使用5元的USB转TTL串口线也能用,只是需要手动断电一次而
已,专用的下载线增加了自动断电功能,使下载更方便些)下载进芯片,得到一只带程序的芯片.
利用面包板搭建测试电路实际验证逻辑功能,如果逻辑不满意或者定时时间不合适还可以回去修改程序,重新编译下装,直到满意为止,为了能够应用到实际环境中,还需要为它配上电源电路,输入按键开关,输出驱动三极管或继电器等硬件才能和实际的应用环境配合使用,发挥预想的作用。

实际应用中对于抗干扰还是需要花费一些心思的,干扰来自一下几个方面:
1电磁阀动作时候产生的电磁脉冲和反电动势,这个可以使用二极管做续流,来消除电磁阀断电反电动势脉冲,通过增加光耦进行输出隔离,也可以提高抗干扰性能;
2 对于开关输入通道要考虑单片机输入电阻是比较高的,长线容易引入外部干扰,这个问题可以通过在输入引脚外加1K上拉电阻的方法来降低输入阻抗,达到抗干扰的目的;
3 电源也是干扰源,因为大功率电机和电磁阀的动作都会造成24V电源的瞬间剧烈波动,尽管单片机的电源消耗不大但是很容易因干扰而复位或者造成输入输出不正常等现象,因此电源滤波也很重要,通过示波器可以观察到当电机或电磁阀动作时,单片机5V电源的波动情况,通过采取增加π型LC滤波,可以极大降低电源引起的干扰.
4 电磁辐射也要考虑,单片机控制板本体最好增加金属外壳并接地,抵抗电机电磁阀或厨房用电设备的外部干扰,这就是为什么我喜欢收集金属糖果糕点盒的原因,呵呵!
对于DIYer来讲,有时候想法挺好,试验也成功,但是实际装机后却失败了,这些可能不是我们做的不好,实际是没有考虑到复杂的工作环境,真正的产品为什么比我们DIY的成本高,其主要方面就是考虑的实际工作现场的复杂性,真正的核心控制可能很简单,但是周边的各种保护很复杂,甚至接错线了也要考虑到,成本和可靠性就成正比了,希望朋友们DIY快乐!。

相关文档
最新文档