购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.13 实例解读
——与发光二极管的交互

交互,是人与系统之间的互动。前面用单片机控制发光二极管进行闪烁,都是单片机的“独角戏”,我们只是看看热闹。但在实际当中,常常需要用户介入进行参数等的设定。就像前两章的实例中(见图3-23、图1-14),用户通过键盘、按钮等参与了单片机系统的运行。

3.13.1 需求分析

为了更清楚地实现完整单片机系统的设计过程,这里设计的一个实例功能比较简单。如图3-50所示,一开始,两支发光二极管与3.10节、3.11节中介绍的一样以500ms为间隔进行交替发光,直到按钮开关按下时,交替发光的频率变快,变成以200ms为间隔。直到按钮开关释放后交替发光又恢复以500ms为间隔。

图3-50 与发光二极管交互的系统框图

图3-50为实现交互添加了一个按钮开关,可将它与单片机的一个I/O口相连,比如P1.0口。按钮没有按下时,P0.4口、P2.0口以500ms为间隔变换状态;当按钮按下后,会使P1.0口电平由高变低,单片机检测出后就把P0.4口、P2.0口的电平变换间隔调整成200ms。从视觉上看,按下按钮开关后两支发光二极管闪烁变得更急促。

3.13.2 电路设计

电路设计还是从最简系统出发,根据系统框图所示的外设添加器件。在这个与发光二极管交互的实例中,需要添加两支发光二极管和一个按钮开关,电路图如图3-51所示。实际上这个系统是在发光二极管交替发光系统(见图3-41)的基础上添加了一个按钮开关S1和上拉电阻R3构成的。

3.13.3 程序设计

如图3-51所示的系统电路由于多出了一个用于交互的按钮开关S1,它连接到单片机的P1.0口(1管脚)上。当S1没有按下时,由于电阻R3的上位作用P1.0=1;当S1按下后,P1.0口因接入地中于是P1.0=0。只要单片机检测P1.0口的状态就知道用户有没有按下按钮开关,从而对发光二极管的闪烁时间进行调整即可。所以交互程序只需要在交替发光的程序(程序3-1)基础上进行一些改动即可。

如图3-52所示为该程序的流程图,如果按钮开关S1不按下,P1.0口不为低电平,则流程图所示的就是一个以500ms为间隔的交替发光程序。在这期间,一旦按下S1,P1.0出现低电平,则马上进行200ms为间隔的急促的交替发光。

图3-51 与发光二极管交互的系统电路图

图3-52 与发光二极管交互的系统程序流程图

根据图3-52和程序3-1可以得到程序3-2。首先,在“MAIN:”程序段先由指令“MOV P1,#0FFH”把P1口作为输入口,以便响应按钮开关S1。

接下来的“FLASH:”程序段负责当S1按下后用更短的延时进行发光二极管的交替发光,其中使用的延时子程序“DELAY1:”延时时长只有200ms。

而按钮开关S1的检测由“DELAY:”程序段中的一条指令“JNB P1.0,FLASH”实现。当P1.0=1时,该指令不进行任何操作;当P1.0=0时,该指令会跳向“FLASH:”程序段执行急促交替发光的操作。

如果S1一直被按下,“FLASH:”程序段将被不断执行,急促交替发光持续进行。直到S1释放后,程序又回到“MAIN:”中进行500ms间隔的交替发光。

程序3-2:与发光二极管的交互(对应图3-51)

指令小贴士:

3.13.4 延时子程序

程序3-1、3-2都出现了延时子程序,在主程序中指令“CALL DELAY”的功能是调用子程序DELAY。当单片机执行到“CALL DELAY”时,就转到子程序DELAY中去执行,而在子程序DELAY的最后一行的指令RET是子程序结束的标志,表明将要返回主程序的CALL DELAY的下一行继续执行。这个过程可以用图3-53来解释。

为什么子程序DELAY可以实现延时呢?我们用以下一段延时程序来解释一下,程序3-3是一个延时10ms的程序。在标号“D1:”后的指令“MOV R4,#20”使R4=20,R4是单片机的工作寄存器,可以保存数据,这里也可以理解成为一个变量。同理,指令“MOV R5,#248”使R5=248。指令“DJNZ R5,$”的功能是将R5的值减1,不等于0则重新执行本行指令,继续将R5减1看是否等于0。指令中的美元符号“$”指向本条指令的地址。

图3-53 主程序与子程序的执行

程序3-3:延时程序段(部分)

可以凭着直觉猜想单片机与计算机一样,在执行一个指令或任务时需要花费一定的时间,例如,一条DJNZ指令执行花费的时间为2个机器周期(附录B中有AT89S51所有指令的执行周期和字节长度),由于R5=248,所以执行完“DJNZ R5,$”所耗时间为2×248个机器周期。加上前一条1个机器周期的指令“MOV R5,#248”共花去1+2×248=497个机器周期。

接下来,指令“DJNZ R4,D2”将R4的值减1,不等于0,则跳回标号D2处继续执行。由于R4预先装入了20,所以这4条指令共花去了20×(497+2)+1=9981个机器周期。如果使用的是12MHz的晶振,1个机器周期就为1μs(微秒),则以上这段程序所花的时间为9981×1μs=9981μs≈10ms。

现在回到前面延时子程序DELAY部分,如程序3-4所示。这个程序实际上在程序3-3之上再加上一层循环,由于一开始R3=50,这样,通过指令“DJNZ R3,D1”把程序3-3重复执行了50次,所以程序3-4的总延时约为50×10=500ms。修改工作寄存器R3、R4、R5的值可以改变延时的时间。

程序3-4:500ms延时子程序

最后看来,延时的实质是:因为单片机在执行指令时需要时间,虽然执行一条指令只需要几个微秒,但通过循环就能把微秒级的执行时间提高到毫秒级甚至秒级。所以,延时子程序就是反复多次执行几条汇编指令,耗费时间而已。 qjc46VjCkEBG7PL3/1wJvXIqMgwvhV25KNZtJ4b3/KvpJNGyk+Uu6Nm4Ip5rfarS

点击中间区域
呼出菜单
上一章
目录
下一章
×