汇编的51单片机的跑马灯

2023-01-11  

话不多说,先上程序

ORG 0000H

MAIN:MOV P1,#0O

LCALL DELAY

MOV A,#0FEH

SETB C

TO: MOV P1,A

LCALL DELAY

LCALL DELAY

RLC A

JC TO

MOV P1,A

LCALL DELAY

LCALL DELAY

TO1: RRC A

MOV P1,A

LCALL DELAY

LCALL DELAY

JC TO1

AJMP TO

DELAY:MOV R2,#0FEH

TC1:MOV R3,#0FEH

TC2:DJNZ R3,TC2

DJNZ R2,TC1

RET

END

这个程序的目的是使8个LED循环点亮,还有一个状态是都不亮,我的LED是搭在P1口上,给低电平就亮。总的现象就是先全部亮一次,然后从左到右依次亮,然后全部灭掉,然后从右到左依次亮一遍,然后灭掉,然后就这样循环下去。


现在来对代码一步一步进行分析 我在前面讲过的知识点我就不重复了,会写的简略点,不懂的往前看。

ORG 0000H ;这个就不说了

MAIN:MOV P1,#00 ;让灯全部都亮

LCALL DELAY ;延时

MOV A,#0FEH ;11111110 赋给累加器A,累加器A就相当于c语言中的一个临时变量,临时的寄存器。

SETB C ;把进位标志位C置为1,它就相当于给八位加上了一位,这个可以让灯有个全灭的状态,等你理解完下面的全部东西再来看这个语句的作用,这样理解起来比较好。


TO: MOV P1,A ;这个语句标号为 TO,执行后是使最左边的灯亮起来

LCALL DELAY

LCALL DELAY

RLC A ;这个是新的语句,对A进行循环左移进位,RLC,我的理解就是recircle left carry ,转化为中文就是循环左移进位,意思就是把累积器A加上进位标志位C一起进行循环左移

相当于就是9个数在循环往复的移动,里面还有一个0,这个0移到哪里,哪个灯就亮了,移到进位标志位的时候就每个灯都不亮,因为进位标志位不控制灯的亮灭。


JC TO ;JC是意思是根据进位标志位C是否为1来判断是否转移,jump carry,如果C等于1,就跳到TO里面继续执行左移,否则就就执行后面的程序,而由于8个1和一个0在这九个位置移动,所以只有当0移动到进位标志位C这里它才会执行下面的程序,所以在它没有循环到全部熄灭的状态时,就会继续执行左移

MOV P1,A ;把进位标志位C为0的这个状态也赋给P1口,让灯全部熄灭。

LCALL DELAY

LCALL DELAY

TO1: RRC A ;RRC,recircle right carry,循环右移带进位 和RLC循环的方向相反,本质没有什么不同 ,从这个时候开始右边的第一个灯亮,一直亮到最左边

MOV P1,A

LCALL DELAY

LCALL DELAY

JC TO1 ;循环右移

AJMP TO ;移到最右边就又跳回到前面开始循环左移

DELAY:MOV R2,#0FEH ;下面就是延时函数

TC1:MOV R3,#0FEH

TC2:DJNZ R3,TC2

DJNZ R2,TC1

RET

END

你们可以试试RL和RC,这个不带进位标志位的,所以就不会有全部熄灭的状态了。如果有哪里讲的不对或者不到位的地方,还请大家多多指教,大家最好买个51或者52单片机玩着来学,不然就很没效果,自己去试试少了那些语句会怎么样,然后按自己的目标改变程序。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。