找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14097|回复: 3
打印 上一主题 下一主题
收起左侧

基于51单片机的自动加料机控制系统设计

[复制链接]
跳转到指定楼层
楼主
在现代科学技术的许多领域中,自动控制技术起着愈来愈重要的作用。并且,随着生产和科学技术的发展,自动化水平也越来越高。自动控制利用控制装置使被控对象的某个参数自动地按照预定的规律运行,大大提高了工作的效率,使整个生产过程又快又稳。

本设计主要是研究基于单片机的自动加料机控制系统,控制系统的控制器由单片机AT89C51及其扩展电路组成,单片机控制LCD显示器以及控制电机等执行机构来实现整个控制系统的工作。这个控制系统可以根据送料工艺的需要,设计两条生产线的满料、送料、排料等整个加工流程的参数值。这样大大的提高了控制系统和电机的工作效率,从而实现自动化加料。


1  绪论
1.1  课题背景

随着信息技术的迅猛发展、市场经济的发展,国内、国际市场竞争日益激烈,产品更新更为迅速,尤其是随着高新技术日新月异,产品的类型、工艺外形越来越复杂,精度要求越来越高,再加上企业经营与发展必会面对劳工的短缺、人工成本上要省力化、合理化的发展趋势!传统的手工加料不仅费时费力、工作效率低,且其安全状况令人堪忧,因此已不能满足社会发展的要求。于是机械加料机就应运而生。机械加料机是借助于机器运动的作用力加力于材料,对材料进行运送运输,相对于传统人工手动加料,省去了大部分人力用于材料的运送运输,大大提高了工作效率。但其控制与监测却还是需要花费大量的人力 ,安全性能较传统手工加料而言反而更低,一旦发生事故,造成的后果更为严重。

在变化中求发展、在发展中求变化是一个企业长久稳定发展的秘诀。自动加料机伴随着工业生产的规模扩大和对产品质量的更高追求不断发展,企业为追求更大的效益和更高的产品竞争能力也促进了自动控制技术的发展,国外第一套自动化生产设备是上世纪70年代在欧洲国家出现,自从它已出现人们就察觉到它巨大价值,自动化控制得到了飞速的发展,到目前为止已经经历了三个不同的发展阶段:

(1)连续自动生产阶段:这个阶段是自动化生产控制系统的萌芽阶段主要是运用模拟量PID调节等控制技术和自动逻辑控制技术,这些技术甚至是在二战时期就已经被被简单应用,只不过在那个时候没有给系统的结合起来。该阶段主要采用继电逻辑控制技术进行生产过程控制和工业二次仪表进行状态监测,由于控制系统可靠性不高控制技术落后,在工艺方面产品状态参数监测方面也不够精细,加之检测手段落后,在生产过程还需要大量人力去参与去控制大部分单元,表面上省事,但是生产的稳定性和产品质量都没有办法得到有效的控制。

(2)基于PLC控制的自动化生产阶段:随着计算机技术水平不断的发展,简单的PID控制理论发展到了模糊PID控制这就为技术革新创造了有力的条件,在这样的大环境下面基于PLC控制的自动化生产系统就诞生了。这样的控制系统比着原有自动化柔性系统进步了很多,很多处理工作就不需要认为的参与了;同时计算机技术也促进了检测技术的发展,因此在这个阶段自动化控制系统能够提高生产效率也能够对产品的质量进行保障。

(3)计算机技术控制的自动化生产阶段:数字互联网时代,一个小的电脑或者平板就可以对车间的生产进行控制操作,这是因为计算机技术以及更多的通讯技术都加入到了控制技术里面。不得不说的是现在的传感器技术也发展非常迅速,在这样的情况下我们自动化设备需要的人力就更少了,生产效率也大幅度提高,关键是生产产品的质量也更加优良。

而现在我国自动化程度仍然不高,生产速率依然较低。这一方面是由于我国人口众多、劳动力便宜,很多企业不愿意将有限的资金投入到无限的自动化研究更新中去;另一方面也是由于自动化研制成本较高、适用面窄,国内很多企业虽有需求但是由于资金不足而不能投入。但是随着我国对外贸易的日益增加和市场经济体制的完善,国内外竞争越来越激烈,企业对自动化的需求也必定会日趋增长。我国企业由于引进国外的先进的设备价格又过于昂贵,因此要发挥自己的主观能动性尽自己的能力自主研发或者引进消化吸收的基础上创新研发出能自己使用的自动加料机,现在国内已经有很多家厂家可以生产这个自动加料的装置,且价格公道,具有很大的市场发展潜力,必定会得到一定的发展。

1.2  课题意义

随着单片机和传感器技术的迅速发展,自动加料机领域也得到了很好的发展,自动加料机的发展使传统的手工操作面临严峻的挑战。从加工生产率来看,手工加料过程大多属于劳动密集型,生产率在很大程度上取决于生产过程对人的依赖性,它是工人执行某一具体操作所花费时间的函数,其劳动量在产品制造总劳动量中占有相当高的比例。随着国际竞争的日益激烈,产品生产周期不断的缩短、种类的日益增加、质量的要求更高、相应的要求产品交货时间越来越短短、劳动成本的增加。人类手工操作,已经不能与当前的社会经济条件相适应。在生产中作为一个生产元素的出现,手工操作不具备判断准确、灵巧,并赋以较大作用力的这些特性,又不能保证工作的一致性和稳定性,另一方面,从市场经济的现实出发,人工操作与加工功能可靠、质量一致性好、价格合理的要求也极不相适应。这就对企业提出了高要求,即:生产率和产品质量高、稳定,生产加工成本不断降低。所以,加料系统的自动化是生产制造过程中需要解决的关键技术。

加料自动化的重要性还在于促进产品制造系统的整体优化,生产率得以全面提高。自动加料不会因为工人的疲劳、疏忽、情绪、技术不熟练等因素的影响而造成产品质量缺陷或不稳定。有些操作需要洁净空气、惰性气体、真空等特殊环境;有些操作人类难

以接近。因此,从工人劳动保护方面考虑,发展自动加料技术尤为重要,也是满足社会、市场及技术发展过程中产品不断更新的需要。

特别是目前操作过程中的防静电、操作疲劳、协调作业等因素使得手工作业存在了很大的局限性,如容易发生误操作,生产不合格等等,使得生产率大大下降,所以对于加料自动化的改造将会大大提高产品的生产效率以及产品的成品率及公司的竞争能力,同时降低公司的生产成本,对于公司发展具有重大意义。

同时,研究本课题对于个人也有很重要的意义。它需要重点学习单片机的应用知识,掌握C语言及汇编语言用于编程,然后将之前所学其他专业课如《传感器与检测技术》的知识综合在一起。从原理设计到方案论证再到选材、硬件设计和软件设计,每一步都需要查阅大量资料,不断地发现问题、分析问题和解决问题。该课题的研究不仅能巩固以前所学的专业知识,而且能锻炼我收集资料、解决问题及实际动手的能力,更重要的是能够学以致用,为我步入社会走上工作岗位打下坚实的基础。

1.3  课题内容

本次设计主要做了如下几方面的工作:一是确立系统的总体功能设计方案;二是对系统的硬件电路和软件系统的设计;三是单片机及通信接口的硬件电路及软件系统的设计;四是对连接单片机的上位管理计算机软件系统的设计思路、工作原理和实现方法的阐述。

本文将LCD显示技术、传感器技术及信息处理技术等相互融合,将自动加料的多种参数检测和单片机控制理论相结合,提出一种切实可行的自动加料机控制系统,可以全面、实时、自动地对系统数据进行自动记录、存储和处理,并将有关信息根据现场实际情况,采用最有效方式送入计算机进行处理,并可对加料系统进行远程控制。满足了对加料工业生产实行全面、实时、长期检测的要求。与传统技术相比,本系统具有以下优点:

(1)本设计用一台电机就可以控制两条生产线提高了劳动生产率;

(2)单片机的设计提高了系统的可控性、可靠性及实时性;

(3)可对生产线各种状态的时间进行设置,实用性更强。


2  方案选择
2.1  方案选择

   在进行系统设计的时候重心放在加料机的自动化上,于此设想了基于51单片机的方案与基于PLC控制的方案。下面对两种方案进行说明比较。

   PLC即可编程逻辑控制器,是工业控制计算机。采用梯形图、助记符、功能图等编程语言,完成逻辑运算、顺序控制、记数、定时、计算及模拟量处理等功能。单片机由最简单的输出/输入构成。如输出用LED,输入用开关。并且能实现最基本的运行条件,如应有供电、时钟附属电路等。两种方案有如下区别:

(1)PLC比单片机更加复杂,它是在单片机的基础上集成许多其他控制单元组成的;

(2)单片机在在在简易自动化研究系统里面更容易实现而且成本比较小;

因此决定选用单片机做此次设计。

2.2  单片机选型
2.2.1  单片机概述

近年来,随着超大规模集成电路的出现,单片微型计算机发展异常迅猛。在电子应用技术领域,如果说60年代面临的是晶体管技术;70年代面临的是集成电路技术;80年代面临的是单板机技术的话,那么可以讲,单片机技术无疑将是90年代最活跃的新一代电子应用技术。在当前以应用电子技术为代表的高新技术改造系统工业方面,在机电一体化领域,单片机技术必将显示出强大的生命力。单片机功能强、体积小、使用方便、性价比高等优点,获得很大的应用,通用的8位单片机而言,就有50多个系列数百种品种,目前世界上比较著名的部分8位单片机生产厂家和部分机型如下:

Intel(美国英特尔)公司:MCS-51/96及其增强系列

NS(美国国家半导体)公司:NS8070系列

RCA(美国无线电)公司:CDP1800系列

TI(美国得克萨斯仪器仪表)公司:TMS700系列

Cypress(美国Cypress半导体)公司:CYXX系列

Rockwell(美国洛克威尔)公司:6500系列

Motorola(美国摩托罗拉)公司:6805系列

Fairchild(美国仙童)公司:FS系列及3870系列

Zilog(美国齐洛格)公司:Z8系列及SUPER8系列

Atmel(美国 Atmel)公司:AT89系列

National(日本松下)公司:MN6800系列

Hitachi(日本日立)公司:HD6301、HD65L05、HD6305系列

NEC(日本电气)公司:UCOM87、(UPD7800)系列

Philips(荷兰菲利浦)公司:P89C51XX系列

尽管单片机的种类很多但是在我国使用最多并且最广泛的还是51核系列的单片机如Intel公司的MCS-51和美国的89C51。

MCS-51系列单片机包括基本型8031/8051/8751,由于8031片内没有程序存储器;8051是一个程序不超过4KB的小系统而8751是用4KB的EPROM取代了8051的4KBROM作为程序存储器但还是太小了因此均不选用。

与MCS-51系列相比AT89C51/AT89S51单片机片内的4KB的Flash存储器取代了4KB的EPROM可重复编程,功能强大性价比较高且价格较低,因此本设计就选用AT89C51。AT89C51 是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含4KBYTES的可反复擦写的只读程序存储器(PEROM)和128BYTES的随机存取数据存储器(ROM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51 指令系统,片内置通用8 位中央处理器(CPU)和Flash 存储单元。功能强大AT89C51 单片机符合上述选择原则,可提供许多高性价比的应用场合,可灵活应用于各种控制领域[1]。

2.2.2 AT89C51单片机

(1)AT89C51功能特性概述

AT89C51内部结构框图如图1所示。AT89C51 提供以下标准功能:4K 字节Flash 闪速存储器,128 字节内部RAM,32 个I/0口线,两个16 位定时/计数器,一个5 向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。同时,AT89C51 可将至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。空闲方式停止CPU 的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续它的工作。掉电方式时保存RAM中的全部内容,但振荡器禁止其他所有部件工作并停止工作直到下一个硬件复位[1]。

                               P0.0~P0.7                P2.0~P2.7

            


图1 AT89C51内部结构框图

(2)AT89C51引脚功能介绍

AT89C51单片机为40引脚双列直插式封装。其引脚排列和逻辑符号如图2所示。

P0口(39-32引脚):P0口是一组8位漏极开路型双向I/O,也即地址/数据总线复用口。对端口写“1”可作为高阻抗输入端用及 在访问外部数据存储器或程序存储器时,作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路。这组口线在访问期间激活内部上拉电阻,分时转换地址(低8位)和数据总线复用[2]。

P1口(1-8引脚)P1口是一个带有内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”的时候,通过内部的上拉电阻把端口拉到高电平,然后此时可作输入口。因为内部存在上拉电阻,作输入口使用时,某个引脚被外部信号校验期间,P1接收低8位地址[2]。

P2口(21-28引脚)P2口是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,此时可作输入口,通过内部的上拉电阻把端口拉到高电平。同时在访问外部程序存储器或16位外部数据存储器的地址(例如执行MOVE @DPTR指令)时,P2口送出高8位地址数据。在访问8位地址的外部数据存储器(例如执行MOVX @RI指令)时,P2口线上的内容(也即特殊功能寄存器(SFR)区总R2寄存器的内容),在整个访问期间不改变[2]。

P3口(10-17引脚):P3口是一组带有内部上拉电阻的8位双向I/O口,P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口[2]。同时更重要的用途是它的第二功能,如下表所示:

表1  P3口第二功能

端 口 引 脚
         第  二  功  能
P3.0
RXD  (串行输入口)
P3.1
TXD  (串行输出口)
P3.2
(外中断0)
P3,3
(外中断1)
P3.4
T0(定时/计数器0)
P3.5
T1(定时/计数器1)
P3.6
(外部数据存储器写选通)
P3.7
(外部数据存储器读选通)

RST(9引脚)复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将单片机复位。

ALE/

(30引脚)当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。即使不访问外部存储器。ALE仍一时钟振荡频率的1/6输出固定的正脉冲信号,因此它可对外输出时钟或用于定时目的。但要注意的是:每当访问外部数据存储器时将跳过一个ALE脉冲[2]。

(29引脚)程序存储允许( )输出是外部程序存储器的读选通信号,当AT89C51由外部程序存储器取指令(或数据)时,每个机器周期两次有效,即输出两个脉冲,在此期间,当访问外部数据存储器,这两次有效的信号不出现[2]。

EA/Vpp(29引脚):外部访问允许,使CPU仅访问外部程序存储器(地址为0000H--FFFFH),EA端必须保持低电平(接地)。需要注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。如EA端为高电平(接Vcc端),CPU则执行内部会锁存EA端状态[2]。

XTAL1、XTAL2(19、18引脚):当使用单片机内部振荡电路时,用来接石英晶体和微调电容。当采用外部时钟时,XTAL2引脚接地,XTAL1接片外振荡脉冲输入(带上拉电阻)[2]。

2.3  物位传感器的选择

物位是指贮存容器里密度不同的物体形成的分界面,物位是保证生产安全和设备安全的重要系数。它可以确定容器中的贮料数量,以保证连续生产的需要或经济核算;其次为了监视或控制容器的物位,使它保持在规定的范围内;最后可以对它的上下极限位置进行报警,以保证生产安全、正常运行。同时考虑到粉尘的类型、尺寸、是否振动有无粘性等,因此要特别注意选择物位传感器的类型。

2.3.1  电容式物位传感器

原理是当罐内放入被测物料时, 由于被测物料介电常数的影响, 传感器的电容量将发生变化, 电容量变化的大小与被测物料在罐内高度有关, 且成比例变化。检测出这种电容量的变化就可测定物料在罐内的高度。

利用电容式物位传感器,当环境温度、湿度变化时,它们的介电常数随之改变,产生误差。这种误差虽可用后续电路加以补偿(如采用与测量电桥相并联的补偿电桥),但无法完全消除。而且传感器内电极表面不便经常清洗,应加以密封,用以防尘、防潮。若在电极表面镀以极薄的惰性金属(如铑等)层,则可代替密封件起保护作用,可防尘、防湿、防腐蚀,并在高温下可减少表面损耗、降低温度系数,但成本较高。传感器要密封以防止水分侵入内部而引起电容值变化和绝缘性能下降。传感器的壳体刚性要好,以免安装时变形且需用高频电路。 同时也比较麻烦,因此不予选用。

2.3.2  浮力式物位传感器

利用漂浮于液面上的浮标或浸没于液体中的浮筒对液位进行测量的。当液位变化时,前者(恒浮力式)产生相应的位移,而所受到的浮力维持不变,后者(变浮力式)则发生浮力的变化。因此,只要检测出浮标的位移或浮筒所受到的浮力的变化,就可以知道液位的高低。

但是由于其比较适用于液体的检测,如果是固体,半固体就不是很好用了,适用范围较窄因此不选用这种。

2.3.3  阻力式物位传感器

阻力式物位传感器是利用物料对机械运动所呈现的阻挡力的特点来构成各种料位传感器。

  • 重锤探测法:传感器放置仓顶,重锤由电机通过不锈钢带或钢丝绳牵引吊入在仓内,仪表控制传感自动定时对料位进行探测,每次测量时重锤从仓顶起始位置开始下降,碰到料面立即返回到仓顶等待下一次测量。仪表通过对重锤下降过程传感信号的处理可得到仓顶到料面的距离hl,仓高H是由用户预置的,这样用仓高H减去hl便可得出料位高度h=H-hl,仪表直接显示料位高度(h)。但这种方法属于数字传感器,虽然采样是周期性的,但是对时间而言不连续,因此不采用。
  • 旋桨或推板法:利用微型电机做驱动装置,传动轴与离合器相连接,当未接触物料时,电机正常运转,当叶片接触物料时,电机停止转动,检测装置输出一接点信号,同时切断电源停止转动。当物料下降时叶片所受阻力消失,检测装置依靠扭力弹簧恢复到原始状态。针对不同比重物料扭力大小可以调节。这类应用较少也不选用。
  • 音叉法:音叉式物位传感器的工作原理是通过安装在音叉基座上的一对压电晶体使音叉在一定共振频率下振动。音叉的振幅和频率将发生突变,当音叉与被测介质相接触时,智能电路将对此进行检测并把这种变化转换为一个开关信号。音叉式物位传感器具有使用寿命长、性能稳定、安全可靠等优点,也正因它的这诸多优势,决定着音叉式物位传感器具有了适应性强(被测介质不同的电参数、密度对测量均不产生影响)、不需调校(无论测量何种介质都不需要现场调校)和免于维护等特点,它广泛应用于冶金、建材、化工、轻工、粮食等行业中物位的过程控制。机械结构简单、灵敏可靠。

音叉式物位传感器有如下优点:

①适应性强:被测介质不同的电参数、密度对测量均不产生影响。结垢、搅动、湍流、气泡、振动、中等粘度、高温(Max150℃)、高压等恶劣条件对检测也无影响。

②不需调校:由于音叉式物位开关的检测不受被测介质电参数及密度的影响,所以无论测量何种介质都不需现场调校。

③免于维护:由于音叉式物位开关的检测过程由电子电路完成,无活动部件,所以一经安装投入使用便不需要维护。综上所述,选择音叉法阻力式料位传感器。

原理:传感器安装于仓的顶部或仓的侧壁上。音叉由压电晶体驱动产生振动,当叉体被液体浸没或被物料埋没时振动频率发生变化。这个变化由电子电路检出并输出一个开关量用于报警或控制。

适用范围:中等粘度、腐蚀性液体。流动性好的粉状物料和颗粒状物料。

禁用范围:高温、高粘度液体。高温、易结垢固体、块状物料

2.4  显示方式选择
2.4.1  LED显示

在单片机应用系统中,LED数码管是很重要的外设,通常用来显示控制过程和运算结果。LED数码管显示清晰、成本低廉、使用电压低、寿命长、配置灵活的特点,与单片机接口简单易行LED管的显示可分为静态和动态两种。

静态显示的特点是各LED管能稳定地同时显示各自字形系统在每一次显示输出后,能保持显示不变,仅仅在待显示数字需要改变时,才更新其数字显示器中锁存的内容,这种显示占用CPU时间少,显示稳定可靠。缺点是:当显示位数较多时,占用I/O较多。

LED动态显示就是LED轮流地一遍一遍显示各自字形,CPU需定时地对每位LED显示器进行扫描,每位LED显示器分时轮流工作,每次只能使一位LED显示,但由于人眼视觉暂留现象,仍感觉所有的LED显示器都同时显示。这种显示的优点是使用硬件少,占用 I/O少。缺点是:占用CPU时间长,只要不执行显示程序,就立刻停止显示。

由于在自动加料机控制系统中运行是要同时显示两条生产线路满料、送料及排料,所显示的位数很多,因此不采用LED显示

2.4.2  LCD显示

LCD液晶显示屏的显示功能强大、 体积小、重量轻、功耗低可显示大量文字、图形,显示内容丰富,清晰可见,显示质量高,并且数字式接口和AT89C51已经接好,方便。

1602液晶显示器是一种点阵型液晶模块,在显示形式上面是有一定的要求的,一些不规范的图形它都不能显示出来,只能显示一些字母、数字和符号。这是因为它的点阵字符排位决定。我们常见的点阵字符主要有由若干个5×7结构形式,或者也有5×11的结构形式。这些点阵字符位只能显示出一个字符,并且每个字符之间还有一个点阵字符的距离,行与行之间也有一个点阵字符的距离。使得屏幕能够达到字符之间和行距之间都有空位。所以不能构成一个连体的图像。

LCD1602液晶是显示电路最常用到的一款显示屏。尤其在显示字符上,更为普遍。它的屏幕大小可以显示2行字符,每行可以显示16个字符。它的屏幕颜色清晰可调,背光以黄绿色为底,在显示字符或者数字的同时,可以通过调节来改变它的对比度,使得符号和数字容易被观察。因此,决定此设计采用LCD1602显示屏。



3  自动加料机系统的硬件电路设计
3.1  原理框图

图4 原理框图

首先系统供电,通过按键对生产线的送料和排料时间进行设定,设定的时间由LCD显示屏显示出来。设定完毕后,由单片机开始检测安装在物料仓的音叉传感器是否有满料信号输入。若有,则物料仓的阀门打开。此时,电动机带动传送带运动,生产线开始送料、排料,设定的送料、排料时间开始递减,直至为零。电动机停止转动,生产线指示灯亮,表示完成自动加料。

3.2  键盘电路设计

键盘是由若干按钮组成的开关矩阵,它是单片机系统中最常用的输入设备,用户能通过键盘向计算机输入指令、地址和数据,实现人机通信。键盘可以分为独立联接式和行列式两类,每一类又可根据对键盘的译码方法分为编码键盘和非编码键盘两类。编码键盘本身除了按键之外,还包括产生键码的硬件电路,只要按下某一个键,就能产生这个键的代码,同时,还能产生一个脉冲,以通知CPU接收输入键的代码。这种键盘的使用比较方便,亦不需要编写很多程序,但使用的硬件比较偏复杂,在微型的计算机控制系统中并不多见。

非编码键盘是由一些按键排列成的一个行列矩阵。按键的作用,是简单的实现节点的接通与断开,但必须有一套相应的程序与之配合,才能产生出相应的键码。非编码键盘几乎不需要附加硬件电路,目前,在微型计算机控制系统中使用比较普遍。键盘是由若干按钮组成的开关矩阵,它是单片机系统中最常用的输入设备,用户能通过键盘向计算机输入指令、地址和数据,实现人机通信。键盘可以分为独立联接式和行列式两类,每一类又可根据对键盘的译码方法分为编码键盘和非编码键盘两类。编码键盘本身除了按键之外,还包括产生键码的硬件电路,只要按下某一个键,就能产生这个键的代码,同时,还能产生一个脉冲,以通知CPU接收输入键的代码。这种键盘的使用比较方便,亦不需要编写很多程序,但使用的硬件比较偏复杂,在微型的计算机控制系统中并不多见。

图5 按键电路

本设计一共设计有6个按键:步骤时间切换键、时间设定加减键、时间设定确定键以及两个满料信号模拟键,所以采用独立式键盘。通过这些按键可以对两条生产线路的各种运行状态时间进行选择和设定。

3.3  显示电路设计

图6 显示电路

显示电路采用LCD1602液晶显示模块,直接与单片机P0口相连,两行分别显示生产线路1和生产线路2的满料时间、送料时间和排料时间等。显示电路如图6所示。

LCD 1602有16个管脚,每一个管脚都有其固定的作用,管脚图及功能如下:

图7 LCD1602管脚图

1脚VSS为电源地;

2脚VDD为+5V逻辑电源;

3脚V0为对比控制端,可以通过1K阻值的电阻接地;

4脚RS为寄存器选择端,当引脚为高电平1时,表示其为数据寄存器;当引脚为低电平0时,表示其为指令寄存器;

5脚R/W为读写信号线,当引脚为高电平1时,表示其为读操作,当引脚为低电平0时,表示其为写操作;

6脚E(或EN)端为使能信号端,当其为高电平或者是下降沿的时候有效;

7~14脚D0~D7为8位数据总线;

15脚LEDA为背光+5V;

16脚LEDK为背光地线。

3.4  电机控制电路设计
3.4.1  电机驱动电路

图8 电机驱动电路

采用L298N来驱动电机,可直接由单片机的I/O端口来提供模拟时序信号,通过单片机的I/O输入改变芯片控制端的电平,即可以对电机进行正反转,停止的操作,,驱动简单,并且可以同时驱动两台电机。而且在直流电机的电枢两端并联一个瓷片电容,可以稳定电机的电压,不至于对单片机造成干扰,省掉了通过光耦隔离来实现单片机信号与电机驱动信号隔离的环节,节约了成本。电机驱动电路如图8所示。

3.4.2  L298N功能介绍

L298N是ST公司生产的一种高电压、大电流电机驱动芯片。该芯片的主要特点是:工作电压高,最高工作电压可达46V;输出电流大,瞬间峰值电流可达3A,持续工作电流为2A;内含两个H桥的高电压大电流全桥式驱动器,可以用来驱动直流电动机和步进电动机、继电器、线圈等感性负载;采用标准TTL逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作;有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外接检测电阻,将变化量反馈给控制电路;可以直接透过电源来调节输出电压;此芯片可直接由单片机的I/O端口来提供模拟时序信号,通过单片机的I/O输入改变芯片控制端的电平,即可以对电机进行正反转、启停的操作。其引脚功能图及引脚功能如下:

SENSA、SENSB(1脚、15脚):此两端与地连接电流检测电阻,并向驱动芯片反馈检测到的信号;

OUT1 、OUT2(2脚、3脚):此两脚是全桥式驱动器A的两个输出端,用来连接负载;
                 

图9  L298N引脚图

VS(4脚):电机驱动电源输入端;
   IN1 、IN2(5脚、7脚):输入标准的TTL逻辑电平信号,用来控制全桥式驱动器A的开关;
  ENA、ENB(6脚、11脚):使能控制端.输入标准TTL逻辑电平信号;低电平时全桥式驱动器禁止工作;

GND(8脚):接地端,芯片本身的散热片与8脚相通;
   VCC(9脚):逻辑控制部分的电源输人端口;
  IN3 、IN4(10脚 、12 脚):输入标准的TTL逻辑电平信号,用来控制全桥驱动器B的开关;
    OUT3 、OUT4(13脚、14脚):此两脚是全桥式驱动器B的两个输出端,用来连接负载。

                                表2 L298N逻辑状态表



4  自动加料机控制系统的软件设计
4.1  主程序流程图

图10 主程序流程图

4.2  倒计时精确延时子程序
              

图11 延时子程序



结语

本设计是基于AT89C51的自动加料系统,没有外扩ROM和RAM,程序直接放在AT89C51内部闪存中。基于单片机控制的自动加料系统是一种无需人工直接操作,可实现一台电机控制双生产线运作的新型材料自动供给系统,相比于老式自动加料系统定时定点加料、单生产线运行的工作模式,其大大提高了生产效率,降低了生产。大提高了工作可靠性。

本设计的主要部分是由单片机控制的显示器部分与驱动电机电路等硬件部分与软件部分的设计共同组成,本设计的控制系统可以一台电机为两条生产线供料,主要取决于工艺要求。这个过程需要用判断程序实现,当一条生产线排料料结束后判断到另一条生产线物料处于满料状态,则为第二条生产线供料,这需要精准的控制而且要严格控制其误差。

采用L298N作为电机驱动,不仅可以控制电机的启停和正反转,而且还可以同时驱动两台电机,并且能对电机的速度进行调节。因此,未来自动加料机控制必然会得到大规模的使用以及发展,希望本文的一些粗浅工作,能够为后续的深入研究和项目建设,提供一定的帮助。


参考文献:

[1] 张毅刚等.MCS-51单片机应用技术[M].哈尔滨工业大学出版社,2003.7

[2] 谢维成等.单片机原理与应用及C51程序设计[M].清华大学出版社,2009.7

[3] 何立民.MCS-51单片机应用技术[M].北京航空航天大学出版社.1998.7

[4] 徐爱军 .单片机高级语言C51应用程序设计[M]电子工业出版社.1997.7

[5] 李华.MCS-51系列单片机实用接口技术[N].北京航空航天大学出版社.1993.3

[6] 王福瑞.单片微机测控系统设计大全[M].北京航空航天大学出版社.2000.5

[7] 于微波等.微型计算机控制系统[M].吉林大学出版社.2002.5

[8] 陈汝全等.实用微机与单片机控制技术[M].电子科技大学出版社.1998.11

[9] 武庆生等.单片机原理与应用[M].电子科技大学出版社.1998.2

[10] 刘灿军.实用传感器[M].国防工业出版社.2004.6

[11] 方佩敏.新编传感器原理应用于电路详解[M].电子工业出版社.1998.6

[12] 赵负图.传感器应用技术[M].传感器集成电路手册[M].化学工业出版社.2002.4

[13] 薛文达 等传感器应用技术[M].东南大学出版社.1998.12

[14] 张勇德.过程控制装置[M].化工出版社.2001.5

[15] 杨绪东.实用电子电路精选[M].化工出版社.2004.5

[16] 徐科军.传感器与检测技术[M].电子工业出版社.2004.5

[17] 杨帮文.新型继电器使用手册[M].人民邮电出版社.2004.5

[18] 周秉功.继电器选型手册[M].机械工业出版社.1998.8

[19] 陈兆宽.计算机过程控制软件设计[M].电子工业出版社.1993.12

[20] 付晓光.单片机原理与实用技术[M].清华大学出版社.2004.8

[21] 刘勇等.数字电路[M].电子工业出版社.2003.1

[22] 康华光等.电子技术基础[M].高等教育出版社.2006.1


单片机源程序:
  1. #include   
  2. #include     //包含_nop_()函数定义的
  3. #include


  4. #define uint unsigned int
  5. #define uchar unsigned char

  6. unsigned char count=0,ss=0;

  7. void delay_timer( uchar);

  8. sbit start_1 = P1^0;
  9. sbit start_2 = P1^1;
  10. sbit inc = P1^2;
  11. sbit dec = P1^3;
  12. sbit mode = P1^4;
  13. sbit ok = P1^5;
  14. sbit led1 = P1^6;
  15. sbit led2 = P1^7;
  16. sbit IN1 = P2^3;
  17. sbit IN2 = P2^4;

  18. sbit RS=P2^0;   
  19. sbit RW=P2^1;   
  20. sbit E=P2^2;   
  21. sbit BF=P0^7;   

  22. uint timer = 0;
  23. uchar mode_val = 0;
  24. uint cnt_whole =0;

  25. uint set_limit = 1000;
  26. uchar flag_step = 0;
  27. uchar flag_begin = 0;
  28. uint cnt = 0;

  29.             
  30. uchar t_p_1, t_p_2, t_p_3, t_p_4, v_4, v_3, v_2, v_1;
  31. uchar t_p_a_1, t_p_a_2, t_p_a_3, t_p_a_4;
  32.                                          
  33. uint timer0_cnt = 0;
  34. unsigned char flag = 0;
  35. uchar flag_1 = 0, flag_2 = 0;
  36. uchar time_set[4] = {5, 5, 5, 5};
  37. uint time_full[2] = {0, 0};

  38. void disp(void);
  39. void delay1ms()
  40. {
  41.    unsigned char i,j;            
  42.               for(i=0;i<10;i++)
  43.                 for(j=0;j<33;j++)
  44.                  ;                           
  45. }

  46. void delay(unsigned int n)
  47. {
  48.    unsigned int i;
  49.               for(i=0;i<n;i++)
  50.                  delay1ms();
  51. }


  52. unsigned char BusyTest(void)
  53.   {
  54.     bit result;
  55.                             RS=0;      
  56.     RW=1;
  57.     E=1;      
  58.     _nop_();  
  59.     _nop_();
  60.     _nop_();
  61.     _nop_();               
  62.     result=BF;
  63.                             E=0;
  64.     return result;
  65.   }


  66. void WriteInstruction (unsigned char dictate)
  67. {  
  68.    while(BusyTest()==1);  
  69.               RS=0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
  70.               RW=0;  
  71.               E=0;                  

  72.               _nop_();
  73.               _nop_();              
  74.               P0=dictate;           
  75.               _nop_();
  76.               _nop_();
  77.               _nop_();
  78.               _nop_();               //空操作四个机器周期,给硬件反应时间
  79.                 E=0;                  //当E由高电平跳变成低电平时,液晶模块开始执行命令
  80. }


  81. void WriteAddress(unsigned char x)
  82. {

  83.      WriteInstruction(x|0x80);
  84. }


  85. void WriteData(unsigned char y)
  86. {
  87.    while(BusyTest()==1);
  88.                 RS=1;           //RS为高电平,RW为低电平时,可以写入数据
  89.                 RW=0;
  90.                 E=0;           
  91.                 P0=y;         
  92.                 _nop_();
  93.                 _nop_();
  94.                 _nop_();
  95.               _nop_();        //空操作四个机器周期,给硬件反应时间
  96.               E=0;            //当E由高电平跳变成低电平时,液晶模块开始执行命令
  97. }


  98. void LcdInitiate(void)
  99. {
  100.    delay(15);             //延时15ms,首次写指令时应给LCD一段较长的反应时间
  101.    WriteInstruction(0x38);
  102.               delay(5);   //延时5ms 
  103.               WriteInstruction(0x38);
  104.               delay(5);
  105.               WriteInstruction(0x38);
  106.               delay(5);
  107.               WriteInstruction(0x0d);
  108.               delay(5);
  109.               WriteInstruction(0x06);
  110.               delay(5);
  111.               WriteInstruction(0x01);  //清屏幕指令,将以前的显示内容清除
  112.               delay(5);
  113. }


  114. void main(void)            //主函数
  115. {
  116.   uint i = 0;            
  117.               uchar s_1, s_2, s_3, m_1, m_2, m_3, p_1, p_2, p_3, q_1, q_2, q_3;
  118.             
  119.   TMOD=0x01;
  120.   TL0=0xf0;
  121.   TH0=0xd8;                                                                     
  122.   IT0 = 1;

  123.               ET0 = 1;
  124.               EA=1;
  125.                 led1 = 0;
  126.               led2 = 0;
  127.               LcdInitiate();         //调用LCD初始化函数
  128.               while(1)
  129.               {
  130.                             if(start_1 == 0)
  131.                  {
  132.                                delay(50);
  133.                                           if(start_1 == 0 && flag_1 == 0)
  134.                                           {            
  135.                                                         flag_1 = 1;
  136.                                                         flag_step = 1;
  137.                                           }
  138.                  }
  139.                             if(start_2 == 0)
  140.                  {
  141.                                delay(50);
  142.                                           if(start_2 == 0 && flag_2 == 0)
  143.                                           {            
  144.                                                         flag_2 = 1;
  145.                                           }
  146.                  }
  147.                             if(inc == 0 && flag_step == 0)
  148.                             {
  149.                                           delay(50);
  150.                                           if(inc == 0)
  151.                                           {
  152.                                                         if(time_set[mode_val] < 200)
  153.                                                                       time_set[mode_val] ++;
  154.                                                         else;
  155.                                           }
  156.                             }

  157.               if(dec == 0 && flag_step == 0)
  158.               {
  159.                                delay(50);
  160.                                           if(dec == 0)
  161.                                           {
  162.                                                           if(time_set[mode_val] > 0)
  163.                                                                                     time_set[mode_val] --;
  164.                                           }
  165.                                           else;
  166.               }
  167.             
  168.             
  169.                             if(mode == 0)
  170.                             {
  171.                                           delay(50);
  172.                                           if(mode == 0)
  173.                                           {
  174.                                                         if(mode_val >= 3)
  175.                                                                       mode_val = 0;
  176.                                                         else
  177.                                                                       mode_val ++;
  178.                                           }
  179.                                          
  180.                             }
  181.                            
  182.                            
  183.                             if(ok == 0)
  184.                             {
  185.                                           delay(10);
  186.                                           if(ok == 0)
  187.                                           {
  188.                                                         flag_begin = 1;
  189.                                           }
  190.                             }
  191.                            
  192.                             if(flag_begin == 1)
  193.                             {
  194.                                           WriteAddress(0xcd);  
  195.                                 WriteData('o');
  196.                                 WriteAddress(0xce);
  197.                                           WriteData('k');                                         
  198.                             }
  199.                             else
  200.                             {
  201.                                           WriteAddress(0xcd);  
  202.                                 WriteData(' ');
  203.                                 WriteAddress(0xce);
  204.                                           WriteData(' ');            
  205.                                          
  206.                             }
  207.                
  208.             
  209.                                           s_1 = time_set[0]%10;
  210.                                           s_2 = time_set[0]/10%10;
  211.                                 s_3 = time_set[0]/100;

  212.                                           m_1 = time_set[1]%10;
  213.                                           m_2 = time_set[1]/10%10;
  214.                                 m_3 = time_set[1]/100;
  215.                            
  216.                                           p_1 = time_set[2]%10;
  217.                                           p_2 = time_set[2]/10%10;
  218.                               p_3 = time_set[2]/100;
  219.                            
  220.                                           q_1 = time_set[3]%10;
  221.                                           q_2 = time_set[3]/10%10;
  222.                               q_3 = time_set[3]/100;

  223.                            
  224.                                           t_p_1 = time_full[0] %10;
  225.                      t_p_2 = time_full[0]/10%10;
  226.                      t_p_3 = time_full[0]/100%10;
  227.                
  228.                                          
  229.                                           t_p_a_1 = time_full[1] %10;
  230.                     t_p_a_2 = time_full[1]/10%10;
  231.                     t_p_a_3 = time_full[1]/100%10;
  232.             
  233.                                          
  234.                                                       
  235.                                           WriteAddress(0x00);  
  236.                                 WriteData(t_p_3 + 0x30);
  237.                                 WriteAddress(0x01);
  238.                                 WriteData(t_p_2 + 0x30);
  239.                                           WriteAddress(0x02);  
  240.                                 WriteData(t_p_1 + 0x30);

  241.                                           WriteAddress(0xc0);  
  242.                                 WriteData(t_p_a_3 + 0x30);
  243.                                 WriteAddress(0xc1);
  244.                                 WriteData(t_p_a_2 + 0x30);
  245.                                           WriteAddress(0xc2);  
  246.                                 WriteData(t_p_a_1 + 0x30);
  247.                                                       
  248.                                           WriteAddress(0x04);  
  249.                                 WriteData(s_3 + 0x30);
  250.                                 WriteAddress(0x05);
  251.                                 WriteData(s_2 + 0x30);
  252.                                           WriteAddress(0x06);  
  253.                                 WriteData(s_1 + 0x30);
  254.                                                       
  255.                                                       
  256.                                           WriteAddress(0xc4);  
  257.                                 WriteData(p_3 + 0x30);
  258.                                 WriteAddress(0xc5);
  259.                                 WriteData(p_2 + 0x30);
  260.                                           WriteAddress(0xc6);  
  261.                                 WriteData(p_1 + 0x30);
  262.                                                       
  263.                                                       
  264.                                           WriteAddress(0x09);  
  265.                                 WriteData(m_3 + 0x30);
  266.                                 WriteAddress(0x0a);
  267.                                 WriteData(m_2 + 0x30);
  268.                                           WriteAddress(0x0b);  
  269.                                 WriteData(m_1 + 0x30);
  270.                                                       
  271.                                                       
  272.                                           WriteAddress(0xc9);  
  273.                                 WriteData(q_3 + 0x30);
  274.                                 WriteAddress(0xca);
  275.                                 WriteData(q_2 + 0x30);
  276.                                           WriteAddress(0xcb);  
  277.                                 WriteData(q_1 + 0x30);
  278.                                                       
  279.                                           WriteAddress(0x0d);  
  280.                                 WriteData(mode_val + 0x30);
  281.                                 WriteAddress(0x0e);
  282.             

  283.                                           delay(100);
  284.                                          
  285.                             }
  286.               }
  287.             
  288.             
  289. void timer0(void) interrupt 1                              //定时器0                                          10ms
  290. {

  291.                 TL0= 0xf0;
  292.                 TH0= 0xd8;
  293. if(flag_begin == 1)
  294. {
  295.               if(timer0_cnt >= 100)
  296.               {
  297.                             timer0_cnt = 0;
  298.                             if(flag_step == 1 && flag_1 == 1)
  299.                             {
  300.                                           led1 = 0;
  301.                                           IN1 = 1;
  302.                                           IN2 = 0;
  303.                                           if(time_set[flag_step - 1] == 0)
  304.                                           {
  305.                                                         flag_step = 2;
  306.                                           }
  307.                                           else
  308.                                                         time_set[flag_step - 1] --;
  309.                             }
  310.                             else if(flag_step == 2 && flag_1 == 1)
  311.                             {
  312.                                           IN1 = 1;
  313.                                           IN2 = 0;
  314.                                           if(time_set[flag_step - 1] == 0)
  315.                                           {
  316.                                                         flag_step = 3;
  317.                                                         led1 = 1;
  318. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整文档下载(word格式 可编辑):
http://www.51hei.com/bbs/dpj-86636-1.html




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:625382 发表于 2020-7-15 01:24 来自手机 | 只看该作者
lcd为什么没显示??
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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