2019-10-25 14:22:59 qq_26275617 阅读数 30
  • 巫妖王51单片机开发板配套视频课程

    本课程是巫妖王51单片机开发板的配套视频课程,本课程的目标是用少的时间带大家初级入门51单片机。配合巫妖王51单片机开发板,让大家花费少的时间少的钱就能轻松开启单片机学习之路。

    18902 人正在学习 去看看 朱有鹏

自动化毕业后,一共花了5-6年时间。先后做了电力电子新能源逆变电路,嵌入式,半导体工艺设备,电工,电气自动化电气成套设备,半导体检测设备,防爆电气,单片机,模拟滤波电路。大概除了数字电路,跟自动化相关的全产业链我都见过了。见的多了也就屁都不会咯!看样子武侠小说里并没说谎。就记录一下一些零碎的所见所闻。

 PLC  51单片机

2017年的时候,在一家电气成套设备公司,借助这个平台,看见,客户很多时候在使用单片机替代部分PLC功能。

我以为凭借成本优势,以及大学生红利,大量的毕业生终究会将技术普及。

然而,几年过去了,我们专业的毕业生,四十四号人,没听说有几个人从事本专业的岗位,更别说技术研发工程师了。本就少的可怜的从业人员,被一线城市一扫而空,甚至给出几百上千的住房补贴。少数二线城市,也只能勉强花店钱,捡捡漏。

广大的三四五线小镇,基本上没有相关从业人员。这也是几年以后我才了解到的现状。

根据美日韩的城市发展现状推测,未来中国的人口大趋势是小城市人口持续不断的流逝,不存在大规模回流的可能。

今年2019年,我去到一家非标设备公司,发现,工作十年的单片机工程师离职了,取而代之的是PLC电气自动化工程师。

这推翻了我2017年的认知。

甚至有人说,最适合的上位机编程语言是C#,结果,普及度并不高,而那些使用C#的很多都是自己专业混的不好,跨到别的行业去了。事实上,这类语言开发工程师,在小城市尤其是内陆小城市,倒是很少见。

现在,我被要求学习labview来做上位机开发。

PC   PLC

后来,去到半导体设备行业,发现分化的很明显,PC软件的发展很大程度上,取代部分单片机功能了。而现场设备的动作依旧是PLC的战场。PLC开始向嵌入式的方向靠拢。

现在的这家公司,单片机的活被PC和PLC联合瓜分了。原因是,单片机开发过于麻烦复杂,周期过长。

嵌入式 与 传统单片机

手机的疯狂发展,带动了嵌入式的大规模普及,以前不带操作系统的单片机,最终,向着嵌入式方向融合。

传统单片机似乎穷途末路了。或者说脱胎换骨了。

半导体的集成程度越来越高。手机的一块主板,不过拇指大小,我记得上大学那会儿,有一章节介绍集成电路,说一块芯片指甲大小,当时以为,牛逼啊!现在,一块主板都是拇指大小了。

传统单片机以迭代的形式,把自己替换掉了。而本质是科技的进步,换下了它。

在标准产品领域,单片机慢慢爬了上来,嵌入式系统的单片机,代替了不带系统的单片机。

在非标市场,单片机似乎并没有什么优势,但是,嵌入式系统的单片机未来能不能改变这一现状,不好说,至少常用的51败了。

模拟电路和数字电路。

我对模拟电路的认知,还停留在半导体收音机,电子电源上。只是刚毕业那会做新能源的时候接触逆变器常常见到。

而对于数字电路则见得特别多了。毕业多年,又一次偶遇模拟电路。才发现,模拟电路好像不见了。

根据同学了解到,不少模拟电路公司后来转到数字电路去了。

以至于,公司想招聘模拟电路相关的工程师几乎是很难招到了。市场慢慢被数字电路吃掉了。

于是,我被弄去做滤波电路。奶奶的,自此,除了数字电路,我怕是接触了自动化全产业链了。

摩尔定律与台积电

技术的迭代真的是快啊!几年一个变化,几年又一个变化。你方唱罢,我又登场。芯片已经做到肉眼快看不见的地步了。

台积电竟然开始2纳米的研发了,英特尔终于不再14nm+++++++了

5nm过完年就量产了。体积又可以缩小,以后指甲盖是没法形容芯片的尺寸了。

5g与物联网

物联网的热潮是两年前吧,政府大量扶持,那些做工控的,单片机的公司纷纷搞起物联网来。结果,物联网还是只有大体量的公司才做的起,标准这玩意可不是什么公司都能做的。现在也没见什么小公司把物联网做起了。偶尔见到做一两个串口路由器的公司。

5g终于开始发货了,等到大规模上市,估计等到明年,而明年是5nm上市的时间。所以,它们两遇到了一起。cpu好不容易省下的功耗估计又让基带芯片给吃掉了吧。

 

2012-01-15 22:18:27 iteye_18590 阅读数 526
  • 巫妖王51单片机开发板配套视频课程

    本课程是巫妖王51单片机开发板的配套视频课程,本课程的目标是用少的时间带大家初级入门51单片机。配合巫妖王51单片机开发板,让大家花费少的时间少的钱就能轻松开启单片机学习之路。

    18902 人正在学习 去看看 朱有鹏
知识竞赛抢答器PLC设计
2009年10月13日
  知识竞赛抢答器PLC设计
  摘 要:本文介绍了利用三菱FX2N系列PLC对知识竞赛抢答器的控制,阐述了控制方案。实现抢答器功能的方式有多种,可以采用早期的模拟电路、数字电路或模数混合电路。近年来随着科技的飞速发展,单片机、PLC的应用不断地走向深入,同时带动传统的控制检测技术的不断更新。本文采用日本三菱公司生产的FX2N-48MR型PLC 作为核心控制器进行四路抢答器系统的设计,并且设计出了系统结构图、程序指令、梯形图以及输入输出端子的分配方案。同时根据知识竞赛抢答器的控制要求和特点,确定PLC 的输入输出分配,并进行现场调试。
    关键词:PLC 知识竞赛抢答器 PLC程序设计
    第一章 概述 …………………………………………………………………………1
     1.1 PLC的简介………………………………………………………………………1
     1.2 PLC的用途与特点………………………………………………………………1
     1.2.1 PLC的用途………………………………………………………………1
     1.2.2 PLC的特点 ……………………………………………………………2
     1.3 PLC的分类………………………………………………………………………4
     1.3.1按I/O点数容量分类……………………………………………………4
     1.3.2按结构形式分类…………………………………………………………4
    第二章 整体方案的选择……………………………………………………………6
     2.1整体功能介绍 …………………………………………………………………6
     2.2控制要求 ………………………………………………………………………6
     2.3用单片机和PLC分别做系统的比较 …………………………………………7
    第三章 硬件电路设计 ……………………………………………………………9
     3.1控制特点分析 …………………………………………………………………9
     3.2 PLC机型的选择步骤与原则 …………………………………………………10
     3.3抢答器流程图 …………………………………………………………………11
     3.4程序中所使用的FX系列PLC的编程元件介绍………………………………11
     3.4.1三菱FX系列PLC取指令与输出指令(LD/LDI/LDP/LDF/OUT)……11
     3.4.2三菱FX系列PLC触点串联指令(AND/ANI/ANDP/ANDF) …………12
     3.4.3三菱FX系列PLC触点并联指令(OR/ORI/ORP/ORF)………………13
     3.4.4三菱FX系列PLC块操作指令(ORB / ANB) ………………………14
  知识竞赛抢答器PLC设计
  双击自动滚屏 文章来源:至诚工作室 发布者:至诚 发布时间:2008-12-11 9:17:51 阅读:2461次
  3.4.5三菱FX系列PLC置位与复位指令(SET/RST) ……………………15
     3.4.6传送类指令MOV SMOV CMOV BMOV FMOV………………………………15
     3.4.7三菱FX系列PLC常数(K、H)………………………………………18
     3.4.8三菱FX系列PLC输入继电器(X) …………………………………18
     3.4.9三菱FX系列PLC输入继电器(Y) …………………………………19
     3.4.10辅助继电器 …………………………………………………………19
     3.4.11三菱FX系列PLC定时器(T)………………………………………20
     3.4.12微分指令(PLS/PLF) ………………………………………………22
     3.4.13位右移和位左移指令 ………………………………………………23
     3.5 PLC与七段LED显示器连接设计 ……………………………………………24
     3.5.1 LED数码管的结构及主要特性 ………………………………………24
     3.5.2 PLC与七段数码管方案选择 …………………………………………25
     3.5.3 PLC与七段数码管直接连接阻值计算 ………………………………26
     3.5.4 外部硬件接线图 ……………………………………………………26
    第四章 软件设计…………………………………………………………………27
     4.1I/O分配 ………………………………………………………………………27
     4.2根据控制要求进行梯形图设计 ………………………………………………28
     4.3程序运行过程分析 ……………………………………………………………33
     4.4 源程序…………………………………………………………………………34
     4.5程序的下载、安装和调试 ……………………………………………………41
    第五章 总结与展望 ………………………………………………………………42
    致谢…………………………………………………………………………………43
    参考文献……………………………………………………………………………45
   
  1.1 PLC的简介
  国际电工委员会(IEC)于1987年对PLC定义如下:
  PLC是专为在工业环境下应用而设计的一种数字运算操作的电子装置,是带有存储器,可以编制程序的控制器。它能够存储和执行指令,进行逻辑运算,顺序控制,定时,计数和算术等操作,并通过数字式和模拟式的输入输出,控制各种类型的机械和生产过程。PLC及其有关的外围设备,都应按易于与工业控制系统形式一体,易于拓展其功能的原则设计。
  事实上,PLC就是以嵌入式CPU为核心,配以输入,输出等模块,可以方便的用于工业控制领域的装置。PLC与机器人,计算机帮助设计与制造一起作为现代工业的三大支柱。
  知识竞赛抢答器PLC设计
  1.2 PLC的用途与特点
  1.2.1 PLC的用途
  PLC的初期由于其价格高于继电器控制装置,使其应用受到限制。但近年来由于微处理器芯片及有关元件价格大大下降,使PLC的成本下降,同时又由于PLC的功能大大增强,使PLC 的应用越来越广泛,广泛应用于钢铁、水泥、石油、化工、采矿、电力、机械制造、汽车、造纸、纺织、环保等行业。PLC的应用通常可分为五种类型:
  (1)顺序控制 这是PLC应用最广泛的领域,用以取代传统的继电器顺序控制。PLC可应用于单机控制、多机群控、生产自动线控制等。如注塑机、印刷机械、订书机械、切纸机械、组合机床、磨床、装配生产线、电镀流水线及电梯控制等。
  (2)运动控制 PLC制造商目前已提供了拖动步进电动机或伺服电动机的单轴或多轴位置控制模版。在多数情况下,PLC把扫描目标位置的数据送给模版块,其输出移动一轴或数轴到目标位置。每个轴移动时,位置控制模块保持适当的速度和加速度,确保运动平滑。
  相对来说,位置控制模块比计算机数值控制(CNC)装置体积更小,价格更低,速度更快,操作方便。
  (3)闭环过程控制 PLC能控制大量的物理参数,如温度、压力、速度和流量等。PID(Proportional Intergral Derivative)模块的提供使PLC具有闭环控制功能,即一个具有PID控制能力的PLC可用于过程控制。当过程控制中某一个变量出现偏差时,PID控制算法会计算出正确的输出,把变量保持在设定值上。
  (4)数据处理 在机械加工中,出现了把支持顺序控制的PLC和计算机数值控制(CNC)设备紧密结合的趋向。著名的日本FANUC公司推出的Systen10、11、12系列,已将CNC控制功能作为PLC的一部分。为了实现PLC和CNC设备之间内部数据自由传递,该公司采用了窗口软件。通过窗口软件,用户可以独自编程,由PLC送至CNC设备使用。美国GE公司的CNC设备新机种也同样使用了具有数据处理的PLC。预计今后几年CNC系统将变成以PLC为主体的控制和管理系统。
  (5)通信和联网 为了适应国外近几年来兴起的工厂自动化(FA)系统、柔性制造系统(FMS)及集散控制系统(DCS)等发展的需要,必须发展PLC之间,PLC和上级计算机之间的通信功能。作为实时控制系统,不仅PLC数据通信速率要求高,而且要考虑出现停电故障时的对策。
  1.2.2 PLC的特点
  (1)抗干扰能力强,可靠性高 继电接触器控制系统虽具有较好的抗干扰能力,但使用了大量的机械触头,使设备连线复杂,由于器件的老化、脱焊、触头的抖动及触头在开闭时受电弧的损害大大降低了系统的可靠性。传统的继电器控制系统中使用了大量的中间继电器、时间继电器。由于触点接触不良,容易出现故障,PLC用软件代替大量的中间继电器和时间继电器,仅剩下与输入和输出有关的少量硬件,接线可减少互继电器控制系统的1/10--1/100,因触点接触不良造成的故障大为减少。
  而PLC采用微电子技术,大量的开关动作由无触点的电子存储器件来完成,大部分继电器和复杂的连线被软件程序所取代,故寿命长,可靠性大大提高。
  微机虽然具有很强的功能,但抗干扰能力差,工业现场的电磁波干扰,电源波动,机械振动,温度和湿度的变化,都可能使一般通用微机不能正常工作。而PLC在电子线路、机械结构以及软件结构上都吸收了生产控制经验,主要模块均采用了大规模集成电路,I/O系统设计有完善的通道保护与信号调理电路;在结构上对耐热、防潮、抗震等都有精确的考虑;在硬件上采用隔离、屏蔽、滤波、接地等抗干扰能力,目前个生产厂家生产的PLC,平均无故障时间都大大超过了IEC规定的10万小时,有的甚至达到了几十万小时。
  (2)控制系统结构简单、通用性强、应用灵活 PLC产品均成系列化生产,品种齐全,外围模块品种也多,可有各种组件灵活组合成各种大小和不同要求的控制系统。在PLC构成的控制系统中,只需在PLC的端子上接入相应的输入、输出信号线即可,不需要诸如继电器之类的物理电子器件和大量而有繁杂的硬件接线线路。当控制要求改变,需要变更控制系统功能时,可以用编程器在线或离线修改程序,修改接线量很小。同一个PLC装置有、用于不同的控制对象,只是输入、输出组件和应用软件不同而已。
  (3)编程方便,易于使用 PLC是面向用户的设备,PLC的设计者充分考虑到现场工程技术人员的技能和习惯,PLC程序的编制,采用梯形图或面向工业控制的简单指令形式。梯形图与继电器原理图相类似,直观易懂,容易掌握,不需要专门的计算机知识和语言,深受现场电气技术人员的欢迎,近年来又发展了面向对象的顺序控制流程图语言,也称功能图,使编程更加简单方便。
  (4)功能完善,扩展能力强 PLC中含有数量巨大的用于开关量处理的继电器类软件,可轻松地实现大规模的开关量逻辑控制,这是一般的继电器控制所不能实现的。PLC内部具有许多控制功能,能方便地实现D/A、A/D转换及PID运算,实现过程控制、数字控制等功能。PLC具有通信联网功能,他不仅可以控制一台单机,一条生产线,还可以控制一个机群,许多生产线。他不但可以进行现场控制,还可以用于远程控制。
  (5)PLC控制系统设计、安装、调试方便 PLC中相当于继电器系统中的中间继电器、时间继电器、计数器等“软元件”数量巨大,硬件齐全,且为模块化积木式结构,并已商品化,故可按性能、容量(输入、输出点、内存大小)等选用组装。又由于用软件编程取代了硬接线实现控制功能,使安装接线量大大减小,设计人员只要一台PLC就可进行控制系统的设计可在实验室进行模拟调试。而继电接触器系统需要在现场调试,工作量很大且繁难
  知识竞赛抢答器PLC设计
  (6)维修方便,维修工作量小 PLC具有完善的自诊断,履历情况存储及监视功能。对于内部工作状态、通信状态、异常状态和I/O点的状态均有显示。工作人员通过他可查出故障原因,便于迅速处理,及时排除。
  (7)结构紧凑 体积小、重量轻,易于实现机电一体化。
  由于以上特点,使得PLC获得极为广泛的应用。
  1.3 PLC的分类
  1.3.1按I/O点数容量分类
  一般来说,PLC处理的I/O点数比较多,反映控制关系比较复杂,用户要求的程序存储器容量比较大,要求PLC的指令及其他功能比较多,指令执行的过程比较快等。按PLC的输入输出点数可将PLC分为三类。
  (1)小型机 小型PLC的功能一般以开关量控制为主,其输入、输出总数在256点一下,用户程序存储器容量在4K字一下。现在的高性能小型机还具有一定的通信能力和少量的模拟量处理能力。这类PLC价格低廉,体积小,适合于控制单台设备,开发机电一体化产品。
  典型的小型机有OMRON公司的CPM2A系列、SIEMEN公司的S7-200 系列,MITSUBISH公司的FX系列和AB公司的SLC500系列等整式PLC等产品。
  (2)中型机 中型机PLC的输入、输出总点数在256-2048点之间,用户程序存储器容量达到2-8K字。中型机PLC不仅具有开关量和模拟量的控制功能,还具有更强的数字计算能力,他的通信功能和模拟量处理能力更强大。中型机的指令比小型机更丰富,适用于更复杂的逻辑控制系统以及连续生产过程控制场合。
  典型的中型机有SIEMENS公司的S-300系列、OMRON公司的C200H系列、AB公司的SLC500系列模块式PLC等产品。
  (3)大型机 大型机PLC的输入、输出总点数在2048点以上,用户程序存储器容量达到8-6K字。大型PLC的性能已经与工业控制计算机相当,他具有计算、控制和调节的功能,还具有很强的网络结构和通信联网能力。他的监视采用CRT显示,能够表示过程动态流程,纪录各种曲线,PID调节参数选择图;他配备多种智能板,构成一个多功能系统。这种系统还可以和其他型号的PLC互联,和上位机相连,组成一个集中分散的生产过程和产品质量控制系统。大型机适用于设备自动化控制、过程自动化控制和过程监控系统。
  典型的大型PLC有SIEMENS公司的S7-400系列、OMRON公司的CVM1和CS1系列、SB公司的SLC5/05系列等产品。
  上述划分没有严格的界限,随着PLC技术的飞速发展,某些小型PLC也具备中型机和大型机的功能,这也是PLC的发展趋势。
  1.3.2按结构形式分类
  按PLC物理结构形式的不同,可分为整体式(也称单元式)和组合式(也称模块式)两类。
  (1)整体式结构 整体式结构的PLC是将中央处理单元(CPU)、存储器、输入单元、电源、通信端口、I/O扩展端口等组装在一个箱体内构成主机。内外还有独立的I/O扩展单元等通过扩展电缆与主机上的扩展端口相连,以构成PLC不同配置与主机配合使用。整体式结构的PLC结构紧凑、体积小、成本低、安装方便。小型机常用这种结构。
  (2)组合式结构 这种结构的PLC是将CPU、输入单元、输出单元、电源单元、智能I/O单元,通信单元等分别做成相应的电路板和扩展模块。组合式的特点是配置灵活,输入接点、输出接点的数量可以自由选择,各种功能模块可以依需要灵活配置。大、中型PLC常用组合式结构。
  第五章 总结与展望
  本抢答器系统虽是针对四路参赛选手设计的,但通过原理分析可知,它也完全适用于多于四路选手的抢答场合。当然,如果对外围电路及程序稍加修改,就很容易使之扩展成更多路的抢答器。若去掉程序中的互锁功能,可以将本抢答器改成呼叫器,用在医院病房等多种地方。由此可见,只要我们运用恰当,PLC技术能实现许多复杂的功能,能极方便的控制我们所需要控制的对象,给我们生产和生活带来极大的方便。
  知识竞赛的一个最重要的硬件设备就是抢答器。以往的电子抢答器,许多功能也达不到的,比如播放视频题,抢答视频暂停再继续功能等。
  但是,随着科学技术飞速的发展,抢答器由硬件化逐步向软件化发展。抢答器竞赛软件利用计算机搞知识竞赛,经过调查,利用抢答器竞赛软件办一次类似电视台效果的知识竞赛,其费用仅仅是到电视台演播厅举办一次竞赛费用的十分之一还少。更关键的是,抢答器竞赛软件不是一次性产品,可以多次重复使用,这是一次拥有长期受益的软件。
  采用抢答器竞赛软件是大势所趋
  对于一个每年都有赛事的单位企业,只要单位有计算机和投影仪,搞知识竞赛不利用抢答器竞赛软件,如同是有好马没有配好鞍。
  以往企业自己搞知识竞赛,都是主持人读题,观众选手得安静仔细听题目,有条件的花上万元买个电子抢答器,算是给知识竞赛赛场添彩了。大多依靠主持人发挥水平,选手和观众渴望的类似电视台的节目效果难以实现。与电视播放的那些竞赛场面对照――选手坐在显示器前答题,观众看着大屏幕显示题目和答案,大屏幕有抢答显示计分排行等,绚丽的画面有节奏的音乐――差距很大,但这些都不是电视台的专利,利用抢答器竞赛软件,用户自己就可以实现这样的视觉效果。运用互动式多媒体技术,将竞赛题目制作成演示程序。通过投影仪大屏幕或电视墙在现场播放,给观众强烈的视听感受,凝聚竞赛现场气氛。通过选手面前的显示器,为参赛队员提供最直接的看题效果,保证队员对题目的正确理解。 抢答器竞赛软件就是简单利用计算机及投影仪设备资源,通过软件来实现专业效果的竞赛系统。它实现竞赛的成本低,便于组织,通用性好。毫不夸张,除了电视台专业制作外,抢答器竞赛软件是所有同类软件中功能最全的!最适宜普通知识竞赛操作的!将会全面发展到社会各个企事业单位。
2015-10-11 16:43:52 liucheng5037 阅读数 13967
  • 巫妖王51单片机开发板配套视频课程

    本课程是巫妖王51单片机开发板的配套视频课程,本课程的目标是用少的时间带大家初级入门51单片机。配合巫妖王51单片机开发板,让大家花费少的时间少的钱就能轻松开启单片机学习之路。

    18902 人正在学习 去看看 朱有鹏

在了解modbus协议后就是基于该协议的设计了,下面先说一下基于航太电子HTM52单片机的从机设计。

设计思想如下:

modbus协议是以主从的方式通信的,也就是上位机发送指令,下位机应答机制,发起通信的一直是上位机,下位机只要应答就好了。

modbus协议被设计出来是针对PLC应用的,这里我们可以简单的模拟PLC环境,可以在单片机里面设计一块共享区,该区域是上位机和下位机共享的,均可以读取或写入该区域的值,所有的modbus协议都是针对该快区域的操作,下位机也是根据这块区域的值做相应的操作。

这块共享区我们用结构体来表示,这里我们只用了两个变量:

/*modbus 16位值的定义,起始地址0000H,每一个值为16位 int型,占两个字节 */
struct MODBUS_ADD{
int LED_value;//地址:0000H  LED灯的值,该值得低8位代表分表代表LED1--LED8
int LED_ctrl;//地址:0001H  控制指令
};
struct MODBUS_ADD modbus_Addt;//声明一个modbus结构体变量
struct MODBUS_ADD *modbusAdd;//结构体指针,指向这个变量

在主函数中,只需要查询这块区域的值,作出相应的动作就好了:

void main()
{
	 SystemInit();
	 init_MODBUS();
	 modbus_Addt.LED_ctrl = COMM_PC;
	while(1)
	{				
				//将需要交互的数据读取到公共区
			  /*start*/
		if(modbus_Addt.LED_ctrl != COMM_PC)
		{
			 modbus_Addt.LED_value = LED_PORT;
		}
			  /*end*/
			 
		 	//同步公共区数据到实际运行效果
			  /*start*/
			 switch(modbus_Addt.LED_ctrl)
			 {
				 case COMM_PC: 
					 LED_PORT = ~(uchar)(modbus_Addt.LED_value & 0x00ff);
				 break;
				 case COMM_FLOW:
					 LedFlow();
				 break;
				 default:
					 LED_PORT = ~(uchar)(modbus_Addt.LED_value & 0x00ff);
				 break;
			 }
			  /*end*/
	}
}

接下来看modbus协议具体怎么实现的,可以看到在主函数中是没有参与这个协议的,也就是相当于modbus协议的实现是在另外一个线程中,主函数不需要关心实现的细节,这样做的好处的是主函数可以近针对于自己的实现任务,二不用考虑任务的参数从哪来的

51单片机与上位机通信采用串口的方式,串口中断负责接收和发送数据,这里我们还用到了一个定时器,负责监控当前modbus的状态,判断这一帧数据是否完成,如果判断为一帧数据接收完成,就解析该帧数据,并执行相应的指令。

注意一下rec_time_out这个变量,这个变量在定时器中断里面是不断自加的,但在串口中断里面就清零了,这样做的意义是判断一帧数据是否接收完成,如果rec_time_out这个变量值大于某个值,说明在一段时间是没有数据接收的,可以认为数据接收接收,当然上位机那边必须满足一帧数据是连续发送的

串口中断程序如下,这里用到了串口中断发送数据帧,具体解析可以参考我的另一篇博客 http://blog.csdn.net/liucheng5037/article/details/48831993

//串口中断
void SerISR() interrupt 4 using 2
{
	if(RI == 1)
	{
		unsigned char data_value;
		RI=0;
		if(send_buf.busy_falg == 1) return;//发送未完成时禁止接收
		data_value = SBUF;
		rec_time_out = 0;//一旦接收到数据,清空超时计数
		switch(rec_stat)
		{
			case PACK_START:
				rec_num = 0;
				if(data_value == PACK_START)//默认刚开始检测第一个字节,检测是否为本站号
				{
					modbus_recv_buf[rec_num++] = data_value;
					rec_stat = PACK_REC_ING;
				}
				else
				{
					rec_stat = PACK_ADDR_ERR;
				}
				break;
	
			case PACK_REC_ING:	// 正常接收
	
				modbus_recv_buf[rec_num++] = data_value;
				break;
	
			case PACK_ADDR_ERR:	// 地址不符合 等待超时 帧结束
				break;
			default : break;
		}
		
	}
	if(TI == 1)	 //进入发送完成中断,检测是否有需要发送的数据并进行发送
	{
		TI = 0;
		send_buf.index++;
		if(send_buf.index >= send_buf.length)
		{
			send_buf.busy_falg = 0;//发送结束
			return;
		}
		SBUF = send_buf.buf[send_buf.index];//继续发送下一个	
	}
}

定时器实现函数,注意超时检测方法:

/* 定时器中断 1ms*/
void Time0ISR() interrupt 1 using 1
{
    TL0 = T1MS;                     //reload timer0 low byte
    TH0 = T1MS >> 8;                //reload timer0 high byte
	if(PACK_REC_OK == time_out_check_MODBUS()) 
	{
		//成功接收一帧数据后,处理modbus信息,同步公共区数据
		function_MODBUS(modbus_recv_buf);
	}

}
/*超时帧检测,在1ms定时器里面运行,返回当前状态*/
int time_out_check_MODBUS(void)
{
<span style="white-space:pre">	</span>rec_time_out++;
<span style="white-space:pre">	</span>if(rec_time_out == 9)<span style="white-space:pre">				</span>// 数据接收超时5ms,给程式足够长的处理时间
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>rec_stat = PACK_START;
<span style="white-space:pre">		</span>rec_num = 0;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>else if((rec_time_out == 4) && (rec_num > 4)) // 超时数据帧结束4ms
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>rec_stat = PACK_REC_OK;
//<span style="white-space:pre">		</span>modbus_rtu->rec_num = 0;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">		</span>return rec_stat;<span style="white-space:pre">		</span>
}

一帧数据接收成功后,执行方法就在函数 function_MODBUS中,如下,指令解析和发动都是严格按照modbus协议来的,这里只是用到了协议的常用的几个指令,大家可以自由扩展,

void function_MODBUS(unsigned char *rec_buff)
{	
	switch(rec_buff[1])	// 功能码索引
	{
		case 1:	// 01功能码:读取线圈(输出)状态  读取一组逻辑线圈的当前状态(ON/OFF)
			//read_coil();
			break;

		case 2:	 //02功能码:读取输入状态  读取一组开关输入的当前状态(ON/OFF)
			//read_input_bit();
			break;

		case 3:	//03功能码:读取保持型寄存器 在一个或多个保持寄存器中读取当前二进制值
			read_reg(rec_buff);
			break;

		case 4:	//04功能码:读取输入寄存器 在一个或多个输入寄存器中读取当前二进制值
			read_reg(rec_buff);
			break;

		case 5:	//05功能码 :强制(写)单线圈(输出)状态  强制(写)一个逻辑线圈通断状态(ON/OFF)
			//force_coil_bit();
			break;

		case 6:	//06功能码:强制(写)单寄存器 把二进制写入一个保持寄存器
			force_reg(rec_buff);
			break;

		case 15:
			//force_coil_mul();
			break;

		case 16: //16功能码:强制(写)多寄存器 把二进制值写入一串连续的保持寄存器
			force_reg(rec_buff);
			break;

		default:

			//modbus_send_buff[1] = rec_buff[1] | 0X80;
			//modbus_send_buff[2] = ERR_FUN_CODE;		// 不合法功能号
			//send_num = 5;
			break;
	}
	rec_stat = PACK_START;//发送之后使缓存回到初始状态
	rec_num = 0;
}
/*
function:对应modbus功能号03,04 批量读寄存器
input:rec_buf接收到的指令 send_data需要发送的指令
*/
void read_reg(unsigned char * rec_buff)
{
<span style="white-space:pre">	</span>unsigned char begin_add = 0;
<span style="white-space:pre">	</span>unsigned char data_num = 0;
<span style="white-space:pre">	</span>unsigned char *piont;
<span style="white-space:pre">	</span>unsigned int send_CRC;
<span style="white-space:pre">	</span>unsigned int send_num;
<span style="white-space:pre">	</span>int i;


<span style="white-space:pre">	</span>begin_add = rec_buff[3]*2;//地址1字节
<span style="white-space:pre">	</span>data_num = rec_buff[5]*2;//需要读取的字节数
<span style="white-space:pre">	</span>send_num = 5 + data_num;<span style="white-space:pre">	</span>// 5个固定字节+数据个数 addr1 + fun1 + num1 +【data】+ crc2 
<span style="white-space:pre">	</span>rec_buff[2] = data_num;//字节数
<span style="white-space:pre">	</span>piont = (unsigned char *)modbusAdd;  //将结构体转换为字符数组,便于后面的循环读取或写入
<span style="white-space:pre">	</span>for(i=0;i<data_num;i++)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>rec_buff[3+i] = piont[begin_add +i];
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>send_CRC = comp_crc16(rec_buff, send_num-2);
<span style="white-space:pre">	</span>rec_buff[send_num-2] = send_CRC >> 8;
<span style="white-space:pre">	</span>rec_buff[send_num -1] = send_CRC;
<span style="white-space:pre">	</span>send_count = send_num;
<span style="white-space:pre">	</span>PutNChar(rec_buff , send_count);
}


/*
function:对应modbus功能号06和16,单个和批量写寄存器
input:rec_buf接收到的指令 send_data需要发送的指令
*/
void force_reg(unsigned char * rec_buf)
{
<span style="white-space:pre">	</span>unsigned char fun_code,begin_add,data_num;//功能码,开始地址,数据长度
<span style="white-space:pre">	</span>unsigned int send_num;//发送数据长度
<span style="white-space:pre">	</span>unsigned char *piont;
<span style="white-space:pre">	</span>unsigned int send_CRC;
<span style="white-space:pre">	</span>int i;


//<span style="white-space:pre">	</span>send_data[0] = rec_buf[0]; //获取站号


<span style="white-space:pre">	</span>fun_code = rec_buf[1];<span style="white-space:pre">	</span>//获取功能码
//<span style="white-space:pre">	</span>send_data[1] = fun_code;


//<span style="white-space:pre">	</span>send_data[2] = rec_buf[2];//获取起始地址
//<span style="white-space:pre">	</span>send_data[3] = rec_buf[3];


<span style="white-space:pre">	</span>begin_add = rec_buf[3]*2;
<span style="white-space:pre">	</span>piont = (unsigned char *)modbusAdd;<span style="white-space:pre">	</span>//将结构体转换为字符数组,便于后面的循环读取或写入
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>if(fun_code == 6)//写单个寄存器,返回指令与接收的指令完全一样
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>piont[begin_add] = rec_buf[4];//寄存器高位写入
<span style="white-space:pre">		</span>piont[begin_add+1] = rec_buf[5];//寄存器低位写入
<span style="white-space:pre">		</span>send_num = 8;//
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>else if(fun_code == 16)//写多个寄存器
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>data_num = rec_buf[5]*2;
<span style="white-space:pre">		</span>send_num = 8;
<span style="white-space:pre">		</span>for(i=0;i<data_num;i++)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>piont[begin_add+i] = rec_buf[7+i];
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>send_CRC = comp_crc16(rec_buf, send_num-2);//CRC校验
<span style="white-space:pre">	</span>rec_buf[send_num-2] = send_CRC >> 8;
<span style="white-space:pre">	</span>rec_buf[send_num -1] = send_CRC;
<span style="white-space:pre">	</span>send_count = send_num;
  PutNChar(rec_buf , send_count);
}

基于51单片机modbus下位机设计这里就结束了,这种方法是比较灵活了,将协议的实现单独放在一层,避免与主函数有太多交互,该工程的位置请关注我的git地址:

https://github.com/zhui-ying/PC_MCU51Project/

里面有多个工程,但设计方法是一致的。

2013-01-26 21:39:52 h32dong809 阅读数 4153
  • 巫妖王51单片机开发板配套视频课程

    本课程是巫妖王51单片机开发板的配套视频课程,本课程的目标是用少的时间带大家初级入门51单片机。配合巫妖王51单片机开发板,让大家花费少的时间少的钱就能轻松开启单片机学习之路。

    18902 人正在学习 去看看 朱有鹏

 怎么上传图片呀?

 

1.系统简介

     本系统为xxx检测仪,用于检测xxx载重量,并以模拟输出量形式把载重量传递给主控制系统。

     检测仪根据电梯轿底橡胶块随载重做弹性变化的原理,通过霍尔传感器检测其位移变化且把相应的位移变化变化为电压信号,把传感器传输过来的电压信号经过PIC内部的10位A/D转换为数字信号,单片机把采集到数字量数据经过一系列复杂浮点运算处理后,通过PIC内部PWM模块实现D/A转换。把单片机处理后的数字量数据转换为模拟量数据输出(0.5V—3.5V)。      

 

2.方案选择

(1)      主控制芯片。

      主控制芯片选用PIC单片机,PIC单片机MicroChip单片机的主要产品是PIC 16C系列和17C系列8位单片机,相对于51系列单片机,PIC单片机CPU采用RISC结构,分别仅有33,35,58条指令,采用Harvard双总线结构,运行速度快,低工作电压,低功耗,较大的输入输出直接驱动能力,价格低,一次性编程,小体积. 适用于用量大,档次低,价格敏感的产品.在办公自动化设备,消费电子产品,电讯通信,智能仪器仪表,汽车电子,金融电子,工业控制不同领域都有广泛的应用,PIC系列单片机在世界单片机市场份额排名中逐年提高.发展非常迅速。.

(2)      A/D转换电路

PIC单片机内带A/D转换电路。采用PIC内带A/D转换电路省去了专用A/D转换芯片,降低成本,再者PIC内带A/D转换精度达到10BIT。满足实际生产精度要求。

(3)      D/A转换电路

实现D/A转换有很多种方法,例如采用D/A转换器,F/V频率电压转换器,加权电阻或R-2R的梯形电阻网络均可以实现,本设计才用PIC单片机的PWM脉宽调制器可以实现模数转换。具有电路简单,成本低的特点。同时通过完善后续RC滤波电路,可以实现高精度的输出,满足实际生产需求。

(4)      总结

总的来说,本设计充分利用了PIC单片机内部资源,电路简单,功能齐备,成本低。

 

3.电路设计

(5)       A/D转换电路。

数字系统只能处理数字信号,而称重传感器输出电压量是模拟信号,若要在数字系统中处理这些信号,则必须先把传感器测量的模拟量通过A/D转换模块将其转换为数字量。PIC内部A/D转换一般包括4个步骤,即采样,保持,量化,编码。

A/D转换电路输入如下图1所示:

 

图 1   A/D转换输入电路


     

 图中Vi即是传感器测量的模拟量输入口,二极管的作用的防止反流,起保护作用。

(因R18的电阻值极大,分流极小可忽略不计,故输入到单片机A/D转换口RA0的电压值约为Vi值。保护电路对输入值影响不大)。

(2) 按键电路

按键盘电路电路图如下图2所示:

图中电阻,电容作用是用于去除按键抖动。当按键未被按下时,对应的IO口为高电平,当按键被按下时,IO口高电平被拉低,单片机获得此信息,进而跳转到相应程序执行。

图2   按键电路

 

(6)       D/A转换电路

D/A转换电路电路图如下图3所示:

      其中R11,C6构成RC滤波电路,用于实现PWM波转直流,LM358用作电压跟随器,以提高输出电路的带负载能力。

      D/A转换输出Vout=Vcc*(PWM高电平值/PWM周期值)=5*脉宽/(PR2+1)。

      其中Vout=3.5-3*(Vin-Vmin)/(Vmax-Vmin)

      (其中Vin是传感器输入值,Vmin是满载自学习值,Vmax是满载自学值)

 

图 3   D/A转换电路电路图

 

(7)       电源电路

电源电路电路图如下图4所示:

       24V 输入电压进78M12后转变为12V电压输出为LM358提供电源,12V电压输入到7805后输出5V电压,供单片机及其他芯片用电。电路中的电容起滤波稳压作用。

 

                                图 3  电源电路图

没有更多推荐了,返回首页