这个试验的跑马灯和上个试验的效果是一样的,也是使每个灯轮流点亮。既然效果一样,我们为什么做这么多灯的试验哪?我们做试验,不是开发产品,要求创新,我们做试验主要是学习知识,虽然这个试验和上个试验的,效果一样,但是我们确实使用了不同的方法。
在上节课中让 LED 流水是去逐个控制P1端口的每个位来实现的,那么我们这次的试验是在程序一开始就给P1口送一个数,这个数本身就让P1.0先低,其他位为高,然后让这个数据向高位移动不就实现“流水”效果啦?的确如此!
可惜,8051没有让P1数据移动的指令,但有对累加器ACC中数据左移或右移的指令,ACC是8051单片机内部算术逻辑单元中的一个“寄存器”(这里叫他寄存器是不正确的,但你可以先这样理解,ACC在指令中常写为A),他在数据传输和数据处理过程中作用十分重要,ACC为8位。他可与片内所有单字节寄存器交换数据,实际上P1和其他端口在单片机中也是一个寄存器。这样我们可以将需移动的数据先放到ACC中,让其移动,然后将ACC移动后的数据再转送到P1口,这样同样可以实现“流水”效果。
程序如下:
star: ;开始
mov acc,#0feh ;ACC中先装入LED1熄灭的数据(即二进制的 1111 1110)
mov p1,acc ;将ACC的数据送P1口
acall delay
mov r0,#7 ;因上句送到 p1口的数据就熄灭了一位,
;所以将数据再移动7次就完成一个8位流水过程
loop: ;数据移动循环
rl a ;将ACC中的数据左移一位
mov p1,a ;把ACC移动过的数据送p1口显示
acall delay ;调用延时
djnz r0,loop ;没有移动够7次继续移动
ljmp star ;移动完7次后跳到开始重来,以达到循环流动效果
delay: ;延时子程序,就是上节课中的延时子程序
mov r1,#50
del0:
mov r2,#100
del1:
mov r3,#100
djnz r3,$
djnz r2,del1
djnz r1,del0
ret ;延时子程序结束,返回到调用处的下一句
end ;本汇编程序到此结束
接下来,将上述程序编译,并烧写到前面我们的实验芯片中.