单片机

单片机可以替代PLC 吗?

这个问题如同面粉能代替面条一样,答案是否定的。第一次听到这个答案可能很多人都有疑问:

单片机和PLC分别是什么?

它们之间有什么区别?

单片机

单片微型计算机(Single Chip Microcomputer ),亦称微控制单元(Microcontroller Unit),简称MCU,是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器(Central Process Unit;CPU)、随机存储器(Random Access Memory;RAM)、只读存储器(Read-Only Memory;ROM)、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在各个领域广泛应用。诸如手机、PC外围、遥控器,至汽车电子、工业上的步进马达、机器手臂的控制等,都可见到MCU的身影。

“入手STM32单片机的知识点总结"

单片机出现的历史并不长,但发展十分迅猛。它的产生与发展和微处理器的产生与发展大体同步,自1971年美国Intel公司首先推出4位微处理器以来,它的发展到目前为止大致可分为5个阶段。

单片机发展的初级阶段(1971年至1976年)

1971年11月Intel公司首先设计出集成度为2000只晶体管/片的4位微处理器Intel 4004, 并配有RAM、 ROM和移位寄存器, 构成了第一台MCS—4微处理器, 而后又推出了8位微处理器Intel 8008, 以及其它各公司相继推出的8位微处理器。

单片机发展的初级阶段(1971年至1976年)

1971年11月Intel公司首先设计出集成度为2000只晶体管/片的4位微处理器Intel 4004, 并配有RAM、 ROM和移位寄存器, 构成了第一台MCS—4微处理器, 而后又推出了8位微处理器Intel 8008, 以及其它各公司相继推出的8位微处理器。

低性能单片机阶段(1976年至1980年)

以1976年Intel公司推出的MCS—48系列为代表, 采用将8位CPU、 8位并行I/O接口、8位定时/计数器、RAM和ROM等集成于一块半导体芯片上的单片结构, 虽然其寻址范围有限(不大于4 KB), 也没有串行I/O, RAM、 ROM容量小, 中断系统也较简单, 但功能可满足一般工业控制和智能化仪器、仪表等的需要。

“入手STM32单片机的知识点总结"

高性能单片机阶段(1980年至1990年)

这一阶段推出的高性能8位单片机普遍带有串行口, 有多级中断处理系统, 多个16位定时器/计数器。片内RAM、 ROM的容量加大,且寻址范围可达64 KB,个别片内还带有A/D转换接口。

16位单片机阶段(1983年至1989年)

1983年Intel公司又推出了高性能的16位单片机MCS-96系列, 由于其采用了最新的制造工艺, 使芯片集成度高达12万只晶体管/片。

全方位高水平发展阶段(1990年至今)

到目前为止,单片机也有从传统的8位处理器平台向32位高级RISC处理器平台转变的趋势,但8位机依然难以被取代。8位单片机成本低,价格廉,便于开发,其性能可以满足大部分的需要,只有在航天、汽车、机器人等高技术领域,需要高速处理大量数据时,才需要选用16/32位,而在一般工业领域,8位通用型单片机,仍然是目前应用最广的单片机。单片机在集成度、功能、速度、可靠性、应用领域等全方位向更高水平发展。

单片机的特点是编程、维护相对复杂,编程方式常用C语言或者汇编语言,成本较低,I/O接口相对有限。

PLC

PLC,全称Programmable Logic Controller,即可编程逻辑控制器,是一种专门为在工业环境下应用而设计的数字运算操作电子系统。它采用一种可编程的存储器,在其内部存储执行逻辑运算、顺序控制、定时、计数和算术运算等操作的指令,通过数字式或模拟式的输入输出来控制各种类型的机械设备或生产过程。

“入手STM32单片机的知识点总结"

单片机为什么不能取代PLC呢?

1. 稳定性与可靠性

有人说这是个伪问题,单片机是元器件,PLC是由元器件以及庞大的软件构成的系统,两者在这一方面没有可比性。这话没有错,大多PLC的控制芯片实际上就是单片机,也就是说可以将PLC看成是单片机的二次开发,单论工业防护等级,单片机的稳定性和可靠性能根本比不了PLC这种IP67类的产品( IP为标记字母,第一标记数字表示接触保护和外来物保护等级,第二标记数字表示防水保护等级)。而且就PLC这种能应对工业恶劣环境的产品还开发出一套冗余系统。如果稳定性与可靠性对比没有意义,那么我们就从其他方面分析。

“入手STM32单片机的知识点总结"

2. I/O功能

单片机的I/O点实在有限,而反观PLC呢?针对不同的现场信号,均有相应的I/O点可与工业现场的器件(如按钮、开关、传感电流变送器、电机启动器或控制阀等)直接连接,并通过总线与CPU主板连接。工业里几乎任意一条生产线,都有上百甚至上千I/O点,就这点单片机完全无法比拟。

“入手STM32单片机的知识点总结"

3. 扩展功能

一条完整的工业生产线除了控制,还有通信、上位、组态、运动控制与显示等等,这些东西都需要依靠完整的工业体系与通信协议去做,例如西门子公司的PROFIBUS-DP通信、三菱重工的CC-LINK等等。而单片机和PC、单片机和单片机之间的通信大都用串口。单片机的串口是全双工异步通信串口,那么像MODBUS、PROFIBUS、CAN open、以太网等通信协议单片机是否能一一实现?或许单片机可以做到,但是这就涉及到下一个分析点,开发周期。

“入手STM32单片机的知识点总结"

4. 开发周期

PLC的品牌多达200多种,几乎每个品牌都有不同编程软件,而且都在不断完善自己的编程软件,使之能够越来越简单的服务于电气工程师,而各种程序块也是越来越方便人性化的任意去调用,比如PID模块、运动控制模块等,大大减轻了工程师的开发压力也缩短了开发周期。那单片机要如何实现?没有现成的模块使用,那就只能开发,那么做过非标自动化设备的工程师都会遇到一个问题——工期不足。PLC这种高度集成化模块化的产品在达到满足设备所需的开发周期,在工期面前也是抓襟见肘,更不用说如同白纸一张的单片机。

5. 通信距离

现在大多数流水线是要跨区域整合与监视的,所用的通讯方式多为以太网加中继器,或者直接走民用宽带光纤,所用的东西到最后很可能是用的就是微软的IE浏览器,很明显PLC是有RJ-45接口,即使本体没有RJ-45也可以配备以太网模块,可单片机搭载的PCB板能加上这个接口然后开发出以太网通信吗?开发需要多久?

“入手STM32单片机的知识点总结"

6. 编程语言

这点对单片机来讲是一个优势,同时也是一个劣势。上面提到PLC的品牌有两百多种,编程软件更多,尽管大多数PLC的编程语言都大同小异,但是每接触一款不同品牌的PLC,电气工程师就要从PLC的硬件参数、软元件、编程软件等等各个方面从头了解一次才能使用的得心应手。而单片机的编程语言用的是C语言或者汇编语言,这对于任何单片机都是通用的。换句话说,学会C语言或者汇编语言,便可以应用任何单片机开发想要的功能(前提是要有相关的电工电子学基础)。但话又说回来,电气工程师不是电子工程师,他们的工作不是单单考虑单片机如何驱动继电器来控制机床的,甚至有的电气工程师都不会C语言、汇编语言之类的MCU开发语言。近些年,IEC-61131-3标准的推广,越来越多的PLC支持多种编程语言,如类似C语言的ST语言,类似电路图的CFC语言。这种便利的功能是传统单片机开发环境真的无法实现。

结论

经过上面阐述,我们可以看出,PLC实际上可以看成是单片机的二次应用开发,但是它又有自己鲜明的特点。到目前为止,中国的单片机应用和嵌入式系统开发走过了二十余年的历程,国民经济建设、军事及家用电器等各个领域,尤其是手机、汽车自动导航设备、PDA、智能玩具、智能家电、医疗设备等行业都是应用了单片机。行业高端目前有超过10余万名从事单片机开发应用的工程师。

来源地址:

https://www.sohu.com/a/274772593_100279726

本文素材来源网络,版权归原作者所有。如不支持转载,请联系删除。

围观 227

单片机复位电路就好比电脑的重启部分,当电脑在使用中出现死机,按下重启按钮电脑内部的程序从头开始执行。单片机也一样,当单片机系统在运行中,受到环境干扰出现程序跑飞的时候,按下复位按钮内部的程序自动从头开始执行。本文介绍的就是单片机按键复位电路原理和电路图解析。

复位电路

在单片机系统中,系统上电启动的时候复位一次,当按键按下的时候系统再次复位,如果释放后再按下,系统还会复位。所以可以通过按键的断开和闭合在运行的系统中控制其复位。

当这个电路处于稳态时,电容起到隔离直流的作用,隔离了+5V,而左侧的复位按键是弹起状态,下边部分电路就没有电压差的产生,所以按键和电容 C11以下部分的电位都是和GND相等的,也就是0V电压。我们这个单片机是高电平复位,低电平正常工作,所以正常工作的电压是0V电压,完全OK,没有问题。

通常的按键分为独立式按键和矩阵式按键两种,独立式按键比较简单,并且与独立的输入线相连接,如下图所示。

“独立式按键电路图"
独立式按键电路图

4条输入线接到单片机的IO口上,当按键K1按下时,+5V通过电阻R1然后再通过按键K1最终进入GND形成一条通路,那么这条线路的全部电压都加到了R1这个电阻上,KeyIn1这个引脚就是个低电平。当松开按键后,线路断开,就不会有电流通过,那么KeyIn1和+5V就应该是等电位,是一个高电平。我们就可以通过KeyIn1这个IO口的高低电平来判断是否有按键按下。

这个电路中按键的原理我们清楚了,但是实际上在我们的单片机IO口内部,也有一个上拉电阻的存在。我们的按键是接到了P2口上,P2口上电默认是准双向IO口,我们来简单了解一下这个准双向IO口的电路,如下图所示。

“准双向IO口结构图"
准双向IO口结构图

当内部输出是高电平,经过一个反向器变成低电平,NPN三极管不会导通,那么单片机IO口从内部来看,由于上拉电阻R的存在,所以是一个高电平。当外部没有按键按下将电平拉低的话,VCC也是+5V,他们之间虽然有2个电阻,但是没有压差,就不会有电流,线上所有的位置都是高电平,这个时候我们就可以正常读取到按键的状态了。

当内部输出是个低电平,经过一个反相器变成高电平,NPN三极管导通,那么单片机的内部IO口就是个低电平,这个时候,外部虽然也有上拉电阻的存在,但是两个电阻是并联关系,不管按键是否按下,单片机的IO口上输入到单片机内部的状态都是低电平,我们就无法正常读取到按键的状态了。

矩阵按键和独立按键的关系

我们在使用按键的时候有这样一种使用经验,当需要多个按键的时候,如果做成独立按键会大量占用IO口,因此我们引入了矩阵按键,如图6所示,使用了8个IO口来实现16个按键。

“单片机按键复位电路原理和电路图"

其实独立按键理解了,矩阵按键也简单,我们来分析一下。图6中,一共有4组按键,我们只看其中一组,如图7所示。大家认真看一下,当KeyOut1输出一个低电平,KeyOut2、KeyOut3、KeyOut4这三个输出高电平时,是否相当于4个独立按键呢。

“单片机按键复位电路原理和电路图"

单片机按键复位电路各元件的作用

“单片机按键复位电路原理和电路图"

如上图,R17 C13组成止电复位电路,刚上电时,C13是电压为0,电源通过R17对电容充电,因此,RST引脚呈现高电平,高电平时间大于2个晶振周期,单片机复位。

电容充电完毕,RST引脚呈现低电平,复位结束。

按钮S22和R16组成手动复位电路 ,按下S22,电源接通R16和 R17,由于R17阻值比较大,因此RST是高电平,同时电容通过R16迅速放电,即使按钮触点断开,电源也可对C13充电,使RST高电平稳定一段时间 ,保证可靠复位。C13容量较小时,R16可省掉,小电容短路放电不会损坏按钮触点。

来源:STM32嵌入式开发
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:
cathy@eetrend.com)。

围观 318

(1)存储器扩展:容量需求,在选择时就考虑到单片机的内部存储器资源,如能满足要求就不需要进行扩展,在必须扩展时注意存储器的类型、容量和接口,一般尽量留有余地,并且尽可能减少芯片的数量。选择合适的方法、ROM和RAM的形式,RAM是否要进行掉电保护等。

(2)I/O接口的扩展:单片机应用系统在扩展I/O接口时应从体积、价格、负载能力、功能等几个方面考虑。应根据外部需要扩展电路的数量和所选单片机的内部资源(空闲地址线的数量)选择合适的地址译码方法。

(3)输入通道的设计:输入通道设计包括开关量和模拟输入通道的设计。开关量要考虑接口形式、电压等级、隔离方式、扩展接口等。模拟量通道的设计要与信号检测环节(传感器、信号处理电路等)结合起来,应根据系统对速度、精度和价格等要求来选择,同时还需要和传感器等设备的性能相匹配,要考虑传感器类型、传输信号的形式(电流还是电压)、线性化、补偿、光电隔离、信号处理方式等,还应考虑A/D转换器的选择(转换精度、转换速度、结构、功耗等)及相关电路、扩展接口,有时还涉及软件的设计。高精度的模数转换器价格十分昂贵,因而应尽量降低对A/D转换器的要求,能用软件实现的功能尽量用软件来实现。

(4)输出通道的设计:输出通道设计包括开关量和模拟量输出通道的设计。开关量要考虑功率、控制方式(继电器、可控硅、三极管等)。模拟量输出要考虑D/A转换器的选择(转换精度、转换速度、结构、功耗等)、输出信号的形式(电流还是电压)、隔离方式、扩展接口等。

(5)人机界面的设计:人机界面的设计包括输入键盘、开关、拨码盘、启/停操作、复位、显示器、打印、指示、报警等。输入键盘、开关、拨码盘应考虑类型、个数、参数及相关处理(如按键的去抖处理)。启/停、复位操作要考虑方式(自动、手动)及其切换。显示器要考虑类型(LED,LCD)、显示信息的种类、倍数等。此外还要考虑各种人机界面的扩展接口。

(6)通信电路的设计:单片机应用系统往往作为现场测控设备,常与上位机或同位机构成测控网络,需要其有数据通信的能力,通常设计为RS-232C、RS-485、红外收发等通信标准。

(7)印刷电路板的设计与制作:电路原理图和印刷电路板的设计常采用专业设计软件进行设计,如Protel,OrCAD等。设计印刷电路板需要有很多的技巧和经验,设计好印刷电路板图后应送到专业化制作厂家生产,在生产出来的印刷电路板上安装好元件,则完成和制作。

(8)负载容限的考虑:单片机总线的负载能力是有限的。如MCS-51的P0口的负载能力为4mA,最多驱动8个TTL电路,P1~P3口的负载能力为2mA,最多驱动4个TTL电路。若外接负载较多,则应采取总线驱动的方法提高系统的负载容限。常用驱动器有:单向驱动器74LS244,双向驱动器74LS245等。

(9)信号逻辑电平兼容性的考虑:在所设计的电路中,可能兼有TTL和CMOS器件,也有非标准的信号电平,要设计相应的电平兼容和转换电路。当有RS-232,RS-485接口时,还要实现电平兼容和转换。常用的集成电路有MAX232,MAX485等。

(10)电源系统的配置:单片机应用系统一定需要电源,要考虑电源的组数、输出功率、抗干扰。要熟悉常用三端稳压器(78хх系列、79хх系列)、精密电源(AD580,MC1403,CJ313/336/385,W431)的应用。

(11)抗干扰的实施:采取必要的抗干扰措施是保证单片机系统正常工作的重要环节。它包括芯片、器件选择、去耦滤波、印刷电路板布线、通道隔离等。

来源:面包板社区
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 89

为了防止大家的程序不被剽窃,本文给大家分享单片机加密的方法。

常见加密方法

程序写保护

这种方法是最常见,也是最简单的一种。现在的MUC基本都有写保护功能,但是这种容易被人破解。

烧断数据总线

这个方法听起来不错,但有损坏的风险,同样也能破解。

软件加密

是一些防止别人读懂程序的方法,单一的这种方法不能防止别人全盘复制,须配合其他的加密算法。

添加外部硬件电路的加密方法

这个方法效果看起来比较好,但会增加成本。

芯片打磨改型

这个方法改了型号能误导,但同时也增加成本,解密者一般也能分析出来。

通过通过联网加序列号加密

通过连接网络,在你的MCU中生成一个唯一的随机长序列号,并加入复杂的特种算法,或加入你们重新编码的企业信息在里面,每个芯片内不同,复制者只能复制到一个序列号。

通过MCU唯一的标识加密

以前很多MCU没有唯一标识码,现在的很多MCU都具有唯一标识码了。

这个方法比较好,简单省事,能很好的防止复制。

读保护 + 唯一ID加密

使用读保护 + 唯一ID的加密是最常用的一种方法,也是推荐大家使用的一种方法。

唯一ID

现在正规的芯片,每颗出厂的时候都带了一个唯一标识码,这个号码是唯一不重复的,比如STM32的就使用96位作为唯一ID。

和我们每个人的身份证号码一样,现在刚出生的婴儿,上户的时候就给他一个身份证号,那么每个芯片一生产出来,也就具备了这个身份证号。

加密原理

读保护就不用说了,增加被破解难度。

使用唯一ID加密的方法很多,这里说一种简单的方法:出厂时程序读取唯一ID并保存在一个位置,以后程序执行之前,要读取并匹配这个唯一ID,一致才执行程序。

当然,这种方法是最基础的原理,但也存在被破解的风险。所以,存储的数据,以及读取验证这两个地方需要进一步添加一些算法。

这样操作之后,即使别人读取了你的程序,也是无法正常执行。

来源: 电子工程世界-论坛
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 387

理论上,只要是用晶振作为时基的单片机时间钟,在常温下做到日差1秒之内,甚至更精准是应该极易达成的。

只是许多人并不知道如何达成这个目标的方案。

“如何用单片机做一个高精度的时间钟方案?"

而且市面很多带单片机的产品中,时间都做不准,这绝对是设计问题。例如:笔者车子上的时钟日差有10秒多。

一般大多数人所设计的定时器时常,是根据晶振标出的数据(如12M)计算而成的,固定不变,设计呆板。但普通晶振的实际振荡频率是不可能与标出的数据完全相同的,例如:12.00043M,11.99985……,这个误差必然积累,所以时钟就不准了。另外绝大多数设计也没有考虑微调方案,对于日差几秒无法控制。

日差1秒要求的精准是:1秒/(24小时*60分*60秒),对应12M晶振;当频率是12.000014M或11.999986M,日差就有1.2秒。可见用普通晶振做的时间钟,如果不采取修正措施,会因精度不够,时钟日差10多秒是很普遍的。

在笔者设计的有单片机时间产品中,随机取10个,同时上电,3天后再看时钟,它们之间的最大时间误差,一般都不会超出1秒(普通晶振,不联网)。许多产品月差在1秒之内。

“如何用单片机做一个高精度的时间钟方案?"

1、实现方法:

1)将时间的定时中断时常数做成可修正的,且加入微调常数,定时时常数与微调时常数在FLASH中取得。微调时常数用于修正时常数的小数点之后的部分。

2)程序可以对某端口输入的秒脉冲再进行计算,并据之修正定时器的时常数,以及微调常数,并存入FLASH中。达成利用外部精准脉冲源对时钟进行校准的目的,说白了,就是用外校消除普通晶振的个体差异。同时程序也可以输出自己的秒脉冲,这样就可以达成产品之间的互校。

3)选择一个产品,对其时钟进行精确校准(这需要外部精准的时钟源。如果手中没有,可以多花点时间,用手机、电视、广播上的报时进行校准),这样就可以将它做成一个自己的【标准秒脉冲时钟源】。

4)产品出货前,用自己的【标准秒脉冲时钟源】校一下(将输出的标准秒脉冲送入其它产品的校准端口,让其它产品自动完成定时器时常数及微调常数的修正。)

如此处理,时间钟的精度就取决于晶振的稳定度,而不是精度。而晶振的稳定度普遍可以达到PPM级,当环境温度变化不大时,极易保证<11.57PPM,这就达成了日差小于1秒的目的。

2、产品相关时间基准的程序:

1)将端口输入的秒脉冲与本体的晶振频率进行比对,计算出定时器的时常数与微调时常数(只做一次即可,计算结果保存到FLASH了,其最初值是按晶振的标称值计算确定的)。

2)时间微调补偿。

3)秒脉冲输出(用于互校,可以放弃不写)。

要点:定时器的时常数不是程序直接赋值,而是从FLASH中调取的。

来源:嵌入式ARM
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:
cathy@eetrend.com)。

围观 75

一、总线概述

计算机系统是以微处理器为核心的,各器件要与微处理器相连,且必须协调工作,所以在微处理机中引入了总线的概念,各器件共同享用总线,任何时候只能有一个器件发送数据(可以有多个器件同时接收数据)。

计算机的总线分为控制总线、地址总线和数据总线等三种。而数据总线用于传送数据,控制总线用于传送控制信号,地址总线则用于选择存储单元或外设。

二、单片机的三总线结构

51系列单片机具有完善的总线接口时序,可以扩展控制对象,其直接寻址能力达到64k( 2的16次方) 。在总线模式下,不同的对象共享总线,独立编址、分时复用总线,CPU通过地址选择访问的对象,完成与各对象之间的信息传递。

“5分钟了解单片机数据、地址、控制总线结构!"

单片机三总线扩展示意如图1所示。

1、数据总线

51单片机的数据总线为P0口,P0口为双向数据通道,CPU从P0口送出和读回数据。

2、地址总线

51系列单片机的地址总线为16位。

为了节约芯片引脚,采用P0口复用方式,除了作为数据总线外,在ALE信号时序匹配下,通过外置的数据锁存器,在总线访问前半周期从P0口送出低8位地址,后半周期从P0口送出8位数据。

高8位地址则通过P2口送出。

3、控制总线

51系列单片机的控制总线包括读控制信号P3.7和写控制信号P3.6等,二者分别作为总线模式下数据读和数据写的使能信号。

三、单片机总线时序分析

51 单片机总线时序如图2 所示。

“5分钟了解单片机数据、地址、控制总线结构!"

从图2中可以看出,完成一次总线(读写)操作周期为T,P0口分时复用,在T0期间,P0口送出低8位地址,在ALE的下降沿完成数据锁存,送出低8位地址信号。在T1期间,P0口作为数据总线使用,送出或读入数据,数据的读写操作在读、写控制信号的低电平期间完成。

需要注意的是,在控制信号(读、写信号)有效期间,P2口送出高8位地址,配合数据锁存器输出的低8 位地址,实现16位地址总线,即64kB范围的内的寻址。

由于CPU不可能同时执行读和写操作,所以读、写信号不可能同时有效。

四、常见单片机编址电路

1、简单地址扩展

51单片机的P2口可以直接作为高8位地址总线使用,在一些简单系统电路中,常使用P2口直接编址驱动。

下面以使用数据缓冲器74LS273驱动数码显示为例,分析P2口编址驱动的静态数码显示电路的设计。

一位LED数码显示单元电路如图3所示。

“5分钟了解单片机数据、地址、控制总线结构!"

WR与A8(P2.0)相或提供74LS273的时钟信号,当执行“MOVX @DPTR,A”指令时,地址信息由DPTR寄存器确定,会出现有效的写信号WR,只有当地址A8为满足“0”时,写信号才可以作为74LS273的时钟信号输入,完成数据锁存。

P2口为A8~A15的8位地址线,很容易扩展到8只LED数码管,WR信号分别与A8~A15按或关系连接,每位地址线均为低电平有效,即可实现8个有效地址。

该方案电路简单,但有效地址数太少,不适用于复杂系统设计。

2、低8位地址锁存

通常的设计电路是使用8D锁存器74LS373实现地址锁存,74HC573与之逻辑功能相同,只是引脚布局不一样,使用74HC573布线更容易。

74LS373真值表如图4所示。

“5分钟了解单片机数据、地址、控制总线结构!"

在输出允许OE为L、控制使能LE为H时,输出为跟随状态;OE为L、LE为L时,输出为保持状态。

地址锁存电路如图5所示。OE接地,LE接单片机的ALE脚将产生满足时序的低8位地址信号。

执行以下三条指令会得到如图6所示的时序图。

MOV DPTR,# 0FF55H; 低8 位地址为55H

MOV A,# 0AAH; 待发送数据0AAH→A( 55H 取反)

MOVX,@DPTR,A; A 中的0AAH送地址为0FF55H 的对象中会。

“5分钟了解单片机数据、地址、控制总线结构!"

从图6中可以看出,P0口先送55H,在ALE下降沿实现地址锁存,随后送出数据0AAH,在WR有效( 低电平)期间锁存器输出低8位地址55H,P0口送出数据0AAH。

3、带译码器的复杂地址接口电路

理论上高8位地址线可以产生256个有效地址,如何实现地址“扩展”呢?地址扩展准确描述是地址译码,例如3根地址线可以译码成8 个地址,4根译码成16个有效地址。这里选择3-8译码器实现地址译码,电路图以及对应的编址如表1 所示。

“5分钟了解单片机数据、地址、控制总线结构!"

五、单片机总线编址电路实例

总线扩展接口的单片机系统,包括外部32k RAM扩展、LCD1602接口、输入输出口。

“5分钟了解单片机数据、地址、控制总线结构!"

D0~D7接数据总线P0口,地址线A0~A14接单片机地址总线低15位,单片机地址线A15接RAM片选信号,低电平有效,这样RAM地址分配从0000H到7FFFH,与74138译码地址不冲突。

LCD1602接口电路如图9所示。

“5分钟了解单片机数据、地址、控制总线结构!"

RS、RW分别接A12、A13,使能信号编址为Y7,这样LCD的四个驱动地址(数据读写和命令读写)为0CFFFH到0FFFFH(无关位为1)或者8700H到0B700H(无关位为0)。

有些时候单片机引脚不够用,还要进行扩展,输入口扩展电路如图10 所示。

“5分钟了解单片机数据、地址、控制总线结构!"

利用74HC573(74LS373)的高阻态功能,将其输出Q0~Q7接P0口,在满足总线地址读操作中,可以把输入InPORT的数据读入单片机的累加器,地址为0F8FFH或8000H。

输出口扩展电路如图11所示。

“5分钟了解单片机数据、地址、控制总线结构!"

利用74LS273数据锁存功能,在满足总线地址写操作中,可以把单片机累加器里的数据写入273 锁存输出,地址为0F8FFH或8000H。由于所用控制总线不同,可以和输入共用地址。

六、结束语

总线扩展是设计单片机控制电路必须掌握的技术,大量的特殊功能IC都支持总线接口,如ADC0809,TLC7528,DDS器件AD9851等。

总线接口的要点就是在严格的控制时序下,总线被分时复用,以实现复杂系统设计。

来源:CSDN博客
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 128

摘要:不知道大家有没有这样一种感觉,就是感觉自己玩单片机还可以,各个功能模块也都会驱动,但是如果让你完整的写一套代码,却无逻辑与框架可言,上来就是开始写!东抄抄写抄抄。说明编程还处于比较低的水平,那么如何才能提高自己的编程水平呢?学会一种好的编程框架或者一种编程思想,可能会受用终生!比如模块化编程,框架式编程,状态机编程等等,都是一种好的框架。

今天说的就是状态机编程,由于篇幅较长,大家慢慢欣赏。那么状态机是一个这样的东东?状态机(state machine)有5个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。

1、什么是状态机?

状态机是一个这样的东东:状态机(state machine)有 5 个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。

状态:一个系统在某一时刻所存在的稳定的工作情况,系统在整个工作周期中可能有多个状态。例如一部电动机共有正转、反转、停转这 3 种状态。

一个状态机需要在状态集合中选取一个状态作为初始状态。

迁移:系统从一个状态转移到另一个状态的过程称作迁移,迁移不是自动发生的,需要外界对系统施加影响。停转的电动机自己不会转起来,让它转起来必须上电。

事件:某一时刻发生的对系统有意义的事情,状态机之所以发生状态迁移,就是因为出现了事件。对电动机来讲,加正电压、加负电压、断电就是事件。

动作:在状态机的迁移过程中,状态机会做出一些其它的行为,这些行为就是动作,动作是状态机对事件的响应。给停转的电动机加正电压,电动机由停转状态迁移到正转状态,同时会启动电机,这个启动过程可以看做是动作,也就是对上电事件的响应。

条件:状态机对事件并不是有求必应的,有了事件,状态机还要满足一定的条件才能发生状态迁移。还是以停转状态的电动机为例,虽然合闸上电了,但是如果供电线路有问题的话,电动机还是不能转起来。

只谈概念太空洞了,上一个小例子:一单片机、一按键、俩 LED 灯(记为L1和L2)、一人, 足矣!

规则描述:

1、L1L2状态转换顺序OFF/OFF--->ON/OFF--->ON/ON--->OFF/ON--->OFF/OFF

2、通过按键控制L1L2的状态,每次状态转换需连续按键5次

3、L1L2的初始状态OFF/OFF

“单片机编程技巧—状态机编程"
图1

下面这段程序是根据功能要求写成的代码。

程序清单List1:

void main(void)
{
 sys_init();
 led_off(LED1);
 led_off(LED2);
 g_stFSM.u8LedStat = LS_OFFOFF;
 g_stFSM.u8KeyCnt = 0;
 while(1)
 {
  if(test_key()==TRUE)
  {
   fsm_active();
  }
  else
  {
   ; /*idle code*/
  }
 }
}
void fsm_active(void)
{
 if(g_stFSM.u8KeyCnt > 3) /*击键是否满 5 次*/
 {
  switch(g_stFSM.u8LedStat)
  {
   case LS_OFFOFF:
    led_on(LED1); /*输出动作*/
    g_stFSM.u8KeyCnt = 0;
    g_stFSM.u8LedStat = LS_ONOFF; /*状态迁移*/
    break;
   case LS_ONOFF:
    led_on(LED2); /*输出动作*/
    g_stFSM.u8KeyCnt = 0;
    g_stFSM.u8LedStat = LS_ONON; /*状态迁移*/
    break;
   case LS_ONON:
    led_off(LED1); /*输出动作*/
    g_stFSM.u8KeyCnt = 0;
    g_stFSM.u8LedStat = LS_OFFON; /*状态迁移*/
    break;
   case LS_OFFON:
    led_off(LED2); /*输出动作*/
    g_stFSM.u8KeyCnt = 0;
    g_stFSM.u8LedStat = LS_OFFOFF; /*状态迁移*/
    break;
   default: /*非法状态*/
    led_off(LED1);
    led_off(LED2);
    g_stFSM.u8KeyCnt = 0;
    g_stFSM.u8LedStat = LS_OFFOFF; /*恢复初始状态*/
    break;
  }
 }
 else
 {
  g_stFSM.u8KeyCnt++; /*状态不迁移,仅记录击键次数*/
 }
}

实际上在状态机编程中,正确的顺序应该是先有状态转换图,后有程序,程序应该是根据设计好的状态图写出来的。不过考虑到有些童鞋会觉得代码要比转换图来得亲切,我就先把程序放在前头了。

这张状态转换图是用UML(统一建模语言)的语法元素画出来的,语法不是很标准,但拿来解释问题足够了。

“图2按键控制流水灯状态转换图"
图2按键控制流水灯状态转换图

圆角矩形代表状态机的各个状态,里面标注着状态的名称。

带箭头的直线或弧线代表状态迁移,起于初态,止于次态。

图中的文字内容是对迁移的说明,格式是:事件[条件]/动作列表(后两项可选)。

“事件[条件]/动作列表”要说明的意思是:如果在某个状态下发生了“事件”,并且状态机

满足“[条件]”,那么就要执行此次状态转移,同时要产生一系列“动作”,以响应事件。在这个例子里,我用“KEY”表示击键事件。

图中有一个黑色实心圆点,表示状态机在工作之前所处的一种不可知的状态,在运行之前状态机必须强制地由这个状态迁移到初始状态,这个迁移可以有动作列表(如图1所示),但不需要事件触发。

图中还有一个包含黑色实心圆点的圆圈,表示状态机生命周期的结束,这个例子中的状态机生生不息,所以没有状态指向该圆圈。

关于这个状态转换图就不多说了,相信大家结合着上面的代码能很容易看明白。现在我们再聊一聊程序清单List1。

先看一下fsm_active()这个函数,g_stFSM.u8KeyCnt = 0;这个语句在switch—case里共出现了 5 次,前 4 次是作为各个状态迁移的动作出现的。从代码简化提高效率的角度来看,我们完全可以把这 5 次合并为 1 次放在 switch—case 语句之前,两者的效果是完全一样的,代码里之所以这样啰嗦,是为了清晰地表明每次状态迁移中所有的动作细节,这种方式和图2的状态转换图所要表达的意图是完全一致的。

再看一下g_stFSM这个状态机结构体变量,它有两个成员:u8LedStat和 u8KeyCnt。用这个结构体来做状态机好像有点儿啰嗦,我们能不能只用一个像 u8LedStat 这样的整型变量来做状态机呢?

当然可以!我们把图 2中的这 4 个状态各自拆分成 5 个小状态,这样用 20 个状态同样能实现这个状态机,而且只需要一个 unsigned char 型的变量就足够了,每次击键都会引发状态迁移, 每迁移 5 次就能改变一次 LED 灯的状态,从外面看两种方法的效果完全一样。

假设我把功能要求改一下,把连续击键5次改变L1L2的状态改为连续击键100次才能改变L1L2的状态。这样的话第二种方法需要4X100=400个状态!而且函数fsm_active()中的switch—case语句里要有400个case,这样的程序还有法儿写么?!

同样的功能改动,如果用g_stFSM这个结构体来实现状态机的话,函数fsm_active()只需要将if(g_stFSM.u8KeyCnt>3)改为if(g_stFSM.u8KeyCnt > 98)就可以了!

g_stFSM结构体的两个成员中,u8LedStat可以看作是质变因子,相当于主变量;u8KeyCnt可以看作是量变因子,相当于辅助变量。量变因子的逐步积累会引发质变因子的变化。

像g_stFSM这样的状态机被称作Extended State Machine,我不知道业内正规的中文术语怎么讲,只好把英文词组搬过来了。

2、状态机编程的优点

说了这么多,大家大概明白状态机到底是个什么东西了,也知道状态机化的程序大体怎么写了,那么单片机的程序用状态机的方法来写有什么好处呢?

(1)提高CPU使用效率

话说我只要见到满篇都是delay_ms()的程序就会蛋疼,动辄十几个ms几十个ms的软件延时是对CPU资源的巨大浪费,宝贵的CPU机时都浪费在了NOP指令上。那种为了等待一个管脚电平跳变或者一个串口数据而岿然不动的程序也让我非常纠结,如果事件一直不发生,你要等到世界末日么?

把程序状态机化,这种情况就会明显改观,程序只需要用全局变量记录下工作状态,就可以转头去干别的工作了,当然忙完那些活儿之后要再看看工作状态有没有变化。只要目标事件(定时未到、电平没跳变、串口数据没收完)还没发生,工作状态就不会改变,程序就一直重复着“查询—干别的—查询—干别的”这样的循环,这样CPU就闲不下来了。在程序清单 List3 中,if{}else{}语句里else下的内容(代码中没有添加,只是加了一条/*idle code*/的注释示意)就是上文所说的“别的工作” 。

这种处理方法的实质就是在程序等待事件的过程中间隔性地插入一些有意义的工作,好让CPU不是一直无谓地等待。

(2) 逻辑完备性

我觉得逻辑完备性是状态机编程最大的优点。

不知道大家有没有用C语言写过计算器的小程序,我很早以前写过,写出来一测试,那个惨不忍睹啊!当我规规矩矩的输入算式的时候,程序可以得到正确的计算结果,但要是故意输入数字和运算符号的随意组合,程序总是得出莫名其妙的结果。

后来我试着思维模拟一下程序的工作过程,正确的算式思路清晰,流程顺畅,可要碰上了不规矩的式子,走着走着我就晕菜了,那么多的标志位,那么多的变量,变来变去,最后直接分析不下去了。

很久之后我认识了状态机,才恍然明白,当时的程序是有逻辑漏洞的。如果把这个计算器程序当做是一个反应式系统,那么一个数字或者运算符就可以看做一个事件,一个算式就是一组事件组合。对于一个逻辑完备的反应式系统,不管什么样的事件组合,系统都能正确处理事件,而且系统自身的工作状态也一直处在可知可控的状态中。反过来,如果一个系统的逻辑功能不完备,在某些特定事件组合的驱动下,系统就会进入一个不可知不可控的状态,与设计者的意图相悖。

状态机就能解决逻辑完备性的问题。

状态机是一种以系统状态为中心,以事件为变量的设计方法,它专注于各个状态的特点以及状态之间相互转换的关系。状态的转换恰恰是事件引起的,那么在研究某个具体状态的时候,我们自然而然地会考虑任何一个事件对这个状态有什么样的影响。这样,每一个状态中发生的每一个事件都会在我们的考虑之中,也就不会留下逻辑漏洞。

这样说也许大家会觉得太空洞,实践出真知,某天如果你真的要设计一个逻辑复杂的程序,

我保证你会说:哇!状态机真的很好用哎!

(3)程序结构清晰

用状态机写出来的程序的结构是非常清晰的。

“单片机编程技巧—状态机编程"

程序员最痛苦的事儿莫过于读别人写的代码。如果代码不是很规范,而且手里还没有流程图,读代码会让人晕了又晕,只有顺着程序一遍又一遍的看,很多遍之后才能隐约地明白程序大体的工作过程。有流程图会好一点,但是如果程序比较大,流程图也不会画得多详细,很多细节上的过程还是要从代码中理解。

相比之下,用状态机写的程序要好很多,拿一张标准的UML状态转换图,再配上一些简明的文字说明,程序中的各个要素一览无余。程序中有哪些状态,会发生哪些事件,状态机如何响应,响应之后跳转到哪个状态,这些都十分明朗,甚至许多动作细节都能从状态转换图中找到。可以毫不夸张的说,有了UML状态转换图,程序流程图写都不用写。

来源:嵌入式Linux
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:
cathy@eetrend.com)。

围观 138

01、确定任务

开发单片机最小系统。

02、任务分析

该系统具有的功能:

(1)具有2位LED数码管显示功能。
(2)具有八路发光二极管显示各种流水灯。
(3)可以完成各种奏乐,报警等发声音类实验。
(4)具有复位功能。

03、功能分析

(1)两位LED数码管显示功能,我们可以利用单片机的P0口接两个数码管来现这个功能;

(2)八路发光二极管显示可以利用P1口接八个发光二极管实现这个功能;

(3)各种奏乐、报警等发声功能可以采用P2.0这个引脚接一蜂鸣器来实现。

(4)利用单片机的第9脚可以设计成复位系统,我们采用按键复位;利用单片机的18、19脚可以设计成时钟电路,我们利用单片机的内部振荡方式设计的。

04、设计框图

“实例分析!单片机最小系统开发运行的全过程"

05、硬件电路设计

根据本系统的功能,和单片机的工作条件,我们设计出下面的电路图。

“实例分析!单片机最小系统开发运行的全过程"

06、元件清单的确定

数码管:共阴极2只(分立)
电解电容:10UF的一只
30PF的电容2只
220欧的电阻9只
4.7K的电阻一只
1.2K的电阻一只
4.7K的排阻一只,
12MHz的晶振一只
有源5V蜂名器一只
AT89S51单片机一片
常开按钮开关1只
紧锁座一只(方便芯取下来的,绿色的)
发光二极管(5MM红色)8只
万能板电路版15*17CM
S8550三极管一只
4.5V电池盒一只,导线若干。

07、硬件电路的焊接

按照原理图把上面的元件焊接好。

08、相关程序编写

针对上面的电路原理图,设计出本系统的详细功能:

(1)第一个发光二极管点亮,同时数码管显示“1”。
(2)第二个发光二极管点亮,同时数码管显示“2”。
(3)依次类推到第八个发光二极管点亮,同时数码管显示“8”。

以上出现的是流水灯的效果

(4)所有的发光二极管灭了,同时数码管现实“0”。
(5)数码管显示“1”。
(6)数码管显示“2、……”直到“9、A、B、C、D、E、F、Y”。
(7)蜂鸣器发出九声报警声后重复上面所有步骤。
(8)程序如下:

ORG 0000H;伪指令,定义下面的程序代码(机器代码)从地址为0000H的单元存放。

LJMP START;跳转到标号为START的地方去执行。

ORG 0030H;伪指令,定义下面的程序代码(机器代码)从地址为0030H的单元存放。

START:MOV P1,#0FEH ;点亮第一个发光二极管。

CLR P2.7 ;送低电平到第一个数码管,开启数码管。

CLR P2.6 ;送低电平到第二个数码管,开启数码管。

MOV P0,#06H;让数码管显示“1” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#0FDH;点亮第二个发光二极管。

MOV P0,#5bH;让数码管显示“2” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#0FBH;点亮第三个发光二极管。

MOV P0,#4fH;让数码管显示“3” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#0F7H;点亮第四个发光二极管。

MOV P0,#66H;让数码管显示“4” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#0EFH;点亮第五个发光二极管。

MOV P0,#6dH;让数码管显示“5” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#0DFH;点亮第六个发光二极管。

MOV P0,#7dH;让数码管显示“6” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#0BFH;点亮第七个发光二极管。

MOV P0,#07H;让数码管显示“7” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#7FH;点亮第八个发光二极管。

MOV P0,#7fH;让数码管显示“8” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P1,#00H;灭了所有的发光二极管。

MOV P0,#3FH;让数码管显示“0” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#06H;让数码管显示“1” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#5bH;让数码管显示“2” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#4fH;让数码管显示“3” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#66H;让数码管显示“4” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#6dH;让数码管显示“5” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#7dH;让数码管显示“6” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#07H;让数码管显示“7” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#7fH;让数码管显示“8” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV P0,#6fH;让数码管显示“9” 。

LCALL DELAY;调用延时子程序,起到延时的目的。

MOV R4,#9;送蜂鸣器的报警次数。

LOOP:SETB P2.0;不发声

LCALL DELAY;调用延时子程序,起到延时的目的。

CLR P2.0;发声。

LCALL DELAY;调用延时子程序,起到延时的目的。

DJNZ R4,LOOP;发声九次后向下执行。

SETB P2.0;关闭发声

LJMP START;跳转到标号为START处执行,循环本程序。

DELAY:MOV R7,#200;这是延时子程序。

D1:MOV R6,#200

D2:MOV R5,#200

D3:DJNZ R5,D3

DJNZ R6,D2

DJNZ R7,D1

RET;延时子程序返回指令。

END;结束伪指令。

09、调试和编译

利用KEIL C51 软件对上面的程序进行调试和编译,产生*.HEX文件,以便用编程器写入单片机芯片中。

10、编程器的使用

用编程器把电脑里生成的*.HEX文件写到芯片中。

11、产品调试

通上4.5V(三节电池)的电源,可以调试本系统,如果没有错误就可以正常工作了。

来源:嵌入式ARM
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 63

页面

订阅 RSS - 单片机