单片机总线设计法全攻略1、目前广大工程师在设计单片机系统时的两种方案之我见针对51单片机,工程师们在设计系统时,从宏观上讲无非就是两种方案:总线式设计方案和非总线式设计方案。
所谓总线式设计方案就是利用51单片机的读写外部RAM功能,将要设计的外部设备(比如说键盘、液晶等)统统挂到单片机总线上,使其统一按类似读写外部RAM功能的指令方法进行操作;而所谓非总线式设计方案,则是不利用单片机的读写外部RAM功能,而直接利用I/O 口读写方式进行外部设备的读写,比如说LED灯、液晶等,因为液晶有两种读写方式,总线方式和模拟I/O方式(贵刊也有文章介绍过),而这里读写液晶的模拟I/O方式就是这里我要说的非总线式设计方案。
那么这两种方案到底哪一种好呢?说这句话可能有点外行,我自己也这样认为,但是为了更好的让初学者了解其中的道理,我还是班门弄斧简单阐述一下:首先要说明,我的这种阐述是建立在有读写外部RAM功能的单片机的基础之上的。
我个人认为,两种方案各有利弊:对于总线式设计方案来说,优点就是能够充分发挥单片机的总线读写功能,系统一旦设计完成,易于日后的升级和扩展。
缺点是灵活性差,硬件连接比较固定;同时由于单片机读写总线时必定要产生一定的总线时间延迟,这样对于低速的单片机来说,如果设计的系统非常庞大的话,那就需要设计人员考虑一下实时性要求了,但是根据我个人多年来的开发经验来说,只要设计得当,一般问题不大,但还是将此问题摆出来,让大家商榷。
对于非总线式设计方案来说,最大的优点就是灵活性强,这种方案可以根据设计者的爱好自由选择单片机端口进行外围设备的设计(当然是要在符合设计原则的前提下),缺点是升级需要重新设计电路图。
2、总线法设计单片机系统的原理和方法2.1 总线法设计原理简介总线式设计方案对于很多的初学者来说是比较困难的,因为对于这种方法来说,牵扯到单片机和外围设备时序逻辑的分配、地址空间的分配、总线驱动能力等等的问题,一旦设计不好,系统便无法启动,或者说部分模块无法工作。
确实,总线式设计方案存在一定的难度,我想这大概也就是很多初学者甚至包括很多单片机设计工程师们也更趋向于利用非总线式设计方案来进行单片机系统设计的原因吧(仅为个人观点,如有不对,还望切磋)。
所以在这一节接下来的内容中我将会带领大家踏入单片机总线式设计方案的大门,让你领略一下在这块设计领域的无限精彩。
首先我们先来看看51单片机读写外部RAM的时序图,如图1、2所示:图1为51单片机读外部RAM的时序图。
图1 51单片机读外部RAM的时序图注意在这里我们只需要关心ALE、RD、PORT0、PORT2四个信号的时序,而不必关心PSEN信号,因为这个信号是用来控制读写外部程序存储器的,跟我们的讨论不相关,有兴趣的可以自行研究,下同。
下面我就跟大家一起讨论一下这四路信号是如何共同使用的。
有过设计经验的人都很清楚,ALE信号就是我们常说的地址锁存信号,那么它为什么要锁信号呢?锁谁的信号呢?又是如何锁的呢?第一、二个问题很简单,因为51单片机的P0口是地址/数据复用的8位端口,在读写外部RAM时,P0口上会顺序接连出现你要读写的地址信号和读到或要写的数据,如果当地址信号出现时不将此8位地址锁住,那么它将会迅速消失,便无法利用此地址进行外部存储器的地址选择;而针对第三个问题,信号时如何锁的,稍微有点麻烦,因为灵活性很大。
大家请仔细看图1的ALE 和PORT0两个信号,LHLL t ——ALE 的有效脉冲宽度AVLL t +——为P0口地址信号的有效时间长度LLAX t 我们先暂且研究一下这两个信号便可解答上面的问题,注意到P0口地址的有效时间长度为+两个时间长度的和,那么我们到底在哪个时间段来锁存地址信号呢?通过时序图我们可以发现,显然必须在ALE 的有效脉冲宽度内来截取这个P0口的地址信号,那么有人会问多出这个时间段干什么用,在这个时间段内P0口其实也在继续保持有效的低8位地址,请继续往下看便可理解。
好了,既然这样,我们要锁存此时的P0口地址信号很显然就要在ALE 的有效脉冲宽度内来动手脚了,大家一看,哈,这简单,这要在ALE 信号为高电平的时候,直接利用373芯片获取P0口地址信号不就完了嘛!不错,是的,目前大家都是这么做的。
那么我现在问你,方法唯一吗?我这么一提醒,大家可能又会想,奥,对了,在ALE 信号的两个边沿也可以啊!那么你又错了,我说还有一个方法就是在ALE 信号的下降沿可以,上升沿是不行的啊!为什么啊?你看看图1的时序,P0口地址的有效起始时间的左边沿在ALE 信号的有效脉冲上升沿后面呢,这显然不行吧!当然我们经常用的方法还是利用74ls373这类高电平传输的芯片。
这里告诉了大家两种方法,只是想提醒大家有时候方法是非常灵活的,后面我会就这两种锁存地址的方法分别以实例的形式体现在大家面前。
AVLL t LLAX t LLAX t AVLL t 好了,地址我们锁存完了,既然P0口是地址和数据复用端口,那我们再来研究一下后面的数据又是怎么传输的。
为了更好的让大家同时了解外部存储器的读和写的原理,这部分我打算结合图2介绍一下数据的写入。
图2为51单片机写外部RAM 的时序图。
图2 51单片机写外部RAM 的时序图同样在这里我们只需要关心ALE 、WR 、PORT0、PORT2四个信号的时序。
请看下面几个时间量:LLWL t ——ALE 信号跳为低到WR 信号开始变低的时间段WLWH t ——WR 信号有效宽度QVWX t ——P0口数据有效开始到WR 信号开始有效WHQX t ——WR 信号有效结束到P0口数据有效结束通过上面我们可以看出,也就是说在ALE 信号跳为低电平以后,延迟这么长的时间后,LLWL t WR 低电平信号会紧跟着出现,注意这个信号是单片机自动产生的,很多读者总是以为要设置什么寄存器之类的东西,容易出现迷惑,只要我们在程序里一调用MOVX 或者在C 语言里读写XDATA (外部)的地址,WR 或者RD 便会自动出现了。
于是乎这时候我们便可以写入我们需要传输的数据了。
问题由来了,我们在什么时候把数据写入到外部RAM 或者说外部设备呢?这里请大家注意,我们发现P0口数据有效的总时间段为++,显然要长于WLWH t QVWX t WHQX t WR 信号有效宽度,并且将其包含在之内,所以在这里,根据这个时序原理,我们可以利用WLWH t WR 的下降沿时刻、低电平阶段或是上升沿时刻进行数据的写入,但是我们最常用的是在WR的低电平时期和WR上升沿时刻将有效数据写入,而利用WR的低电平时期写入数据又是最为普遍,因为好多公司生产的带外部总线读写功能的芯片都是要求在WR的低电平时期写数据,跟上面一样,我们在这里讨论这个,主要是给大家提供一种思路,在自己进行地址分配或时序逻辑设计时也许用得上。
在下面的实例中,这两种方法我都会做介绍,请大家仔细体会。
2.2 两种地址锁存法介绍上面我已经提到,在进行地址锁存时有两种锁存方案:高电平地址锁存法和下降沿地址锁存法,注意我这里所说的这两种方法名称是针对单片机的ALE端信号而言。
下面我将结合具体的电路给大家做一下详细介绍(为节省画图空间,考虑到单片机复位电路和晶振电路不是本文所讨论的话题,故省略):2.2.1 高电平地址锁存法本小节介绍的高电平地址锁存法是单片机开发工程师使用最为广泛的一种方法。
在这种方法中选用373或者573芯片,以573为例,其真值表如表1所示:表1 74HC573真值表OE LE D QL H H H L H L L L L X Q0H X X Z由上述真值表我们不难看出,这个片子的特点是:在输出控制端OE有效(低电平)的前提下,当锁存端LE为高电平时,输出端Q随着输入端D变化,而当LE为低电平时,输出端Q保持上一次的输入端数据,这样的逻辑正好符合我们在第一节分析的有关单片机ALE端信号的变化情况,即ALE端为高电平时,单片机P0口的低8位地址信号输出到573的输入端,而输出端跟随变化,一旦ALE变为低电平,573便不再跟随单片机的P0口地址,因为这时候(应该是过一会)P0 口马上就要输出8位“数据”了,这样便完成了单片机低8位地址的锁存。
图3 高电平地址锁存法2.2.2 下降沿地址锁存法本小节给大家介绍另一种方法——下降沿地址锁存法。
这种方法在我们的实际设计中并不是很常见,但是我仍然给大家做一个简单的介绍,目的是让大家开拓思路,了解问题的实质。
在这种方法中选用374或者574芯片,以374为例,其真值表如表1所示:表2 74HC374真值表OE CLK D QL ↑H H L ↑L L L L X Q0H X X Z由上述真值表我们不难看出,这个片子的特点是:在输出控制端OE有效(低电平)的前提下,当锁存端LE输入上升沿信号时,输入端D的信号才能送到输出端Q,而当LE为非上升沿时,输出端Q保持上一次的输入端数据,这样的逻辑正好符合我们在第一节分析的有关单片机ALE端信号的变化情况,即ALE端为高电平时,单片机P0口的低8位地址信号输出到374的输入端,但是输出端不跟随输入端变化,一旦ALE信号变为低电平,这样便瞬间产生了一个下降沿,但是374需要的是一个上升沿信号才能将数据从输入端打进输出端,为此,必须在ALE与CLK端进行一下反相。
这样在单片机这次整个的读写数据的过程中,374的输出端,也就是锁存的单片机的低8位地址就不再变化了,因为,ALE端信号在一次读写过程中是始终保持低电平的,不会再次产生下降沿,也就不会再次更新374的输出端。
这样也同样完成了单片机低8位地址的锁存。
图4 下降沿地址锁存法3、总线法设计单片机模块全突破通过上面第二节我们知道单片机总线低8位地址有两种锁存方法。
在这一节里,我将就总线设计法中经常用到的一些单片机外围模块的设计思路或者方法详细的介绍给大家,希望大家看完后能从中有所体会。
首先我先把下面各个模块中用到的138地址译码电路摆出来:图5 地址译码电路地址分配:CS_LED: 0X8000~0X8FFF; LED指示灯片选地址CS_SHUMA: 0X9000~0X9FFF;数码管片选地址CS_A/D: 0XA000~0XAFFF;A/D转换器片选地址CS_D/A: 0XB000~0XBFFF;D/A转换器片选地址CS_LCD: 0XC000~0XCFFF;液晶片选地址CS_KEY_RD: 0XD000~0XDFFF;读键盘片选地址CS_KEY_WR: 0XE000~0XEFFF;写键盘片选地址地址分配解析:首先咱们先来看看LED指示灯的地址控制端CS_LED为什么是0X8000~0X8FFF,74HC138首先要工作,必须将它的片选输入(E1、E2、E3)端置为有效,根据我们的硬件连接,E1、E2已经接地,这时我们只需要将E3置为高电平即可随时启动该74HC138芯片,又由于我们把单片机的最高位地址线A15接在了E3上,所以,我们所有外设的片选地址都必须让A15位置为高电平“1”,这样,74HC138片选输出就完全取决于C(A14)、B(A13)、A(A12)三个控制端了,显然要让LED指示灯的地址控制端CS_LED有效,也就是让74HC138的Y0输出端有效(为“0”),只需要C(A14)=“0”、B(A13)=“0”、A(A12)=“0”即可,也就是说只要让单片机地址总线的高四位为“1000”,而其他12根低地址线可以任意取“0”和“1”,所以到此我们便推算出了LED 指示灯的片选地址是0X8000~0X8FFF。