上QQ阅读APP看书,第一时间看更新
2.2 跑马灯实例
在上一节点亮1只LED的基础上,让我们来看看如何控制多只LED实现跑马灯效果。
2.2.1 硬件电路图
本实例中,硬件电路和上一节的硬件电路相似,为了实现跑马灯,本实例电路连接了8只LED,原理电路图如图2-2所示。
图2-2 跑马灯原理电路图
2.2.2 软件程序设计
控制多只LED实现跑马灯效果可以有多种实现方式,下面给出其中两种,请对比这两种实现方式的优劣。
1.程序全貌
首先,使用上节学习的直接寻址位置1指令SETB bit和直接寻址位清0指令CLR bit控制P1口实现跑马灯效果,以下为程序实例。
;----------------------------------- ; 跑马灯实例 ;功能:循环轮流点亮8只发光管LED ;----------------------------------- LED1_PIN EQU P1.0 LED2_PIN EQU P1.1 LED3_PIN EQU P1.2 LED4_PIN EQU P1.3 LED5_PIN EQU P1.4 LED6_PIN EQU P1.5 LED7_PIN EQU P1.6 LED8_PIN EQU P1.7 ORG 0000H ;伪指令,指定程序从0000H开始存放 LJMP MAIN ;跳转指令,程序跳转到MAIN处 ORG 0100H ;伪指令,指定以下程序从0100H开始存放 MAIN: MOV SP,#60H ;给堆栈指针赋初值 MOV P1,#0FFH ;给P1赋初值,LED全灭 (1) LIGHT: CLR LED1_PIN ;清零P1.0,LED1亮 (2) LCALL DELAY ;调延时子程序 (3) SETB LED1_PIN ;置一P1.0,LED1灭 (4) CLR LED2_PIN ;清零P1.1,LED2亮 (5) LCALL DELAY ;调延时子程序 (6) SETB LED2_PIN ;置一P1.1,LED2灭 (7) CLR LED3_PIN ;清零P1.2,LED3亮 (8) LCALL DELAY ;调延时子程序 (9) SETB LED3_PIN ;置一P1.2,LED3灭 (10) CLR LED4_PIN ;清零P1.3,LED4亮 (11) LCALL DELAY ;调延时子程序 (12) SETB LED4_PIN ;置一P1.3,LED4灭 (13) CLR LED5_PIN ;清零P1.4,LED5亮 (14) LCALL DELAY ;调延时子程序 (15) SETB LED5_PIN ;置一P1.4,LED5灭 (16) CLR LED6_PIN ;清零P1.5,LED6亮 (17) LCALL DELAY ;调延时子程序 (18) SETB LED6_PIN ;置一P1.5,LED6灭 (19) CLR LED7_PIN ;清零P1.6,LED7亮 (20) LCALL DELAY ;调延时子程序 (21) SETB LED7_PIN ;置一P1.6,LED7灭 (22) CLR LED8_PIN ;清零P1.7,LED8亮 (23) LCALL DELAY ;调延时子程序 (24) SETB LED8_PIN ;置一P1.7,LED8灭 (25) AJMP LIGHT ;跳转,程序继续 (26) ;延时子程序 DELAY: MOV R7,#10H DELAY0: MOV R6,#7FH DELAY1: MOV R5,#7FH DJNZ R5,$ DJNZ R6,DELAY1 DJNZ R7,DELAY0 RET END
本实例也可使用循环左移指令和循环右移指令来实现跑马灯效果,循环左移指令和循环右移指令的功能见表2-6。
表2-6 循环左移指令和循环右移指令
(1)~(26)程序替换为如下程序,运行结果不变。
LIGHT: MOV R0,#08H ;给R0赋初值08H,循环右移8次 MOV A,#0FEH ;给A赋初值0FEH,即11111110 LOOP: RR A ;右移1位 MOV P1,A ;输出显示 LCALL DELAY ;调延时子程序 DJNZ R0,LOOP ;循环右移8次 SJMP LIGHT ;跳转,程序继续
2.运行结果
该实例的运行结果为8只LED循环轮流点亮。
2.2.3 技巧总结
本实例技巧总结如下:
● 同样的运行结果,使用合适的指令可以大大减少代码量,节省程序空间。
● 循环移位指令的应用——乘除法运算:左移1 次 = 无符号数乘2 运算,右移1次 = 有符号数除2运算。